2016-07-06 12 views
0

Ich habe eine geschlossene Linie aus Raster-Zellen, von denen ich die Indizes (col und rohen jeder Zelle in einer Liste gespeichert). Liste ist wie -Get Zellen Indizes der Raster-Datei innerhalb einer gerasterten Grenze in Python

enter image description here

Ich möchte die Indizes der Zellen innerhalb dieser geschlossenen Linie erhalten und speichern sie in einer separaten Liste. Ich möchte das in Python machen. Hier ist ein Bild, um mehr klar: Rastergrenzlinie

enter image description here

+0

Sind Sie sicher, dass Sie alle inneren Punkte (das heißt Zellen innerhalb der Grenze) auflisten möchten? Aus den in Ihrem ersten Bild angegebenen Indizes scheint es, als könnte das eine ziemlich große Menge sein, vielleicht zu groß, um effizient gehandhabt zu werden. Wenn alles, was Sie (später) brauchen, eine Möglichkeit ist, die Mitgliedschaft zu testen, wäre es wahrscheinlich besser, das einzeln zu testen. – PeterE

Antwort

0

Eine Möglichkeit, dies zu nähern ist Ihren eigenen (naiven) Algorithmus zu implementieren, die meine erste Idee war. Auf der anderen Seite, warum das Rad neu erfinden:

Man kann leicht sehen, dass das Problem als ein Schwarzweiß (Raster/Pixel) Bild interpretiert werden kann. Dann bilden der äußere und innere Bereich den Hintergrund (schwarz), während der Rand eine geschlossene (weiße) Schleife ist. (Natürlich könnten die Farben auch umgeschaltet werden, aber ich werde jetzt Weiß auf Schwarz verwenden.) Es gibt einige ziemlich anspruchsvolle Bildverarbeitungsbibliotheken für Python, nämlich skimage, ndimage und mahotas.

Ich bin kein Experte, aber ich denke skimage.draw.polygon, skimage.draw.polygon_perimiter sind der einfachste Weg, um Ihr Problem zu lösen.

Meine Experimente ergaben folgendes:

import matplotlib.pyplot as plt 
import numpy as np 

from skimage.draw import polygon, polygon_perimeter 
from skimage.measure import label, regionprops 

# some test data 
# I used the format that your input data is in 
# These are 4+99*4 points describing the border of a 99*99 square 
border_points = (
    [[100,100]] + 
    [[100,100+i] for i in range(1,100)] + 
    [[100,200]] + 
    [[100+i,200] for i in range(1,100)] + 
    [[200,200]] + 
    [[200,200-i] for i in range(1,100)] + 
    [[200,100]] + 
    [[200-i,100] for i in range(1,100)] 
    ) 

# convert to numpy arrays which hold the x/y coords for all points 
# repeat first point at the end to close polygon. 
border_points_x = np.array([p[0] for p in border_points] + [border_points[0][0]]) 
border_points_y = np.array([p[1] for p in border_points] + [border_points[0][1]]) 

# empty (=black) 300x300 black-and-white image 
image = np.zeros((300, 300)) 

# polygon() calculates the indices of a filled polygon 
# one would expect this to be inner+border but apparently it is inner+border/2 
# probably some kind of "include only the left/top half" 
filled_rr, filled_cc = polygon(border_points_y, border_points_x) 
# set the image to white at these points 
image[filled_rr, filled_cc] = 1 

# polygon_perimeter() calculates the indices of a polygon perimiter (i.e. border) 
border_rr, border_cc = polygon_perimeter(border_points_y, border_points_x) 
# exclude border, by setting it to black 
image[border_rr, border_cc] = 0 

# label() detects connected patches of the same color and enumerates them 
# the resulting image has each of those regions filled with its index 
label_img, num_regions = label(image, background=0, return_num=True) 

# regionprops() takes a labeled image and computes some measures for each region 
regions = regionprops(label_img) 
inner_region = regions[0] 

print("area", inner_region.area) 
# expecting 9801 = 99*99 for inner 

# this is what you want, the coords of all inner points 
inner_region.coords 

# print it 
fig, ax = plt.subplots() 
ax.imshow(image, cmap=plt.cm.gray)