【前編】Pythonでカンタン画像解析~タピオカはいくつ?~
IT技術
python で画像解析してみよう!
業務の効率化や不明確値の定量化に大きく貢献してくれる「画像解析」。
難しそうに思うかもしれませんが、python を使えば、誰でも簡単に出来てしまうのです。
python の特色である「モジュール」と「プログラミング技術」を活用して、仕事の効率化をはかりましょう!
環境構築
以下の説明は、Anaconda および jupyter notebook のユーザーを前提として記述しています。
画像処理用モジュール「opencv」
代表的な画像処理用モジュールとして、「opencv」もしくは「pillow」があげられます。
機能やインストール、その他の手間から見ると大差はありませんが、処理速度は opencv の方が早いです。
もちろん他のモジュールでも同じことができますが、今回は「opencv」を用いて説明します。
インストール
まずは、opencv をインストールしましょう。
Anaconda prompt を起動後に、以下のコマンドを入力するだけで完了です。
1pip install opencv-python
準備完了!
あとは、コード中に from cv2 import * と記載するだけ。
これで、opencv を使って画像を解析できちゃいます!
「異物検知」で画像解析
「画像解析」にはさまざまなやり方・解析対象があります。
今回は、そのなかでもよく使う「異物検知」を使おうと思います。
異物検知は、「顔認証アルゴリズム」や「トリミングしたい箇所の検出」など、さまざまな場面に応用できるため、日々の業務でも大活躍間違いなしですよ!
タピオカを数えてみよう
それではさっそく、下のイラストを解析して、タピオカがいくつあるか数えてみましょう!
色の明暗で判定する
一番簡単な解析は、白黒で読み込み、色の明るさで判定する方法です。
opencv は、numpy array 形式で画像を読み込んでくれます。
つまり、numpy.where 関数を使って「一定範囲の数値=暗さ」の領域を抽出すれば、タピオカを検出できるはずです。
サンプルコード
1from cv2 import *
2from matplotlib import pyplot
3## 画像を白黒で読み込む ##
4img_bw = imread('tapioca_drink.png', 2) # ,2は白黒で読み込むという合図
5
6## 一定の明るさ(この場合は120)より暗い部分のみ残してみる ##
7img_mod = where(img_bw > 120 , 0, img_bw)
8pyplot.imshow(img_mod)
結果は失敗に…
コードを実行すると、このような結果になりました。
どうやら、ストローの部分も濃い色であるため、単純な色の明るさだけだと検出できないようです。
HSV を使ってみよう
このような場合、以下のような対処方法が考えられます。
- cv2.bitwise_and()を使ってマスク処理する
- for 分で条件分岐させる
- HSV を使ってマスク処理する
今回は、HSV を使ってマスク処理してみましょう。
HSV とは?
「HSV」は、色を以下の要素で表現する方式のことです。
- Hue(色相)
- Saturation(彩度)
- Value(明度)
HSV は、人間が色彩を調整する際の感覚に近いため、簡単に可読性の高いコードを書くことができるのです。
サンプルコード
1from cv2 import *
2from numpy import array, where, ones_like
3from matplotlib import pyplot
4
5
6## カラーで読み込んだ画像をcvtColorを用いてhsvに変更 ##
7img_cl = imread('tapioca_drink.png', 6)
8img_hsv = cvtColor(img_cl, COLOR_BGR2HSV)
9
10## 赤色の範囲を定義 ##
11hsv_min = array([150, 64, 0])
12hsv_max = array([180, 255, 255])
13
14## 赤色をマスクする ##
15mask = inRange(img_hsv, hsv_min, hsv_max)
16mask = bitwise_not(mask)
17img_hsv = bitwise_and(img_hsv, img_hsv, mask = mask)
18
19## 背景の黒い部分などを白くする ##
20img_hsv[:, :, 2] = where(img_hsv[:, :, 2] < 10, 255 * ones_like(img_hsv[:, :, 2]), img_hsv[:, :, 2])
21
22## HSVからBGRを経由して白黒に変更する ##
23img_bgr = cvtColor(img_hsv, COLOR_HSV2BGR)
24img_bw = cvtColor(img_bgr, COLOR_BGR2GRAY)
25
26## ごみを取るためのブラシ処理 ##
27img_bw_b = blur(img_bw, (3, 3))
28
29## 暗い部分のみ残してみる ##
30img_bw_b = where(img_bw_b < 90, 255, 0)
31pyplot.imshow(img_bw_b)
結果は…成功!
上記コードを実行すると、以下のような結果になりました。
しっかりタピオカのところだけ切り出せていますね!
タピオカはいくつある?
では、タピオカの数を確認してみましょう。
findContours()関数を使おう
これも、opencv の「findContours()関数」を使えば簡単にできてしまいます。
これは、解析対象の numpy.array を解析し、図の中にいくつ図形があるのか検知します。
先ほどの画像のようにはっきり明瞭なコントラストがあれば、一発で図形を見出すことが可能です。
サンプルコード
1## 型調整のためuint関数を用いる ##
2from numpy import dtype, uint8
3
4## findContours関数でimg_bw_bの明るい領域の枠線を抽出する ##
5cnt_lst, hir_lst = findContours(array(img_bw_b, dtype = uint8), RETR_TREE, CHAIN_APPROX_SIMPLE)
6
7## タピオカが何個検出されたかprintする ##
8print("The number of particle is :", len(cnt_lst))
9
10## 検出したタピオカを線で囲ってみる ##
11for cnt in cnt_lst:
12 img_bw_b = drawContours(img_bw_b, [cnt], 0, 128, 5)
13pyplot.imshow(img_bw_b)
結果
上記コードを実行した結果がこちらです。
カウントしたところ、「15個」と出力されていますね。
ちゃんとイラストと一致しています、大成功です!
他にはどんな処理ができる?
これ以外にも、「contourArea()」や「areLength()」を使って、タピオカの面積率や周囲の長さ、あるいは重心の位置を抽出したり…
…といった処理が可能です。
しかし、これらの検出方法は「粒子同士が重なっている場合、同一粒子と見なす」可能性が高いです。
「Watershed」を使えばこの問題は解決しますが、今回は割愛します。
後半へつづく!
後編では、画像解析で「錆の面積」を算出してみたいと思います!
後半はこちら
こちらの記事もオススメ!
2020.07.28機械学習 特集知識編人工知能・機械学習でよく使われるワード徹底まとめ!機械学習の元祖「パーセプトロン」とは?【人工知能】ニューラルネ...
2020.07.30Python 特集実装編※最新記事順Responder + Firestore でモダンかつサーバーレスなブログシステムを作ってみた!P...
2020.07.17ライトコード的「やってみた!」シリーズ「やってみた!」を集めました!(株)ライトコードが今まで作ってきた「やってみた!」記事を集めてみました!※作成日が新し...
ライトコードでは、エンジニアを積極採用中!
ライトコードでは、エンジニアを積極採用しています!社長と一杯しながらお話しする機会もご用意しております。そのほかカジュアル面談等もございますので、くわしくは採用情報をご確認ください。
採用情報へ
「好きを仕事にするエンジニア集団」の(株)ライトコードです! ライトコードは、福岡、東京、大阪、名古屋の4拠点で事業展開するIT企業です。 現在は、国内を代表する大手IT企業を取引先にもち、ITシステムの受託事業が中心。 いずれも直取引で、月間PV数1億を超えるWebサービスのシステム開発・運営、インフラの構築・運用に携わっています。 システム開発依頼・お見積もり大歓迎! また、現在「WEBエンジニア」「モバイルエンジニア」「営業」「WEBデザイナー」を積極採用中です! インターンや新卒採用も行っております。 以下よりご応募をお待ちしております! https://rightcode.co.jp/recruit