4

640x480のバイナリイメージ(0と255)があります。画像に白いブロブが1つあり(ほぼ円形)、ブロブの重心を見つけたいと思います(常に凸状です)。基本的に、私たちが扱っているのは2Dブール行列です。ランタイムを線形または可能であればより良いものにしたいのですが、これは可能ですか?

これまでの2つの考え方:

  1. numpy.where()機能を活用する
  2. 各列と行の値を合計し、最大値がそれらの数値に基づいている場所を見つけます...しかし、これを行うための迅速で効率的な方法はありますか?これは、私がPythonに比較的慣れていない場合かもしれません。
4

4 に答える 4

6

このコードは、任意の形状の画像の重心を見つけます。それは正確に を見つけます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 つのアプローチを組み合わせることの利点を実際に示しています。

これは、テストに使用した画像です。

ここに画像の説明を入力

于 2012-05-02T08:57:15.823 に答える
2

このコード:

import Image, numpy as np
def getBlobCenter(imname):
        im = Image.open(imname)
        w, h = im.size
        arr = np.array(im)
        xgrid, ygrid = np.mgrid[0:w, 0:h]
        xcen, ycen = xgrid[arr == 255].mean(), ygrid[arr == 255].mean()
        return xcen, ycen

fraxel が提供する 640x480 の画像には 10 ミリ秒かかります

于 2012-05-02T16:59:04.147 に答える
1

ブロブのサイズにもよりますが、画像の解像度を大幅に下げると、目的が達成される可能性があります。

それを 1/10 の解像度に縮小し、1 つの白いピクセルを見つけると、重心をどこで検索するかが正確にわかります。

于 2012-05-02T07:50:30.707 に答える