こんにちは、ヒガシです。
このページではPython-openCVを使って、以下の画像のように画像内にある物体の個数を一発で算出する方法をご紹介していきます。
あなたのやりたいことと一致していれば、ぜひ続きをご覧ください。
画像内物体の個数を数える方法解説
実際のプログラム紹介に入る前に、まずはどのような方法で画像内物体の個数を数えるのかをご説明していきます。
基本的な考え方は以下の通りです。
①画像をモノクロ画像として読み込み、ある閾値で二値化(白と黒だけの画像に)する
②①で作成した画像の輪郭を抽出する
③②で抽出した輪郭の数を数える
ポイントは①の二値化する部分で、この閾値が小さすぎると②の作業で輪郭をきれいに検出できず、それが物体個数の算出に悪影響を与える可能性があります。また、この閾値が大きすぎると輪郭そのものを検出できず、正しく物体個数を算出することができません。
というわけでこの①②の作業は閾値を変えながら何度か繰り返して輪郭がきれいにとれていそうな設定を見つける必要があります。
事前解説はこのくらいにして実際の作業に入っていきましょう。
必要なライブラリを準備する
今回使うのはopenCVのみです。
インストールしていない場合は以下でやり方を解説してますので、参考にしてみてください。
【Python-OpenCV】インストール方法、バージョン確認、使用時の注意点
画像内物体の個数を数えるサンプルコード
今回は以下の画像を例に実演してみます。
こんな感じで各物体の明るさがすべて異なっていますので、先ほど紹介した閾値で結果がどのようにかわるか見てみることにしましょう。
それでは本題である画像を数えるサンプルコードのご紹介です。
※先ほど紹介した画像がbase_file.jpgという名前でプログラム実行フォルダに保存されていることを想定して書いています。
#ライブラリインポート
import cv2
import numpy as np
#物体の個数を数える
img=cv2.imread('base_file.jpg',cv2.IMREAD_GRAYSCALE)
h,w=img.shape[:2]
#二値化する際の輝度閾値
thresh_value=50
#二値化
thresh, img_thresh = cv2.threshold(img, thresh_value, 255, cv2.THRESH_BINARY)
#輪郭抽出
contours, hierarchy = cv2.findContours(img_thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
#輪郭の個数を表示
print(len(contours))
#検出できた物体確認用の画像作成
black_img=np.zeros((h,w),np.uint8)
for i in range(len(contours)):
cv2.drawContours(black_img, contours, i, 255, -1)
cv2.imwrite('contours.jpg',black_img)
サンプルコードの実行結果
それでは先ほどのコードを実行してみましょう。
(thresh_value=50)
結果は15という数値と以下の画像が出力されました。
(以下の画像が検出できた物体を表しています。)
丸の数を数えていただくと15個あることがわかると思います。
というわけで問題なく物体の個数を検出できています。
つぎは先ほどのコードを修正して
thresh_value=150で実行してみます。
結果は7という数値と以下の画像が出力されました。
7つ検出されていますね。
ベース画像と比較してみましょう。
thresh_value=150の場合は比較的明るめの物体のみを検出していることがわかると思います。
こんな感じでthresh_value(二値化の際の閾値)次第で検出できる物体が変わってきますので、ここはあなたの準備した画像に適した数値を探していきましょう。
おわりに
というわけで今回はpython-openCVを使って、画像内物体の個数を算出する方法をご紹介しました。
画像処理の際などにぜひご活用ください。
このように、私のブログでは様々なスキルを紹介しています。
今は仕事中で時間がないかもしれませんが、ぜひ通勤時間中などに他の記事も読んでいただけると嬉しいです。
⇒興味をもった方は【ヒガサラ】で検索してみてください。
確実にスキルアップできるはずです。
最後に、この記事が役に立ったという方は、ぜひ応援よろしくお願いします。
↓ 応援ボタン
にほんブログ村
それではまた!
Follow @HigashiSalary
コメント