6

Ich möchte den Umfang einer bestimmten numpy Array-Struktur berechnen. Mit Perimeter meine ich den exakten Umfang der Struktur im numply array. Die Struktur könnte Löcher enthalten.Berechne den Umfang des numpy Array

Mein aktueller aproach ist so etwas wie dieses:

import numpy 
a = numpy.zeros((6,6), dtype=numpy.int) 
a[1:5, 1:5] = 1;a[3,3] = 0 
# Way 1 
s = ndimage.generate_binary_structure(2,1) 
c = ndimage.binary_dilation(a,s).astype(a.dtype) 
b = c - a 
numpy.sum(b) # The result, however the hole is calculated as 1, although there are 4 edges 

# Way 2 
b = ndimage.distance_transform_cdt(a == 0,metric='taxicab') == 1 
b = b.astype(int) 
numpy.sum(b) # same as above 

enter image description here

Wie Sie sehen es alle benachbarten Zellen zeigt, jedoch die Summe von ihnen nicht den Umfang des Patch nicht gleich. Das Loch im Beispiel-Array wird als 1 berechnet, obwohl es korrekt vier Kanten hat. Es gibt ähnliche Probleme mit größeren Löchern unterschiedlicher Formen.

Ich habe ähnliche Fragen in der Vergangenheit gestellt, aber alle bereitgestellten Lösungen, die irgendwie in den richtigen Ausgabewerten am Ende nicht aufgelöst haben. Jemand hat eine Idee, wie man das erreicht? Keine anderen Pakete als numpy, scipy und die Basispakete bitte.

+1

Welchen Wert erwarten Sie in diesem Beispiel? – Eric

+0

Ein ganzzahliger Wert. Im obigen Testdatensatz sollte der Endwert 20 sein, da es 20 Kanten gibt. – Curlew

Antwort

4

Meinst du, in dem Bild, die Gesamtzahl der Länge-1-Kanten, die blau von rot gefärbten Fliesen trennen? Im obigen Bild würde diese Zahl 28 sein. In dem Beispiel geben Sie einen Code ein (der etwas anders ist, die 4 Ecken unterscheiden sich nicht vom Rest der Rahmenkacheln) wäre 20.

Wenn Sie das sind berechnen möchten, können Sie so etwas wie:

numpy.sum(a[:,1:] != a[:,:-1]) + numpy.sum(a[1:,:] != a[:-1,:])

+0

Das Bild ist das resultierende Array (b) gezeichnet. – Curlew

+0

ja, funktioniert! Ich wähle Ihre Lösung, weil sie wesentlich kleiner und schneller ist – Curlew

5

Zählen Sie die Anzahl der Kanten im Inneren und an den Rändern (geht davon aus binären Bild):

n_interior = abs(diff(a, axis=0)).sum() + abs(diff(a, axis=1)).sum() 
n_boundary = a[0,:].sum() + a[:,0].sum() + a[-1,:].sum() + a[:,-1].sum() 
perimeter = n_interior + n_boundary 

können Sie auslassen n_boundary wenn Das Bild ist korrekt y Null gepolstert.