この記事では、みかんの画像からオレンジ色の部分を抜き出し、その抜き出した部分の重心位置を算出する、ということをやってみます。
この記事の内容を応用すれば
「画像の中から特定色の物体位置を検出したい。」
という状況に役立ちます。
それでは早速やっていきましょう!
題材紹介:みかんの位置検出
今回は上の画像のように、配置や大きさの違う4枚のみかんの画像に対して、
①オレンジ色の部分を抜き出す
②抜き出し部分の重心を算出
③オリジナル画像に抜き出し部分の輪郭、重心をプロットする
ということをやってみようと思います。
「自分のやりたいことに応用できそうだ。」
「なんとなくおもしろそうだ。」
という方はぜひ最後までご覧ください。
※今回はみかんなのでオレンジ色を指定しますが、コード中のオレンジ色を表現する部分を変更するだけで、他の色の物体を検出することも容易に可能です。
実行環境の準備
先ほどまでに紹介した作業をPython上で実行していきます。
インストールから始めたい方は以下からご覧ください。
別途インストールが必要なopenCVについては以下で解説しています。
python(anaconda)、openCVのインストールが完了したら次は実際のコードを書いていきましょう。
指定色の物体位置検出サンプルコード
◆画像の中の指定色の物体位置を検出するコード
#ライブラリインポート
import cv2
import numpy as np
#4枚の画像に対する繰り返し処理
for i in range(4):
#画像の変数宣言
pic_name="mikan"+str(i+1)+ ".jpg"
pic_name_out="mikan"+str(i+1)+ "out.jpg"
gray_pic="mikan"+str(i+1)+ "gray.jpg"
#ベース画像の読み込み
img = cv2.imread(pic_name,cv2.IMREAD_COLOR)
#画像のサイズ情報取得
height, width = img.shape[:2]
#画像の色をHSV形式に変換
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV_FULL)
h = hsv[:, :, 0]
s = hsv[:, :, 1]
v = hsv[:, :, 2]
#ベース画像と同じ大きさの配列を作成
img_mikan=np.zeros((height,width,3),np.uint8)
#オレンジ色を指定
img_mikan[(h <30) & (h > 10) & (s > 120)& (v > 100)] = 255
#オレンジの領域だけの画像を作成
cv2.imwrite(gray_pic,np.array(img_mikan))
#作成した画像を読み込み
img_gray = cv2.imread(gray_pic,cv2.IMREAD_GRAYSCALE)
#読み込んだ画像の重心、輪郭を取得
M = cv2.moments(img_gray, False)
contours, hierarchy= cv2.findContours(img_gray, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
x,y= int(M["m10"]/M["m00"]) , int(M["m01"]/M["m00"])
#ベース画像に重心、輪郭追加して保存
cv2.circle(img, (x,y), 20, 100, 2, 4)
cv2.drawContours(img, contours, -1, color=(0, 0, 0), thickness=5)
print(x,y)
cv2.imwrite(pic_name_out,np.array(img))
なにやら難しそうに見えるかもしれませんが、ひとつひとうの作業に対してコメントをつけていますので、順番に読んでいけばどんな作業をしているのかをイメージできるはずです。
また、検出したい色を変更したい際は、以下の部分をあなたが指定したい色に変更すればOKです。
※プログラムを実行しながら精度よく検出できる数値を探すのが良いでしょう。
#オレンジ色を指定
img_mikan[(h <30) & (h > 10) & (s > 120)& (v > 100)] = 255
HSVの色指定方法については様々なサイトでご紹介されていますので、
【HSV 色 一覧】とかで検索してみてください。
サンプルコードの実行結果
最後に先ほど紹介したサンプルコードを実行してみましょう。
今回は以下の画像ように、先ほど作成したプログラムファイルと一緒に4枚のみかんの画像が入っている状態で実行します。
(今回はmikan_rinkaku.pyというファイル名にしています。)
それではいざ、実行!!!(Anaconda Prompt上で実行してみます。)
すると以下のようなメッセージが表示されました。
これらの数字こそが、今回算出したかったみかんの重心位置です。
(画像の左上を基準としたときの横方向、縦方向のピクセル位置)
また、実行フォルダは以下のようになっています。
もともとあった画像に加えて、
◆みかん部分だけを白く取り出した画像
◆もともとの画像にみかんの輪郭と重心をプロットした画像
が出力されています。
これらの画像を並べると以下のようになっています。
しっかりとみかんの中心付近に印がうってありますね。
おわりに
というわけで今回はpython-openCVを使って、画像の中から指定した色の物体位置を検出する方法についてご紹介しました。
今回は背景白に対して、みかんがひとつという非常にシンプルな画像なので、この程度のコードで問題なく検出できましたが、画像が複雑になったときにすんなり対応できるかはよく確認しておきましょう。
このように私のブログでは様々なプログラミングスキルを紹介しています。
・もっと革新的なことをやりたい。
・プログラミングについてもっと詳しくなりたい。
こんな思いを持っている人は、ぜひ他の記事も見てみてくださいね。
この記事が役に立ったという方は、ぜひ応援よろしくお願いします。
↓ 応援ボタン
それではまた!
コメント