8

このフォーラムで、画像などのマスクされた配列の中央値の計算に関するいくつかの議論を見てきました。私が望むのは、もう少し微妙なことです。それは、画像にメディアン フィルターを適用することです。私はそれを行う方法を知っていますが、遅すぎるため、プロセスをスピードアップする方法をいただければ幸いです。

たとえば、形状 (10,10) のマスクされた配列があり、マスクされた要素を使用しないボックス (3,3) でメディアン フィルターを適用したいとします。私の目標は、画像の各ピクセルの値をボックスのマスクされた中央値の値に置き換えることです。

非常に単純なケースを想定すると、「イメージ」とマスクを次のように作成できます。

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

さて、実際にメジアン フィルターを作成するには、次の方法で力ずくで行うことができます。

 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])

これは問題を解決し、良い結果をもたらしますが、私が言ったように、非常に遅いです。プロセスをわずかに高速化する 1 つの (私にとっては驚くべき) 方法は、次のようにマスクと画像を別々に使用することです。

 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]) 

これにより、実行時間が 0.018 から 0.002 になりました。これは、私が探していた約 50 倍ではないにしても、明らかに優れています (なぜ??)。

入力はありますか?

4

1 に答える 1