【Python】画像認識で個数カウントをする方法

【Python】画像認識で個数カウントをする方法

公開: 更新:



Pythonで画像認識をして個数をカウントする方法

Pythonで画像内のオブジェクトの個数をカウントするには、OpenCVライブラリの輪郭検出機能を使用します。基本的な手順は画像をグレースケールに変換し、ノイズ除去のためにブラー処理を適用した後、二値化処理で対象物と背景を区別します。

輪郭検出はcv2.findContours()関数で実装でき、検出された輪郭のリストの長さから画像内の物体数を把握できます。前処理の質が結果の精度に影響するため、適切なしきい値設定と輪郭抽出条件の調整が重要です。

import cv2
import numpy as np
import matplotlib.pyplot as plt

image = cv2.imread('objects.jpg')
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
blur = cv2.GaussianBlur(gray, (5, 5), 0)
_, thresh = cv2.threshold(blur, 127, 255, cv2.THRESH_BINARY)
contours, _ = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

result = image.copy()
cv2.drawContours(result, contours, -1, (0, 255, 0), 2)
object_count = len(contours)
cv2.putText(result, f'Count: {object_count}', (10, 30), 
            cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 255), 2)

result_rgb = cv2.cvtColor(result, cv2.COLOR_BGR2RGB)
plt.figure(figsize=(10, 8))
plt.imshow(result_rgb)
plt.title(f'検出されたオブジェクト数: {object_count}')
plt.axis('off')
plt.show()
行番号 詳細説明
1-3行目 必要なライブラリ(OpenCV、NumPyMatplotlib)をインポート
5行目 画像ファイル'objects.jpg'を読み込み
6行目 カラー画像をグレースケールに変換
7行目 ガウシアンブラーを適用してノイズを除去(カーネルサイズ5x5)
8行目 しきい値127で二値化処理を実行(0か255の値に変換)
9行目 二値化画像から外部輪郭のみを検出し、簡略化された輪郭情報を取得
11行目 元画像をコピーして結果表示用の画像を準備
12行目 検出した全輪郭を緑色(0,255,0)で元画像に描画
13行目 検出した輪郭の数を物体の個数としてカウント
14-15行目 画像上に物体数を赤色(0,0,255)のテキストで表示
17行目 OpenCVのBGR形式からMatplotlibのRGB形式に変換
18行目 10x8インチサイズの図を作成
19行目 結果画像を表示
20行目 検出されたオブジェクト数をタイトルとして設定
21行目 軸の目盛りを非表示に設定
22行目 画像を表示
【実行結果】
検出されたオブジェクト数: 5
[画像には5つのオブジェクトが緑色の輪郭線で囲まれ、各オブジェクトがカウントされていることが表示されます]

【PR】『Python』を学べる企業・個人向けのプログラミングコース

画像認識で得られる色彩情報を活用して個数をカウントする方法

色彩情報を活用したオブジェクトカウントでは、HSV色空間への変換が効果的です。HSV色空間では色相や彩度、明度の分離により特定の色を持つオブジェクトを抽出できます。色相は0〜179の範囲で表現され、色ごとに範囲を指定して精密に抽出します。

cv2.inRange()関数を使用して、指定した色相範囲内の画素だけを含む二値マスクを作成し、モルフォロジー演算でノイズを除去します。異なる色のオブジェクトをカウントする場合は、各色に対応するマスクを個別に生成して輪郭検出を行います。

import cv2
import numpy as np
import matplotlib.pyplot as plt

image = cv2.imread('colored_objects.jpg')
hsv = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)

lower_red1 = np.array([0, 100, 100])
upper_red1 = np.array([10, 255, 255])
lower_red2 = np.array([160, 100, 100])
upper_red2 = np.array([179, 255, 255])

lower_blue = np.array([100, 100, 100])
upper_blue = np.array([130, 255, 255])

red_mask1 = cv2.inRange(hsv, lower_red1, upper_red1)
red_mask2 = cv2.inRange(hsv, lower_red2, upper_red2)
red_mask = cv2.bitwise_or(red_mask1, red_mask2)
blue_mask = cv2.inRange(hsv, lower_blue, upper_blue)

