
【前編】Pythonでカンタン画像解析~タピオカはいくつ?~
2021.12.20
python で画像解析してみよう!
業務の効率化や不明確値の定量化に大きく貢献してくれる「画像解析」。
難しそうに思うかもしれませんが、python を使えば、誰でも簡単に出来てしまうのです。
python の特色である「モジュール」と「プログラミング技術」を活用して、仕事の効率化をはかりましょう!
環境構築
以下の説明は、Anaconda および jupyter notebook のユーザーを前提として記述しています。
画像処理用モジュール「opencv」
代表的な画像処理用モジュールとして、「opencv」もしくは「pillow」があげられます。
機能やインストール、その他の手間から見ると大差はありませんが、処理速度は opencv の方が早いです。
もちろん他のモジュールでも同じことができますが、今回は「opencv」を用いて説明します。
インストール
まずは、opencv をインストールしましょう。
Anaconda prompt を起動後に、以下のコマンドを入力するだけで完了です。
1 | pip install opencv-python |
準備完了!
あとは、コード中に from cv2 import * と記載するだけ。
これで、opencv を使って画像を解析できちゃいます!
「異物検知」で画像解析
「画像解析」にはさまざまなやり方・解析対象があります。
今回は、そのなかでもよく使う「異物検知」を使おうと思います。
異物検知は、「顔認証アルゴリズム」や「トリミングしたい箇所の検出」など、さまざまな場面に応用できるため、日々の業務でも大活躍間違いなしですよ!
タピオカを数えてみよう
それではさっそく、下のイラストを解析して、タピオカがいくつあるか数えてみましょう!

色の明暗で判定する
一番簡単な解析は、白黒で読み込み、色の明るさで判定する方法です。
opencv は、numpy array 形式で画像を読み込んでくれます。
つまり、numpy.where 関数を使って「一定範囲の数値=暗さ」の領域を抽出すれば、タピオカを検出できるはずです。
サンプルコード
1 2 3 4 5 6 7 8 | from cv2 import * from matplotlib import pyplot ## 画像を白黒で読み込む ## img_bw = imread('tapioca_drink.png', 2) # ,2は白黒で読み込むという合図 ## 一定の明るさ(この場合は120)より暗い部分のみ残してみる ## img_mod = where(img_bw > 120 , 0, img_bw) pyplot.imshow(img_mod) |
結果は失敗に…

コードを実行すると、このような結果になりました。
どうやら、ストローの部分も濃い色であるため、単純な色の明るさだけだと検出できないようです。
HSV を使ってみよう
このような場合、以下のような対処方法が考えられます。
- cv2.bitwise_and()を使ってマスク処理する
- for 分で条件分岐させる
- HSV を使ってマスク処理する
今回は、HSV を使ってマスク処理してみましょう。
HSV とは?
「HSV」は、色を以下の要素で表現する方式のことです。
- Hue(色相)
- Saturation(彩度)
- Value(明度)
HSV は、人間が色彩を調整する際の感覚に近いため、簡単に可読性の高いコードを書くことができるのです。
サンプルコード
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | from cv2 import * from numpy import array, where, ones_like from matplotlib import pyplot ## カラーで読み込んだ画像をcvtColorを用いてhsvに変更 ## img_cl = imread('tapioca_drink.png', 6) img_hsv = cvtColor(img_cl, COLOR_BGR2HSV) ## 赤色の範囲を定義 ## hsv_min = array([150, 64, 0]) hsv_max = array([180, 255, 255]) ## 赤色をマスクする ## mask = inRange(img_hsv, hsv_min, hsv_max) mask = bitwise_not(mask) img_hsv = bitwise_and(img_hsv, img_hsv, mask = mask) ## 背景の黒い部分などを白くする ## img_hsv[:, :, 2] = where(img_hsv[:, :, 2] < 10, 255 * ones_like(img_hsv[:, :, 2]), img_hsv[:, :, 2]) ## HSVからBGRを経由して白黒に変更する ## img_bgr = cvtColor(img_hsv, COLOR_HSV2BGR) img_bw = cvtColor(img_bgr, COLOR_BGR2GRAY) ## ごみを取るためのブラシ処理 ## img_bw_b = blur(img_bw, (3, 3)) ## 暗い部分のみ残してみる ## img_bw_b = where(img_bw_b < 90, 255, 0) pyplot.imshow(img_bw_b) |
結果は…成功!
上記コードを実行すると、以下のような結果になりました。
しっかりタピオカのところだけ切り出せていますね!

タピオカはいくつある?
では、タピオカの数を確認してみましょう。
findContours()関数を使おう
これも、opencv の「findContours()関数」を使えば簡単にできてしまいます。
これは、解析対象の numpy.array を解析し、図の中にいくつ図形があるのか検知します。
先ほどの画像のようにはっきり明瞭なコントラストがあれば、一発で図形を見出すことが可能です。
サンプルコード
1 2 3 4 5 6 7 8 9 10 11 12 13 | ## 型調整のためuint関数を用いる ## from numpy import dtype, uint8 ## findContours関数でimg_bw_bの明るい領域の枠線を抽出する ## cnt_lst, hir_lst = findContours(array(img_bw_b, dtype = uint8), RETR_TREE, CHAIN_APPROX_SIMPLE) ## タピオカが何個検出されたかprintする ## print("The number of particle is :", len(cnt_lst)) ## 検出したタピオカを線で囲ってみる ## for cnt in cnt_lst: img_bw_b = drawContours(img_bw_b, [cnt], 0, 128, 5) pyplot.imshow(img_bw_b) |
結果
上記コードを実行した結果がこちらです。

カウントしたところ、「15個」と出力されていますね。
ちゃんとイラストと一致しています、大成功です!
他にはどんな処理ができる?
これ以外にも、「contourArea()」や「areLength()」を使って、タピオカの面積率や周囲の長さ、あるいは重心の位置を抽出したり…
…といった処理が可能です。
しかし、これらの検出方法は「粒子同士が重なっている場合、同一粒子と見なす」可能性が高いです。
「Watershed」を使えばこの問題は解決しますが、今回は割愛します。
後半へつづく!
後編では、画像解析で「錆の面積」を算出してみたいと思います!
後半はこちら
こちらの記事もオススメ!
書いた人はこんな人

- 「好きを仕事にするエンジニア集団」の(株)ライトコードです!
ライトコードは、福岡、東京、大阪の3拠点で事業展開するIT企業です。
現在は、国内を代表する大手IT企業を取引先にもち、ITシステムの受託事業が中心。
いずれも直取引で、月間PV数1億を超えるWebサービスのシステム開発・運営、インフラの構築・運用に携わっています。
システム開発依頼・お見積もり大歓迎!
また、現在「WEBエンジニア」「モバイルエンジニア」「営業」「WEBデザイナー」「WEBディレクター」を積極採用中です!
インターンや新卒採用も行っております。
以下よりご応募をお待ちしております!
https://rightcode.co.jp/recruit
ライトコードの日常12月 1, 2023ライトコードクエスト〜東京オフィス歴史編〜
ITエンタメ10月 13, 2023Netflixの成功はレコメンドエンジン?
ライトコードの日常8月 30, 2023退職者の最終出社日に密着してみた!
ITエンタメ8月 3, 2023世界初の量産型ポータブルコンピュータを開発したのに倒産!?アダム・オズボーン