OpenCV トラッキング

Salman Mehmood 2024年2月15日
OpenCV トラッキング

このデモンストレーションは、Python と OpenCV を使用して、非常に基本的で単純なモーション検出および追跡システムを作成する方法を学習することを目的としています。この記事の最後に、長方形の境界ボックスを使用してすべての人を追跡することを実現します。

Python と OpenCV を使用してモーション検出および追跡システムを作成する

まず、CAP インスタンスから 2つのフレームを読み取る必要があります。

ret, F1 = CAP.read()

同様に、2 番目のフレームを読み取ります。

ret, F2 = CAP.read()

次に、DF という変数を宣言し、absdiff() 関数を使用します。absdiff() は、最初の F1 と 2 番目の F2 のフレーム間の絶対的な違いを見つけるのに役立ちます。

while CAP.isOpened():
    if ret == False:
        print(ret)
        break
    DF = cv2.absdiff(F1, F2)

cvtColor() メソッドを使用して、この違いをグレースケールモードに変換します。最初のパラメータは DF になります。

2 番目の引数は COLOR_BGR2GRAY で、フレームカラーBGR をグレースケールモードに変換するのに役立ちます。なぜグレースケールモードを見つけているのですか?

後の段階で輪郭を見つけるため、カラーモードよりもグレースケールモードの方が輪郭を見つけるのが簡単です。

Gray_Scale = cv2.cvtColor(DF, cv2.COLOR_BGR2GRAY)

グレースケールモードになったら、GaussianBlur() メソッドを使用してグレースケールフレームをぼかす必要があります。いくつかのパラメータが必要です。1つ目は Gray_Scale、2つ目のパラメーターはカーネルサイズ 5x5、3つ目のパラメーターは Sigma X 値になります。

BL = cv2.GaussianBlur(Gray_Scale, (5, 5), 0)

threshold() メソッドを使用してしきい値を決定する必要があります。2つのオブジェクトを返します。最初の変数は必要ないため、_ を定義します。2 番目の変数は thresh になります。

最初のパラメーターでは、ぼやけた画像をソースとして渡し、2 番目のパラメーターはしきい値 20 になります。最大しきい値は 255 になります。タイプは THRESH_BINARY になります。

_, thresh = cv2.threshold(BL, 20, 255, cv2.THRESH_BINARY)

すべての穴を埋めるために、しきい値を設定した画像を拡張する必要があります。これは、より良い輪郭を見つけるのに役立ちます。dilate() メソッドはいくつかのパラメーターを取ります。最初のパラメーターは定義されたしきい値になり、2 番目のパラメーターはカーネルサイズになりますが、なしを渡します。

3 番目の引数は 3 としての反復回数です。それが機能しない場合は、反復回数を増減できます。

DL = cv2.dilate(thresh, None, iterations=3)

次のステップでは、輪郭を見つけます。findContours() メソッドは 2つの結果をもたらします。1つは輪郭で、もう 1つは階層ですが、2 番目の結果は使用しません。拡張された画像の輪郭を見つけます。

したがって、最初のパラメーターで拡張イメージを渡します。次は、最も一般的に使用される RETR_TREE モードになります。次のパラメータは CHAIN_APPROX_SIMPLE メソッドになります。

CTS, _ = cv2.findContours(DL, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)

次のステップでは、長方形を描画したいので、for ループを使用してすべての輪郭を繰り返します。CTS はリストであり、このリストを繰り返し処理しているため、最初のステップは、boundingRect() メソッドを使用して輪郭のすべての座標を保存することです。

次のステップでは、輪郭領域を見つけます。この領域が特定の値よりも小さい場合、長方形は描画されません。for ループ内で、輪郭領域が 700 未満の場合、反復を続行することを定義します。それ以外の場合は、長方形を描画します。

長方形を描画するには、cv2.rectangle() メソッドを使用する必要があります。ここでの最初の引数は、F1 になるソースになります。2 番目のパラメーターはポイント 1 (x,y) になります。3 番目のパラメーターはポイント 2 になり、次のパラメーターは色の値としてのタプルになり、次のパラメーターは厚さになります。