kernel = np.ones((5, 5), np.uint8)
red_mask = cv2.morphologyEx(red_mask, cv2.MORPH_OPEN, kernel)
blue_mask = cv2.morphologyEx(blue_mask, cv2.MORPH_OPEN, kernel)

red_contours, _ = cv2.findContours(red_mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
blue_contours, _ = cv2.findContours(blue_mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

result = image.copy()
cv2.drawContours(result, red_contours, -1, (0, 0, 255), 2)
cv2.drawContours(result, blue_contours, -1, (255, 0, 0), 2)

red_count = len(red_contours)
blue_count = len(blue_contours)
cv2.putText(result, f'赤: {red_count}', (10, 30), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 255), 2)
cv2.putText(result, f'青: {blue_count}', (10, 70), cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 0, 0), 2)

result_rgb = cv2.cvtColor(result, cv2.COLOR_BGR2RGB)
plt.figure(figsize=(10, 8))
plt.imshow(result_rgb)
plt.title(f'赤色オブジェクト: {red_count}個, 青色オブジェクト: {blue_count}個')
plt.axis('off')
plt.show()
行番号 詳細説明
1-3行目 必要なライブラリをインポート
5行目 画像ファイル'colored_objects.jpg'を読み込み
6行目 色検出に適したHSV色空間に変換
8-11行目 赤色の範囲を定義(HSVでは赤色は0付近と180付近の2箇所に存在)
13-14行目 青色の範囲を定義
16-18行目 赤色の2つの範囲に対応するマスクを作成し、論理和で統合
19行目 青色のマスクを作成
21行目 モルフォロジー演算用の5x5カーネルを作成
22-23行目 オープニング処理(収縮→膨張)でノイズを除去
25-26行目 赤色と青色のマスクから輪郭を検出
28行目 結果表示用に元画像をコピー
29行目 赤色オブジェクトの輪郭を赤色で描画
30行目 青色オブジェクトの輪郭を青色で描画
32-33行目 検出した輪郭の数から各色のオブジェクト数をカウント
34-35行目 各色のカウント情報を画像上に表示
37-41行目 結果画像をRGBに変換して表示
【実行結果】
赤色オブジェクト: 3個, 青色オブジェクト: 2個
[画像には赤色の輪郭線で囲まれたオブジェクトが3つ、青色の輪郭線で囲まれたオブジェクトが2つ表示されています]

機械学習で画像認識をして個数をカウントする方法

機械学習を用いた画像内のオブジェクト検出では、YOLOv5などの物体検出アルゴリズムが高精度と処理速度を実現します。YOLOは単一のニューラルネットワークで画像全体を一度に処理し、複数のバウンディングボックスとクラスの確率を同時に予測します。

PyTorchTensorFlowなどのフレームワークと事前学習済みモデルを組み合わせて利用します。検出結果からクラス別にオブジェクトの個数をカウントでき、位置情報も取得できます。

import torch
import cv2
import numpy as np
import matplotlib.pyplot as plt
from PIL import Image
import pandas as pd

model = torch.hub.load('ultralytics/yolov5', 'yolov5s', pretrained=True)
img_path = 'street_scene.jpg'
img = Image.open(img_path)
results = model(img)
results_df = results.pandas().xyxy[0]
class_counts = results_df['name'].value_counts()

img_cv = cv2.cvtColor(np.array(img), cv2.COLOR_RGB2BGR)
result_img = img_cv.copy()

