このコードは、任意の形状の画像の重心を見つけます。それは正確に を見つけますrez = 1
。を大きくするrez
と、グリッド間隔が大きくなるため、検索速度が大幅に向上しますが、精度は明らかに犠牲になります。ブロブのサイズが範囲内でわかっている場合は、低いrez
検索と高いrez
検索を連鎖させることができるため、迅速かつ安価に答えを見つけることができます
import Image
def find_centroid_faster(im, rez):
width, height = im.size
XX, YY, count = 0, 0, 0
for x in xrange(0, width, rez):
for y in xrange(0, height, rez):
if im.getpixel((x, y)) == 255:
XX += x
YY += y
count += 1
return XX/count, YY/count
たとえば、次の画像を使用します。
im = Image.open('blob.png')
print find_centroid(im, 1)
print find_centroid(im, 20)
#output:
(432, 191)
(430, 190)
timeit
最初のオプション (線形時間) を使用したタイミングO(n)
の実行時間は1.7s
で、2 番目のオプションは0.005s
です。
O(n)
サイズと形状に制約がない限り、正確な答えを見つけるよりも良いことはありません。ただし、速度のために精度を犠牲にすることができます。上記のコードはO(n/(rez ** 2))
、大幅な改善になる可能性があります。報告された結果の精度は± rez / 2
、各次元で です。
アップデート:
sega_sai
重心を見つけるための素敵なコードを書きましたnumpy
(以下の投稿を参照)。スライスを使用して、グリッド間隔を利用するように変更しました。上記と同じ方法で動作します。
def find_centroid_faster_numpy(im,rez):
h, w = im.size
arr = np.array(im)
arr_rez = arr[::rez,::rez]
ygrid, xgrid = np.mgrid[0:w:rez, 0:h:rez]
xcen, ycen = xgrid[arr_rez == 255].mean(), ygrid[arr_rez == 255].mean()
return xcen, ycen
以下はtimeit
、これら 2 つの関数の一連のrez
値に対するグラフ化された結果です。
これは対数グラフなので、2 つのアプローチを組み合わせることの利点を実際に示しています。
これは、テストに使用した画像です。