Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
87
Help us understand the problem. What is going on with this article?
@hitomatagi

OpenCVでオプティカルフローをリアルタイムに描画する(Shi-Tomasi法、Lucas-Kanade法)

More than 3 years have passed since last update.

はじめに

OpenCV(Open Source Computer Vision Library)はBSDライセンスの映像/画像処理ライブラリ集です。画像のフィルタ処理、テンプレートマッチング、物体認識、映像解析、機械学習などのアルゴリズムが多数用意されています。

OpenCVを使った動体追跡の例 (OpenCV Google Summer of Code 2015)
https://www.youtube.com/watch?v=OUbUFn71S4s

インストールと簡単な使い方はこちら
OpenCV 3(core + contrib)をPython 3の環境にインストール&OpenCV 2とOpenCV 3の違い&簡単な動作チェック

静止画像のフィルター処理についてはこちら
OpenCVでエッジ検出してみる
OpenCVで各種フィルター処理をする(グラディエント、ハイパス、ラプラシアン、ガウシアン)
OpenCVで特徴点を抽出する(AgastFeature, FAST, GFTT, MSER, AKAZE, BRISK, KAZE, ORB, SimpleBlob)

動画ファイルの処理についてはこちら
OpenCVで動画をリアルタイムに変換してみる
OpenCVでWebカメラ/ビデオカメラの動画をリアルタイムに変換してみる

今回は、OpenCVを使ってオプティカルフローをリアルタイムに描画してみます。

オプティカルフロー

オプティカルフローとは、動画において、特徴点のフレームとフレームの差分(ベクトル)を表現する方法です。フレームレートは、通常一定なので、特徴点の速度を表現しているとも言えます。
計算方法は、テンプレートマッチングを用いる方法や特徴点/特徴量を用いる方法があります。
今回は、特徴点を用いてオプティカルフローを描画してみます。流れは以下のようになります。

  1. 前のフレームに対して特徴点を検出します。今回は、Shi-Tomashiの方法を用いて特徴点を検出します。
    cv2.goodFeaturesToTrack() を利用します。
  2. 前フレーム内の特徴点のオプティカルフローを、前フレーム、次フレームの情報を用いて、画像ピラミッド型Lucas-Kanade法で計算します。
    cv2.calcOpticalFlowPyrLK() を利用します。
  3. フレームにオプティカルフローを描画します。
  4. 2と3を繰り返します。

プログラム

  • 動作環境

    • python: 3.5.1
    • OpenCV: 3.1.0
  • 動画データ
    OpenCVに付属しているサンプル動画を利用しました。
      OpenCV\opencv\sources\samples\data\768x576.avi

LucasKande.py
import numpy as np
import cv2

cap = cv2.VideoCapture('768x576.avi')

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

# 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()
        mask = cv2.line(mask, (next_x, next_y), (prev_x, prev_y), color[i].tolist(), 2)
        frame = cv2.circle(frame, (next_x, next_y), 5, color[i].tolist(), -1)
    img = cv2.add(frame, mask)

    # ウィンドウに表示
    cv2.imshow('window', img)

    # ESCキー押下で終了
    if cv2.waitKey(30) & 0xff == 27:
        break

    # 次のフレーム、ポイントの準備
    gray_prev = gray_next.copy()
    feature_prev = good_next.reshape(-1, 1, 2)
    end_flag, frame = cap.read()

# 終了処理
cv2.destroyAllWindows()
cap.release()

OpenCVなら、特徴点の抽出、オプティカルフローの計算ともに、メソッドを1個呼ぶだけです。
なんて便利な世の中なんでしょう(^^;)

実行結果

実行すると、リアルタイムにオプティカルフローが描画されます。

result1.png

result2.png

result3.png

result4.png

87
Help us understand the problem. What is going on with this article?
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away

Comments

No comments
Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account Login
87
Help us understand the problem. What is going on with this article?