2013-09-16 15 views
7

Widziałem kilka dyskusji na tym forum o obliczaniu mediany zamaskowanych tablic, takich jak obrazy. To, czego chcę, jest nieco bardziej subtelne, polega na zastosowaniu medianowego filtra na moim obrazie. Znam sposób, aby to zrobić, ale jest zbyt wolny i doceniłby sposoby przyspieszenia tego procesu.Median filtr zamaskowanych macierzy

Załóżmy na przykład, że mam tablicę kształtu zamaskowaną (10,10) i chcę zastosować filtr medianowy z ramką (3,3), nie używając zamaskowanych elementów. Moim celem jest zastąpienie wartości w każdym pikselu obrazu wartością zamaskowanej mediany pudełka.

Zakładając bardzo prosty przypadek, możemy zbudować „obrazu” i maskę jako:

im = numpy.random.uniform(size=(10,10)) 
mask = numpy.zeros_like(im) 
mask[1:3,:] = 1 
masked_im = numpy.ma.array(im, mask=mask) 

Teraz, aby rzeczywiście zrobić środkową filtru możemy to zrobić na drodze brute-force z:

lx, ly = im.shape 
side = 3 
im_filt = numpy.zeros_like(im) 
for jj in range(ly): 
    for ii in range(lx): 
     minx, maxx = max([ii-side/2,0]), min([ii+side/2+1,lx]) 
     miny, maxy = max([jj-side/2,0]), min([jj+side/2+1,ly]) 
     im_filt[ii,jj] = numpy.ma.median(masked_im[minx:maxx, miny:maxy]) 

To rozwiązuje problem i daje dobry wynik, ale jak powiedziałem, jest boleśnie powolny. One (dla mnie zaskakujący) sposób nieco przyspieszyć ten proces polega na użyciu maski i obraz osobno, jak:

im_filt2 = numpy.zeros_like(im) 
for jj in range(ly): 
    for ii in range(lx): 
     minx, maxx = max([ii-side/2,0]), min([ii+side/2+1,lx]) 
     miny, maxy = max([jj-side/2,0]), min([jj+side/2+1,ly]) 
     zoom_im = im[minx:maxx, miny:maxy] 
     zoom_msk = mask[minx:maxx, miny:maxy] 
     im_filt2[ii,jj] = numpy.median(zoom_im[zoom_msk == 0]) 

Daje to czas realizacji od 0,018 do 0,002, co jest oczywiście lepsze (dlaczego? ?) jeśli nie przez czynnik ~ 50, którego szukałem.

Jakieś wejście?

Odpowiedz

1

Domyślam się, że różnica wynika głównie z narzutu w dostępie do obiektu MaskedArray (który jest rodzajem opakowania wokół ndarray).

Dla wydajnego filtra medianowego w numpy możesz również spróbować scikit-image. Przyjmuje również argument maski.

+0

Jest teraz w pakiecie [skimage.filter.rank] (http://scikit-image.org/docs/dev/api/skimage.filter.rank.html#median). – letmaik

+0

2 linki powyżej wydają się już nie działać, jakikolwiek pomysł, gdzie to jest teraz? – JoVe

+0

Dzięki za zgłoszenie. Oto nowy link: http://scikit-image.org/docs/stable/api/skimage.filters.rank.html#median – btel