画像の領域分割方法には様々な手法がある
そのなかでも簡単なアルゴリズムである領域拡張法をライブラリ1行でポチー!
ではなく実際に書いてみることにした
領域分割方とは
目的:
あらかじめ設定した画素値に関する条件を満足する,空間的
に連続する領域をひとかたまりの領域として認識すること.
方法:
① 画素値に関する条件を満足する画素をマニュアルにより決定し,
ひとつのラベルをつける(種子点:seed point).
② 近傍の点で条件を満足する画素に同一のラベルをつける.
③ ②を繰り返す.
http://www.cfme.chiba-u.jp/~haneishi/class/7_segmentation.pdf
というわけで代表点をきめたらそれに近い画素値を持っている点の集合をジリジリ広がりながら探索していく方法らしい
実装結果
にゃんちゅうをinputとして用意した
これを領域分割した結果
このようにある程度の制度で領域を見つけている
実装
jupyter notebook を用いたが、別にふつうにpythonファイルを作っても何も変わったことはしてない
画像のopenや書き出しについてはcv2を用いている
#coding:utf-8
import numpy as np
import cv2
#画像の読み込み
test = cv2.imread("./Img/input.jpg", cv2.IMREAD_COLOR)#BGRなので気をつける
gray_test = cv2.imread("./Img/input.jpg",cv2.IMREAD_GRAYSCALE)
width = test.shape[0]
height = test.shape[1]
frag = np.zeros(gray_test.shape)#領域分割フラグ
#画像の書き出し
cv2.imwrite('./Img/test.jpg', test)
cv2.imwrite('./Img/gray_test.jpg',gray_test)
#初期地点
start_position = [int(width/2),int(height/2)]
threshold = 127#分割領域の閾値
pix = gray_test[start_position[0]][start_position[1]]#グループ化させる領域の画素値
for y in range(0,int(height/2)):
for x in range(0,int(width/2)):#上下
r = gray_test[start_position[0]+x][start_position[1]+y]
l = gray_test[start_position[0]-x][start_position[1]+y]
r2 = gray_test[start_position[0]+x][start_position[1]-y]
l2= gray_test[start_position[0]-x][start_position[1]-y]
if ( max(pix,r) -min(pix,r) <= threshold):
frag[start_position[0]+x][start_position[1]+y] = 1
if ( max(pix,l) -min(pix,l) <= threshold):
frag[start_position[0]-x][start_position[1]+y] = 1
if ( max(pix,r2) -min(pix,r2) <= threshold):
frag[start_position[0]+x][start_position[1]-y] = 1
if ( max(pix,l2) -min(pix,l2) <= threshold):
frag[start_position[0]-x][start_position[1]-y] = 1
frag *= 255
cv2.imwrite('./Img/result.jpg', frag)
実装のコメント
探索についてはスタート地点から上下に探索して、
そのあと横にスライド、また上下に探索みたいな方法で実装してみた
ちなみに終了端点のあたりはかなり適当で、領域は端っこまで続かないでしょもう、、、というやる気ないコードなのでその辺りを気にする方は終了条件をしっかりいれておくとよい(実際楽だと思うよ)
また、領域の閾値については0(黒)-255(白)の中間である127を用いているが、特に意味はない
ここを調整すると領域がぼんやりしたり、シャープになったりするのでいじってください