OpenCV-Pythonでツバキのお花部分だけ取り出してみた
こんにちは。らずべりーです。
Markdown記法について調べたので、早速使ってみています。 これ便利ですね!
参考にさせていただいたまとめページ。感謝!
では、そろそろ本題に、、、
植物の画像加工にチャレンジ(やっと)
OpenCV-Pythonに慣れるため、花の部分を取り出してみる画像加工にチャレンジしてみます!
練習しただけなので、この加工した画像を何かに使う予定はないのです。
参考にしたページを以下に貼っておきます。
OpenCV-Pythonチュートリアル — OpenCV-Python Tutorials 1 documentation
使用する素材
今回使う画像はこれ!
今回は冬に職場で見かけて撮影していたツバキの絞り品種(何かは不明)。綺麗ですねー。
でも、単色のツバキより画像加工の難易度が高そう。。。
撮影はiPhoneで普通にぱしゃり。
実行環境
あとはNumpyとかMatplotlibとか。
作業概要
- 画像の読みこみと表示
- ぼかし処理
- グレースケール画像とHueのみ画像に変換
- 2値化
- マスク処理
実際の手順
0. 作業簡便化のためのpyプログラム作成
OpenCV-Pythonのプログラムは癖があって書きづらかったため
Pythonっぽい文法に置き換えるプログラムopencv_wrap.py
を作りました。
import cv2 import matplotlib.pyplot as plt def display_bgr_image(img): img_rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) plt.imshow(img_rgb) def bgr2hsv(img): return cv2.cvtColor(img, cv2.COLOR_BGR2HSV) def bgr2gray(img): return cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) def display_gray_image(img): plt.imshow(img) plt.gray() plt.show()
1. 画像の読みこみと表示
先ほど作ったファイルをcw
モジュールとしてインポートしています。
%matplotlib inline import cv2 import numpy as np import matplotlib.pyplot as plt import opencv_wrap as cw img001_bgr = cv2.imread("IMG_3232.JPG") cw.display_bgr_image(img001_bgr)
2. ぼかし処理
ぼかし処理はcv2.blur
関数で行います。
ぼかし処理の程度を変えるときは(20,20)を好きな値に変更します。
blur001_bgr = cv2.blur(img001_bgr,(20,20)) cw.display_bgr_image(blur001_bgr)
余計なコードが入っていたので修正しました[2017/10/21]
3. グレースケール画像とHueのみ画像に変換
2値化のための準備です。
blur001_gray = cw.bgr2gray(blur001_bgr) blur001_hsv = cw.bgr2hsv(blur001_bgr) h,s,v = cv2.split(blur001_hsv) cw.display_gray_image(blur001_gray) cw.display_gray_image(h)
4. 2値化
グレースケール画像からは明るい部分(>150)のみを取り出します。
Hue画像からは赤っぽいところ(>120)のみを取り出します。
OpenCVではHueは0-180で色相を表されています。
色見本はこちらのページがわかりやすいです。
2値化処理にはOpenCVは使わず、単純に論理式でTrue or Falseの行列を生成しています。以下のscikit-imageのページを参考にしました。今回、scikit-imageそのものは使わなかったのですが。 *1
3.3. Scikit-image: 画像処理 — Scipy lecture notes
最後に2つの結果を足し合わせて、np.uint8型に変換し、マスク画像としました。 255を掛けているのは結果の確認のためです。
binary_gray = blur001_gray >= 150 binary_h = h >= 120 cw.display_gray_image(255*binary_gray) cw.display_gray_image(255*binary_h) binary_sum_raw = binary_gray|binary_h binary_sum = np.uint8(255*binary_sum_raw) cw.display_gray_image(binary_sum)
5. マスク処理
いよいよマスク処理です!
cv2.bitwise_and
関数でやりました。
img_masked = cv2.bitwise_and(img001_bgr, img001_bgr, mask=binary_sum) cw.display_bgr_image(img_masked)
できました!!やったー(^ ^)ノ
さいごに
実際は色々試行錯誤して迷走しまくりましたが、うまくいったものだけを記録してます。 ぐちゃぐちゃでお見せできたものではないので(^ ^;)
難しかった点は、
- ピンクと白の部分の明るさが違うところ
- 雄しべの部分だけ色味が全然違うところ
の2点ですね。
背景のごちゃごちゃしているところが除ききれていないですが、そのあたりは今後の課題です。(今回は力尽きた、、、)
おしまい