6

Chcę obliczyć obwód danej struktury tablicy numpy. Z obwodem mam na myśli dokładny obwód struktury w tablicy numpy. Struktura może zawierać dziury.Obliczyć obwód numpy array

Mój obecny aproach jest coś takiego:

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

Jak widać to wyświetla wszystkie sąsiednie komórki, jednak suma z nich nie równa obwodzie plastra. Otwór w tablicy przykładowej jest obliczany jako 1, chociaż ma poprawnie 4 krawędzie. Są podobne problemy z większymi dziurami o różnych kształtach.

Zadawałem podobne pytania w przeszłości, ale wszystkie dostarczone rozwiązania, które w jakiś sposób nie rozwiązały się w prawidłowych wartościach wyjściowych na końcu. Ktoś ma pomysł, jak to zrobić? Nie ma innych pakietów niż numpy, scipy i pakiety podstawowe.

+1

Jakiej wartości można się spodziewać w tym przykładzie? – Eric

+0

Wartość całkowita. W powyższym zestawie danych testowych końcowa wartość powinna wynosić 20, ponieważ jest 20 krawędzi. – Curlew

Odpowiedz

4

Czy masz na myśli, na obrazku, całkowitą liczbę długości-1 krawędzi, które oddzielają niebieski kolor od czerwonych płytek? Na powyższym obrazku liczba ta wynosiłaby 28. W podanym przez Ciebie przykładzie w kodzie (który jest nieco inny, nie mający 4 narożników różniących się od pozostałych płytek granicy) będzie to 20.

Jeśli to właśnie Ty aby obliczyć, można zrobić coś takiego:

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

+0

obraz jest wynikową tablicą (b) narysowaną. – Curlew

+0

tak, działa! Wybieram twoje rozwiązanie, ponieważ jest ono znacznie mniejsze i szybsze – Curlew

5

Policzyć krawędzi we wnętrzu i na krawędziach (zakłada obrazu binarnego):

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 

można pominąć n_boundary jeśli obraz jest poprawny y zero wyściełane.

Powiązane problemy