【python-openCV】指定色の物体位置を検出!みかんの画像を題材に。

f:id:yshgs_elec:20210117220700j:plain

この記事では、みかんの画像からオレンジ色の部分を抜き出し、その抜き出した部分の重心位置を算出する、ということをやってみます。

 

この記事の内容を応用すれば

「画像の中から特定色の物体位置を検出したい。」

という状況に役立ちます。

 

それでは早速やっていきましょう!

スポンサーリンク

題材紹介:みかんの位置検出

みかんの画像からオレンジ色の部分を抽出し、輪郭、重心を描写した結果

今回は上の画像のように、配置や大きさの違う4枚のみかんの画像に対して、

①オレンジ色の部分を抜き出す

②抜き出し部分の重心を算出

③オリジナル画像に抜き出し部分の輪郭、重心をプロットする

ということをやってみようと思います。

 

「自分のやりたいことに応用できそうだ。」

「なんとなくおもしろそうだ。」

という方はぜひ最後までご覧ください。

※今回はみかんなのでオレンジ色を指定しますが、コード中のオレンジ色を表現する部分を変更するだけで、他の色の物体を検出することも容易に可能です。

 

スポンサーリンク

実行環境の準備

今回はanaconda上でpyhtonとopenCVを使って実行していきます。

anacondaにはおおよそのライブラリが組み込まれていますが、openCVは入っていませんので、自分でインストールする必要があります。

 

インストールしていない方は以下の記事を参考にインストールしてみましょう。

【openCV】インストール方法!Windows&anacondaプロント&Python利用者用

 

※anacondaではなく、通常のpythonを用いて行う場合、openCVに加えてnumpyというモジュールもインストールする必要があります。

ここは【numpy インストール】とか検索すればすぐにインストールできるはずです。

 

環境準備が整ったら、実際にコードを書いていきましょう。

スポンサーリンク

pythonコード紹介

◆画像の中の指定色の物体位置を検出するコード

#ライブラリインポート
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で上の画像のフォルダに移動します。

移動できたら、先ほど作成したプログラムを実行します。

anaconda_promptでプログラムを実行する様子

いざ、実行!!!

するとanaconda_prpmpt上は以下のようなメッセージが表示されました。

プログラムを実行したあとの結果

これらの数字こそが、今回算出したかったみかんの重心位置です。

(画像の左上を基準としたときの横方向、縦方向のピクセル位置)

また、実行フォルダは以下のようになっています。

プログラム実行後のフォルダの中身

もともとあった画像に加えて、

◆みかん部分だけを白く取り出した画像

◆もともとの画像にみかんの輪郭と重心をプロットした画像

が出力されています。

 

これらの画像を並べると以下のようになっています。

f:id:yshgs_elec:20210204155619j:plain

しっかりとみかんの中心付近に印がうってありますね。

 

スポンサーリンク

おわりに

というわけで今回はpython-openCVを使って、画像の中から指定した色の物体位置を検出する方法についてご紹介しました。

 

今回は背景白に対して、みかんがひとつという非常にシンプルな画像なので、この程度のコードで問題なく検出できましたが、画像が複雑になったときにすんなり対応できるかはよく確認しておきましょう。

 

このように私のブログでは様々なプログラミングスキルを紹介しています。

・もっと革新的なことをやりたい。

・プログラミングについてもっと詳しくなりたい。

こんな思いを持っている人は、ぜひ他の記事も見てみてくださいね。

この記事が役に立ったという方は、ぜひ応援よろしくお願いします。

↓ 応援ボタン

にほんブログ村 IT技術ブログへ
にほんブログ村

それではまた!

コメント

タイトルとURLをコピーしました