質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

87.37%

オプティカルフローで物体検知をしたいが新規に画面に入った物体が検知できない

解決済

回答 1

投稿

  • 評価
  • クリップ 0
  • VIEW 724

score 6

現状

pythonでオプティカルフローを使用しています。
様々なサイトのサンプルコードを使用させてもらって実験をしているのですが、画面に新しく入ってきた物体の検知ができません。
どこがおかしいのか、ご教示いただけると幸いです。

問題点

最初から画面に映っていた物体の検知はできますが、動画の途中から新しく入ってきた物体の検知ができません。

import cv2
import numpy as np


input_file = 'input.mp4'
output_file = 'output.mp4'
cap = cv2.VideoCapture(input_file)

width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
fourcc = cv2.VideoWriter_fourcc('m', 'p', '4', 'v')
fps = int(cap.get(cv2.CAP_PROP_FPS))
writer = cv2.VideoWriter(output_file, fourcc, fps, (width, height))

# Shi-Tomasiのコーナー検出パラメータ
feature_params = dict( maxCorners = 100,
                       qualityLevel = 0.3,
                       minDistance = 20,
                       blockSize = 20,
                     )

# Lucas-Kanade法のパラメータ
lk_params = dict( winSize  = (15,15),
                  maxLevel = 2,
                  criteria = (cv2.TERM_CRITERIA_EPS | cv2.TERM_CRITERIA_COUNT, 10, 0.03))

# ランダムに色を100個生成(値0~255の範囲で100行3列のランダムなndarrayを生成)
color = np.random.randint(0, 255, (100, 3))

# 最初のフレームの処理
end_flag, frame = cap.read()
gray_prev = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
feature_prev = cv2.goodFeaturesToTrack(gray_prev, mask = None, **feature_params)
mask = np.zeros_like(frame)

while(end_flag):
    # グレースケールに変換
    gray_next = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)

    # オプティカルフロー検出
    feature_next, status, err = cv2.calcOpticalFlowPyrLK(gray_prev, gray_next, feature_prev, None, **lk_params)

    # オプティカルフローを検出した特徴点を選別(0:検出せず、1:検出した)
    good_prev = feature_prev[status == 1]
    good_next = feature_next[status == 1]

    # オプティカルフローを描画
    for i, (next_point, prev_point) in enumerate(zip(good_next, good_prev)):
        prev_x, prev_y = prev_point.ravel()
        next_x, next_y = next_point.ravel()
        ans = cv2.norm(next_point - prev_point);
        mask = cv2.line(mask, (next_x, next_y), (prev_x, prev_y), color[i].tolist(), 2)
        frame = cv2.line(frame, (int(width/2), 0), (int(width/2), int(height)), (255, 255, 255), thickness=1, lineType=cv2.LINE_4)
    img = cv2.add(frame, mask)

    gray_prev = gray_next.copy()
    feature_prev = good_next.reshape(-1, 1, 2)
    #feature_prev = cv2.goodFeaturesToTrack(gray_next, mask = None, **feature_params)
    end_flag, frame = cap.read()

    writer.write(img)

writer.release()
cap.release()

試したこと

上記コードのwhile文の最後の方の
feature_prev = good_next.reshape(-1, 1, 2)
を以下に変更すると新しく動画に入ってきたものを検知できますが、連続した特徴点が取れなくなってしまいます。
feature_prev = cv2.goodFeaturesToTrack(gray_next, mask = None, **feature_params)

行いたいこと

Frameごとに異なる特徴点ではなく、連続した特徴点で物体検知をしたいのですが、どのようにすれば良いでしょうか?
ご教示いただけますと幸いです。
よろしくお願い致します。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

checkベストアンサー

0

最初のフレームで(goodFeaturesToTrack()で)追跡対象たる特徴点群feature_prevを決定して,
以降はそれを(calcOpticalFlowPyrLK()で)追跡している,と.
すなわち,
calcOpticalFlowPyrLK()の実施時点でのfeature_prevが追跡対象の点群というわけだ.

だったら,
例えば,各フレームの処理の最後に feature_prev にてきとーに新しい点のデータを1点加えてやったとしたらどうなるのだろうか?
次のフレームでのcalcOpticalFlowPyrLK()ではその点処理対象になるのではないだろうか.

であれば,
新しく現れた点を追跡対象に加えたいならば,
(何かてきとーなタイミングで)新しい点をgoodFeaturesToTrack()か何か検出して,
それを追跡対象点群であるfeatrue_prev追加してやればよいだけではないだろうか.

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2021/03/22 11:09

    ありがとうございます!
    勉強になりました。教えていただいたことを参考い色々試してみようと思います。

    キャンセル

  • 2021/03/22 11:19

    これ系はいろいろやってみるしかないです.

    点の個数を制限してみたらある移動物体が長いこと視野内に留まっていると他の物体の処理が滞るだとか,
    動かない背景上の点は捨てたいのだけど「移動量が小さい点は捨てる」とかやってると,追跡中の物体の見かけの移動量が減ったら追跡が途切れちゃうだとか,

    まぁいろいろと困ったことが次から次へと起きるんじゃないかと思います.

    キャンセル

  • 2021/03/22 11:49

    ありがとうございます!
    >まぁいろいろと困ったことが次から次へと起きるんじゃないかと思います.
    やはりそうなんですね。。。頑張ってみます!

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 87.37%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る