Pythonでテンプレートマッチングによる物体トラッキング

  • このエントリーをはてなブックマークに追加

動画内の物体を自動的に追跡(トラッキング)する事ができれば、高価な計測システムを使わなくても変位や速度を知る事が出来ます。ここではPythonのOpenCVを使って動画内の物体検知を行う例を紹介します。

こんにちは。wat(@watlablog)です。ここではパターンマッチングを使って物体トラッキングをする例を紹介します

物体検出・トラッキングの例

当ブログでは過去にいくつか物体検知、トラッキングのプログラムを試してきました。

本記事ではまた違った方法で物体トラッキングをしようとしていますが、まずは過去のおさらいをしてみましょう。

差分で動体検知した例

まずは動画の各フレーム差分を使って動体検知をしてみた例です。詳細は「Python/OpenCVで動体検知!動画の動いている部分を検出」という記事に記載しましたが、この記事に記載のコードを使うと以下の動画に示す処理を行う事ができます。

動いていない物体は黒く、動いている物体は白くなります。何かのトリガとする処理をしたい時等には便利ですが、この動体検知では物体がどちらの方向に動いているかといった情報はわかりません。

輪郭情報でトラッキングした例

Python/OpenCVで動画内の物体トラッキングをする方法」という記事では輪郭抽出を使って物体を検出し、トラッキング(追跡)するコードを紹介しています。

結果の例は以下の動画です。緑の丸い輪郭線が検出結果ですが、当ブログのロゴマークを検出し続けています。

この輪郭線は幾何学的な情報を持っているので、座標を割り出す事が出来ます。以下のグラフは座標情報から\(xy\)情報を抽出してプロットした例です。

輪郭検出から物体トラッキングをした例

この方法であれば移動量の数値化ができ、信号処理をする事も可能なため、工学的な用途に使用する事もできるでしょう。

しかし、背景がいつも黒く(もしくは容易に二値化できる等)、輪郭がいつも綺麗に抽出できるとは限りません。なかなか理想的な状況は少ないのではと思っていました。

パターンマッチングでPIVをした例

Python/OpenCVでPIV計測!粒子移動をベクトル化する」という記事では、PIV(粒子画像速度計測法)プログラムを作ってみました。

本来PIVは流体工学の分野で流れを可視化する事に使われますが、以下のように物体の各部の挙動をベクトル化する事が可能です。

このベクトルは大きさや角度といった数値情報を持っていますので、その数値を適切に処理する事で物体の動きを分析する事も出来ます。

しかし、このPIVは画像内全域でパターンマッチングを行っているため、単一の物体をトラッキングする場合はかなり処理に無駄が出てしまうのがネックです。また、複数のベクトルから着目する物体の動きのみを計算するには、さらに複雑なコードが必要になりそうです。

以下のように動く物体が一つでも、検出されるベクトルはサーチウィンドウのサイズによってしまいます。テンプレート画像を用意する手間が無いというのはメリットの一つですが、時系列分析したい時等はやっかい。

PIVを使った単一物体のトラッキング

本記事の目標

題材:楕円軌道の動画

今回は以下の単一点の動きをトラッキングして数値化する事を目標とします。

楕円の軌道アニメーション

ちなみにこの動画は「Pythonのmatplotlibアニメーションで楕円の軌跡!」という記事で作り方を紹介していますので、是非ご覧下さい。

コードの方針

基本は「Python/OpenCVでPIV計測!粒子移動をベクトル化する」で書いたPIVコードを使います。しかし単一の物体トラッキングにとっては画像の全域サーチは無駄が多いので、ベクトルは1本しか計算しないように作る方針とします。

ベクトルを1本しか計算しなければ、素直にそのベクトルの情報が物体の動きを表現している事になるからです。

本記事は画像処理やプログラミングの専門教育を受けた事が無い素人がライブラリの力を借りてコードを書いています。至らぬ点はあると思いますので、ご使用は自己責任でお願いします。

それでは早速作ってみたコードを紹介します。

Pythonパターンマッチングで物体トラッキングするコード

事前準備:テンプレート画像を用意するために

今回はテンプレート画像を使って物体トラッキングを行います。テンプレート画像は解析対象の画像から抽出するのが手っ取り早いので、元画像を抽出して使用します。

movieフォルダを.py実行フォルダの下に作成し、その中に動画を連番画像にした解析対象の画像を入れてください。

そして、以下のコードを実行すると最初の画像が読み込まれ、matplotlibを使って表示されます。はい、単に画像表示をしているだけです。

マウスカーソルをプロット画面に持ってくると、プロット画面の右下にx座標とy座標が表示されます。トラッキングしたい物体の付近を四角く囲うように、左上と右下の座標をメモります(ここはまだアナログ…)。

本当は以下の外部サイトにあるようなGUI上で範囲指定して選択する方法をとりたかった…。ちょっと自分にはハードルが高いのでまた今度。

Qiita:【python】マウスドラッグで画像から範囲指定する

全コード

以下に全コードを示します。詳細はブログ用に細かくコード内コメントを残しましたのでご確認下さい。

Python/OpenCVでPIV計測!粒子移動をベクトル化する」と同じように、予めmovieフォルダに入れておいた解析用画像を使って物体トラッキング解析を行い、結果の画像をtracking_outフォルダに入れるというものです。

ini_startとini_endに先ほどのテンプレート画像の座標を入力して使います。

コードを実行するとtracking.gifが作成されます。

今回の動画の場合の結果を以下に示します。単一の動点の上にベクトルが重なっている事がわかります。

パターンマッチングによる物体トラッキングの結果

以下はベクトルの大きさを時系列で並べた結果を示しています。ちょっと粗い?

数値化した結果

まとめ

本記事は物体検知や輪郭検出による物体トラッキング、PIVによる動画内動体のベクトル化を紹介しました。

PIVでは画像内全域を走査するため、テンプレート画像が必要無いメリットがありますが、ある一点の動体の数値化には苦労します。

一方、今回作った単一のテンプレート画像のみを使って物体トラッキングをすると、テンプレート画像を用意する手間はありますが、単一動点の数値化は大変楽になりました。

どちらも一長一短ですが、武器は多いに越したことはありません。

テンプレートマッチングは色々使えますね!Twitterでも関連情報をつぶやいているので、wat(@watlablog)のフォローお待ちしています!

SNSでもご購読できます。

コメントを残す

*