for CT in CTS:
    (x, y, w, h) = cv2.boundingRect(CT)

    if cv2.contourArea(CT) < 900:
        continue
    cv2.rectangle(F1, (x, y), (x + w, y + h), (0, 255, 0), 2)

動きが見られる場合は、画像にテキストを配置します。cv2.putText() メソッドを使用します。このメソッドは F1 を取り、2 番目はテキストになり、次の引数パラメーターはこのテキストを配置する原点になります。

次のパラメータはフォント面 FONT_HERSHEY_SIMPLEX です。次のパラメータはフォントスケールになります。次はフォントの色になります。次に、最後のパラメータはテキストの太さになります。

cv2.putText(
    F1,
    "Status: {}".format("Movement"),
    (10, 20),
    cv2.FONT_HERSHEY_SIMPLEX,
    1,
    (0, 0, 255),
    3,
)

次に、ループの外側にコードを記述します。まず、出力画像を書き込んで出力を保存し、輪郭を適用した後の結果である F1 を表示します。

次の行では、変数 F2 の新しいフレームを読み取っています。新しいフレームを読み取る前に、F2 の値を F1 に割り当てます。このようにして、2つのフレームの違いを読み取って見つけています。

OP.write(IMG)
cv2.imshow("feed", F1)
F1 = F2
ret, F2 = CAP.read()

完全なソースコード:

import cv2
import numpy as np

CAP = cv2.VideoCapture("input.avi")
FR_W = int(CAP.get(cv2.CAP_PROP_FRAME_WIDTH))

FR_H = int(CAP.get(cv2.CAP_PROP_FRAME_HEIGHT))

FRC = cv2.VideoWriter_fourcc("X", "V", "I", "D")

OP = cv2.VideoWriter("output.avi", FRC, 5.0, (1280, 720))

ret, F1 = CAP.read()
ret, F2 = CAP.read()
print(F1.shape)
while CAP.isOpened():
    if ret == False:
        print(ret)
        break
    DF = cv2.absdiff(F1, F2)
    Gray_Scale = cv2.cvtColor(DF, cv2.COLOR_BGR2GRAY)
    BL = cv2.GaussianBlur(Gray_Scale, (5, 5), 0)
    _, thresh = cv2.threshold(BL, 20, 255, cv2.THRESH_BINARY)
    DL = cv2.dilate(thresh, None, iterations=3)
    CTS, _ = cv2.findContours(DL, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)

    for CT in CTS:
        (x, y, w, h) = cv2.boundingRect(CT)

        if cv2.contourArea(CT) < 900:
            continue
        cv2.rectangle(F1, (x, y), (x + w, y + h), (0, 255, 0), 2)
        cv2.putText(
            F1,
            "Status: {}".format("Movement"),
            (10, 20),
            cv2.FONT_HERSHEY_SIMPLEX,
            1,
            (0, 0, 255),
            3,
        )

    IMG = cv2.resize(F1, (1280, 720))
    OP.write(IMG)
    cv2.imshow("feed", F1)
    F1 = F2
    ret, F2 = CAP.read()

    if cv2.waitKey(40) == 27:
        break

cv2.destroyAllWindows()
CAP.release()
OP.release()

すべての人が動いているので、ステータスが動いていることがわかります。動いている人の周りに描かれている長方形も見ることができます。

OpenCV トラッキング

著者: Salman Mehmood
Salman Mehmood avatar Salman Mehmood avatar

Hello! I am Salman Bin Mehmood(Baum), a software developer and I help organizations, address complex problems. My expertise lies within back-end, data science and machine learning. I am a lifelong learner, currently working on metaverse, and enrolled in a course building an AI application with python. I love solving problems and developing bug-free software for people. I write content related to python and hot Technologies.

LinkedIn

関連記事 - Python OpenCV