用途
領域拡張による物体認識のPython実装
領域拡張:指定したピクセルの周囲をみて、同じモノかどうかを判断して認識を広げる。同じような場所にいつも認識したいオブジェクトがある場合に有用。
Code
- Python / 3.10.5
- Install packages/ openCVなど画像処理系
Code:点と画像を与えて領域を求める
def regionGrow(gray, seeds, thresh, p):
seedMark = np.zeros(gray.shape)
#Eight neighborhoods
if p == 8:
connection = [(-1, -1), (-1, 0), (-1, 1), (0, 1), (1, 1), (1, 0), (1, -1), (0, -1)]
elif p == 4:
connection = [(-1, 0), (0, 1), (1, 0), (0, -1)]
#The growth stops when there is no element in seeds
while len(seeds) != 0:
#Stack top element out of stack
pt = seeds.pop(0)
for i in range(p):
tmpY = pt[0] + connection[i][0]
tmpX = pt[1] + connection[i][1]
#Detect boundary points
if tmpY < 0 or tmpX < 0 or tmpY >= gray.shape[0] or tmpX >= gray.shape[1]:
continue
if abs(int(gray[tmpY, tmpX]) - int(gray[pt])) < thresh and seedMark[tmpY, tmpX] == 0:
seedMark[tmpY, tmpX] = 255
seeds.append((tmpY, tmpX))
return seedMark
引数について
- gray: グレースケールの画像
- openCV形式で挙動確認。Pillowで動かなければ変換するとよさげ。
- seeds: 探索基準にしたいピクセル座標
- [(横,縦)] のようなタプルで入ったリスト形式
- 複数あるなら、[(a1,b1), (a2,b2)]
- [(横,縦)] のようなタプルで入ったリスト形式
- thresh: 閾値
- 2とか一桁の数字からパラメータ探索
- p: どの方向のピクセルを見るか
- 4なら上下左右、8なら斜めも加えた8方向
出力は、
入れた画像と同じ大きさのバイナリー画像
subCode:
自分のseedが会っているか確認用
def seeds_check(img,seeds,size=5):
_img = img.copy()
for seed in seeds:
y,x = seed
_img[y-size:y+size,x-size:x+size] = 255
plt.imshow(_img); plt.title("check seed"); plt.show()
自分の指定したseedsの位置を画像で確認する用
見にくければよしなにsizeを変える
その他
- ざっくり解説
- seedsの座標の一つを取り出し、周囲ピクセルとの輝度値の差をみる
- その差が閾値以下であれば、その座標をマスク領域にしつつ、seedsに追加
- この操作をseedsの中身がなくなるまで繰り返す
- コツ
- pは8に固定して、threshを色々試して行くといい
- 前処理で平坦化しすぎるとエッジがなくなるので、バイラテラルフィルタとかがよさげ
- 認識箇所が複数だったり、ムラがある画像の場合はseedに複数点を入れておくとよさげ