今回は、OpenCVでオプティカルフローを計算してみたので、そのソースコードを共有したいと思います。
オプティカルフローは隣接フレーム間の物体の動きをフローとして算出するものです。
オプティカルフローには疎なオプティカルフローと密なオプティカルフローというものが存在し、
■ 疎なオプティカルフロー:特徴点などの画像中の代表点のフローのみ求める
■ 密なオプティカルフロー:各画素のフローを求める
という違いがあります。今回は、各画素のフローを知りたかったので、密なオプティカルフローを求めるプログラムを作り、その結果を表示する実験を行ってみました。
目次
今回の環境
・OS : Windows10(64bit)
・Visual Studio 2015 Community
・OpenCV 3.3.1
(上記全て環境構築済)
今回はOpenCVは環境済の状態でスタートするので、OpenCVの環境構築は以下の記事などを参照してください。
過去記事①:Nugetを使ってOpenCVの環境構築(Visual Studio 2015)
過去記事②:Visual Studio 2015でOpenCV 3.4環境構築(Windows10)
ソースコード
以下に、密なオプティカルフローを求めるプログラムを示します。アルゴリズムとしては2種類を選択できるようにしており、
createOptFlow_Farneback();
createOptFlow_DualTVL1();
のどちらかをコメントアウトして、どちらかを残すことで、残した方のアルゴリズムで動作します。
また、実験しやすいので連番画像を読み込んで動作する形式になっています。
上記プログラムで表示される結果はオプティカルフローの大きさを表示していますが、実際にはフローは方向情報も保持しています。
実行結果
以下のような連番画像を入力に用いました。
こちらの画像はCDNet2014というデータセットで公開されているものです。
TV-L1の実行結果
シーケンス的には吹雪の中を車が走っているような場面になります。以下に、代表的な3フレームの結果を掲載します。
オプティカルフローとして算出されるベクトルの大きさが大きいほど、結果の画像は白くなります。
なんとなく、車の形状のようなものが取れており、適切にオプティカルフローが計算できているように見えます。
処理時間は、画像出力の時間なども含めてはいますが、CPU動作ではかなり低速です。
Farnebackの実行結果
以下に、Franeback法の処理結果も掲載します。
TV-L1と比較すると、少し精度が落ちるような気がしますね。
一方、処理時間に関してはFarnebackの方がかなり速く計算できていますので、用途に応じて使い分けるのが良さそうです。
まとめ
今回はOpenCVでオプティカルフローを計算してみました。OpenCVに標準実装の関数を使うことで、簡単にオプティカルフローを計算することが可能です。