Python+OpenCVのブロブ解析+カラートラッキングで物体追跡する方法をソースコード付きで解説します。
ブロブ解析+カラートラッキングで物体追跡
前回は、HSV色空間に変換して赤色物体を検出する方法を解説しました。
【Python/OpenCV】カラートラッキング(色追跡)で移動物体検知
Python版OpenCVでカラートラッキング(色追跡)を実装し、移動物体を検出する方法をソースコード付きで解説します。
物体の位置を検出し、追跡したい場合はノイズ(追跡対象以外の部分)を除去する必要があります。
ノイズを除去するために、今回はブロブ解析を利用します。
【Python/OpenCV】最大面積のブロブ情報(座標など)を取得
この記事では、Python版OpenCVで面積が最大のブロブを解析(中心座標やサイズなど取得)する方法をソースコード付きで解説します。
ブロブ解析とは、画像をラベリング処理し、ラベル付けされた領域の特徴を解析することです。
Python版OpenCVでは、cv2.connectedComponentsWithStats()で2値画像のブロブ解析ができます。
つまり、マスク画像を与えてやると、面積が最大の領域のみを取り出したりできます。
これを応用すれば、動画に複数の赤色物体が映っていても、一番大きな赤色物体だけを追跡できます。
実行例
■赤色の振り子を追跡している様子
動画解説版
サンプルコード
サンプルプログラムのソースコードです。
サンプルコードの解説
上記コードは、OpenCVを使ってビデオ内の赤色物体を検出し、その物体の位置を追跡するプログラムです。
以下に各部分の詳細な説明をします。
1. ライブラリのインポート
import cv2
import numpy as np
cv2
: OpenCVライブラリ。画像処理やコンピュータビジョンの機能を提供します。numpy
: 数値計算ライブラリ。配列操作を効率的に行います。
2. 赤色検出関数
def red_detect(img):
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
hsv_min = np.array([0, 127, 0])
hsv_max = np.array([30, 255, 255])
mask1 = cv2.inRange(hsv, hsv_min, hsv_max)
hsv_min = np.array([150, 127, 0])
hsv_max = np.array([179, 255, 255])
mask2 = cv2.inRange(hsv, hsv_min, hsv_max)
return mask1 + mask2
cv2.cvtColor
: 画像をBGR色空間からHSV色空間に変換します。cv2.inRange
: 指定したHSVの範囲内にあるピクセルを抽出し、マスクを作成します。ここでは、赤色の範囲を2つ設定しています。mask1 + mask2
: 2つのマスクを合成して、赤色の領域を検出します。
3. ブロブ解析関数
def analysis_blob(binary_img):
label = cv2.connectedComponentsWithStats(binary_img)
n = label[0] - 1
data = np.delete(label[2], 0, 0)
center = np.delete(label[3], 0, 0)
max_index = np.argmax(data[:, 4])
maxblob = {}
maxblob["upper_left"] = (data[:, 0][max_index], data[:, 1][max_index])
maxblob["width"] = data[:, 2][max_index]
maxblob["height"] = data[:, 3][max_index]
maxblob["area"] = data[:, 4][max_index]
maxblob["center"] = center[max_index]
return maxblob
cv2.connectedComponentsWithStats
: 2値画像のラベリングを行い、各ブロブの統計情報を取得します。np.delete
: 不要なラベル(背景)を削除します。np.argmax
: 最大面積のブロブを特定します。maxblob
: 最大面積のブロブの情報を辞書形式で格納します。
4. メイン関数
def main():
videofile_path = "/Users/github/sample/python/opencv/video/color_tracking/red_pendulum.mp4"
cap = cv2.VideoCapture(videofile_path)
while(cap.isOpened()):
ret, frame = cap.read()
mask = red_detect(frame)
target = analysis_blob(mask)
center_x = int(target["center"][0])
center_y = int(target["center"][1])
cv2.circle(frame, (center_x, center_y), 30, (0, 200, 0), thickness=3, lineType=cv2.LINE_AA)
cv2.imshow("Frame", frame)
cv2.imshow("Mask", mask)
if cv2.waitKey(25) & 0xFF == ord('q'):
break
cap.release()
cv2.destroyAllWindows()
cv2.VideoCapture
: ビデオファイルを読み込みます。cap.read()
: フレームを取得します。red_detect(frame)
: フレーム内の赤色領域を検出します。analysis_blob(mask)
: 赤色領域のブロブ解析を行います。cv2.circle
: 最大面積のブロブの中心に円を描画します。cv2.imshow
: フレームとマスクを表示します。cv2.waitKey
: ‘q’キーが押されるとループを終了します。cap.release()
,cv2.destroyAllWindows()
: リソースを解放し、ウィンドウを閉じます。
関連ページ
【Python版OpenCV超入門】使い方とサンプルコードを解説
Python版OpenCVで画像処理プログラミングを行う方法を入門者向けにソースコード付きで解説するページです。
【画像処理入門】アルゴリズム&プログラミング
画像処理における基本的なアルゴリズムとその実装例(プログラム)についてまとめました。
コメント