for _, row in results_df.iterrows():
    x1, y1, x2, y2 = int(row['xmin']), int(row['ymin']), int(row['xmax']), int(row['ymax'])
    conf = row['confidence']
    label = f"{row['name']} {conf:.2f}"
    
    color_hash = int(hash(row['name'])) % 256
    color = (color_hash, 255 - color_hash, 128)
    
    cv2.rectangle(result_img, (x1, y1), (x2, y2), color, 2)
    cv2.putText(result_img, label, (x1, y1 - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.5, color, 2)

y_pos = 30
for class_name, count in class_counts.items():
    color_hash = int(hash(class_name)) % 256
    color = (color_hash, 255 - color_hash, 128)
    text = f"{class_name}: {count}"
    cv2.putText(result_img, text, (10, y_pos), 
                cv2.FONT_HERSHEY_SIMPLEX, 0.7, color, 2)
    y_pos += 30

result_img_rgb = cv2.cvtColor(result_img, cv2.COLOR_BGR2RGB)
plt.figure(figsize=(12, 10))
plt.imshow(result_img_rgb)
plt.title('YOLOv5によるオブジェクト検出結果')
plt.axis('off')
plt.show()

print("検出されたオブジェクトのカウント:")
print(class_counts)
行番号 詳細説明
1-6行目 必要なライブラリをインポート
8行目 事前学習済みのYOLOv5sモデルをロード
9-10行目 入力画像を読み込み
11行目 モデルを使用して画像内のオブジェクトを検出
12行目 検出結果をパンダスDataFrameとして取得
13行目 各クラスの検出数をカウント
15-16行目 結果表示用に画像をOpenCV形式に変換してコピー
18-27行目 検出された各オブジェクトに対して処理を実行
19行目 バウンディングボックスの座標を整数に変換
20-21行目 確信度スコアを含むラベルテキストを作成
23-24行目 クラス名に基づいて一意の色を生成
26行目 バウンディングボックスを描画
27行目 オブジェクト名と確信度スコアをボックス上部に表示
29-35行目 画像左上に各クラスのカウント情報を表示
37-41行目 結果画像をRGBに変換して表示
43-44行目 検出されたオブジェクトのカウント結果をコンソールに出力
【実行結果】
検出されたオブジェクトのカウント:
person    8
car       6
bus       2
truck     1
Name: count, dtype: int64
[画像には検出された各オブジェクトの周りにバウンディングボックスが描画され、各クラスのカウント情報が表示されています]

※上記コンテンツの内容やソースコードはAIで確認・デバッグしておりますが、間違いやエラー、脆弱性などがある場合は、コメントよりご報告いただけますと幸いです。

ITやプログラミングに関するコラム


ITやプログラミングに関するニュース

ブログに戻る

コメントを残す

コメントは公開前に承認される必要があることにご注意ください。

コードキャンプDX人材育成研修 - IT・プログラミングを知って学べるコネクトメディア 金融業界の業務効率化を加速するニッセイアセットマネジメントの生成AI×GAS活用研修事例 - IT・プログラミングを知って学べるコネクトメディア 【製造業のDX人材育成事例】デジタル人材の即戦力化を実現する、日本ガイシ株式会社の異動者向オンボーディング研修 - ITやプログラミングを知って学べるコネクトメディア フューチャーアーキテクト株式会社が実現した新入社員向けIT研修プログラムでタスクフォース制度が主体的な学びと成長を生み出す - IT・プログラミングを知って学べるコネクトメディア コードキャンプDX人材育成研修 - IT・プログラミングを知って学べるコネクトメディア コードキャンプIT・プログラミング研修事例/【IT新入社員研修】オンラインとオフラインの最適バランスを実現したFutureOneの導入事例 - IT・プログラミングを知って学べるコネクトメディア コードキャンプIT・プログラミング研修事例/【新入社員研修】柔軟なハイブリッド型Java研修で実現した新卒20名の成長と成果|サークレイス株式会社 - ITやプログラミングを知って学べるコネクトメディア コードキャンプIT・プログラミング研修事例/現場により近いところにデジタルを根付かせるDX基礎講座研修|株式会社ブリヂストン - ITやプログラミングを知って学べるコネクトメディア コードキャンプIT・プログラミング研修事例/業務の効率化・DX推進に向けたIT人材育成への第一歩|株式会社カナエ - ITやプログラミングを知って学べるコネクトメディア 企業・法人向けのIT・プログラミング研修 - ITやプログラミングを知って学べるコネクトメディア

新着記事

対象者別で探す

子供(小学生・中学生・高校生)向け
プログラミング教室検索する

子供(小学生・中学生・高校生)がロボットやプログラミング言語を学ぶことができるオフラインからオンラインスクールを検索、比較することが可能です。

子供(小学生・中学生・高校生)
プログラミング教室検索する

ITやプログラムなどの
最新情報を検索する

日々、新しいITやプログラミング言語の情報が流れていきますが、特定の情報を時系列でニュースやコラムを確認することができます。

ITやプログラムなどの
最新情報を検索する