【Python/OpenCV】ブロブ解析+カラートラッキングで物体追跡

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で画像処理プログラミングを行う方法を入門者向けにソースコード付きで解説するページです。
【画像処理入門】アルゴリズム&プログラミング
画像処理における基本的なアルゴリズムとその実装例(プログラム)についてまとめました。

コメント