Optical flow は物体の動きを検出する、動いている物体の検出、追跡(tracking) に有効な手法だ。
OpenCV の解説記事 [オプティカルフロー(Optical Flow)]
(http://labs.eecs.tottori-u.ac.jp/sd/Member/oyamada/OpenCV/html/py_tutorials/py_video/py_lucas_kanade/py_lucas_kanade.html)
./samples/cpp/tutorial_code/video/optical_flow/optical_flow_dense.cpp
./samples/cpp/tutorial_code/video/optical_flow/optical_flow.cpp
./samples/python/tutorial_code/video/optical_flow/optical_flow_dense.py
./samples/python/tutorial_code/video/optical_flow/optical_flow.py
Optical flow には密なoptical flow と疎なoptical flow とがある。
[Object Tracking]
(https://docs.opencv.org/3.4/dc/d6b/group__video__track.html#ga5d10ebbd59fe09c5f650289ec0ece5af)
OpenCV – The Gunnar-Farneback optical flowの説明は、
どのようにoptical flow (u, v) のベクトルを2枚の画像から算出するのかを示している。
https://github.com/pathak22/pyflow
以下のコードで、otical flow の大きさと向きを元に色を与えているので、画像として見ることができる。
mag, ang = cv2.cartToPolar(flow[..., 0], flow[..., 1])
hsv[..., 0] = ang * 180 / np.pi / 2
hsv[..., 2] = cv2.normalize(mag, None, 0, 255, cv2.NORM_MINMAX)
- 特徴
- Cython を利用した実装
- 主だった実装の分はC++言語で書かれている。
- OpenMPを使ってマルチコアを活用するようには書かれていない。(#pragma omp の記載がない。)
- https://github.com/pathak22/pyflow/tree/master/src
- デモコードは、2枚の画像からその間のoptical flow を算出するだけのとても簡潔なものになっている。
- 動画を処理したいときは、自分で拡張すること。
- このサンプルdense-solution.py は依存ライブラリが opencv-python, numpy である。
- そのため、NVIDIA の使えないノートPCでもすぐに動作させることができる。
$ dense-solution.py
渋谷駅前の交差点の動画の例
$ sparse-solution.py
OpenCVのOptical Flowを包括的に試すサンプル
qiita [OpenCVでとらえる画像の躍動、Optical Flow]
(https://qiita.com/icoxfog417/items/357e6e495b7a40da14d8)
Youtube FlowNet 2.0: Evolution of Optical Flow Estimation with Deep Networks
MR flow
GPU
FPGA
Optical flow の研究には、固定カメラの場合と移動カメラの場合とがある。さらに移動カメラの場合でも、視点の高さと水平方向の向きが保たれる場合と、視点の高さ水平方向の向きとも変化する場合がある。それぞれによってoptical flow の使い方が変わってくる。
監視カメラの場合には、圧倒的に多くが固定カメラである。上記の渋谷交差点の画像では、動き差分では、個々の人物を分離できない。
それがoptical flow を用いた場合には、人の流れの中で逆方向に動くしている人などを見つけやすい。
移動カメラのうち、視点の高さと水平方向の向きが一定しているのがある。そうだ、自動車の分野でのOptical flowの分野だ。走行中の車両のうち、自分に近づいてくるものを検知して、しかもその移動速度を評価することができる。
そういった目的のために、リアルタイムにOptical flow を得るために、FPGAの実装がある。
Xilinx FPGA VivadoHLSを使用するLucas‐Kanadeオプティカルフローアルゴリズムの実装
Intel FPGA Optical Flow Design Example
-
Real-time moving obstacle detection using opticalflow models
-
An optical flow-based sensing system for reactive mobile robot navigation
scikit-image Registration using optical flow
昆虫
カエルの視覚
Anatomy and Physiology of Vision in the Frog (Rana pipiens)
私見
Optical flow とステレオカメラの視差とは共通性があると感じている。
2つの画像間で特徴点の対応をとって、その差異を示すことで共通点がある。
視差というのは、左カメラと右カメラの間を、視点が動くことによって生じるoptical flow と捉えることができる。
Optical flow を計算するには、時間差のある画像であることが必須だ。
それに対し、深度 depth (= 視差の逆数)は最近では、単眼の画像からCNNで推定できるようになってきている。
ということは、optical flow が推定可能な状況においては、optical flow と深度の両方を認識可能になっていることを意味している。optical flow 自体は視線の方向を示すものにすぎない。いいかえれば、optical flow 自体は、2次元上のベクトルに過ぎない。
そこに、深度情報から換算される3次元の点群と、optical flow とを組み合わせると、対象点の動きが、3次元の位置(x ,y, z)と3次元の移動量(dx, dy, dz) として換算可能になる。
いま、CNNの進展が可能にしつつあることは、そういうことなんだ。
視差の計算でもoptical flowの計算でも、いきなり解像度の高い領域で対応点をとろうとすると結果が暴れることが知られている。
そのため、今どきの計算では、解像度の粗い対応点マッチングのあとに解像度の高い対応点マッチングをするものなっている。
Optical flowと視差についての共通性については、「NVIDIA Optical Flow SDK 2.0には視差計算やトラッキング機能が追加されたようです」という記事を見つけました。
https://docs.nvidia.com/video-technologies/optical-flow-sdk/nvofa-application-note/index.html
のドキュメントのなかにもNVIDIA Optical Flow AcceleratorがOptical Flow ModeとStereo Disparity Modeとがあることを見つけました。
CNNでのoptical flow の計算でも、粗い画像でのoptical flow の推定の層の後段で、一段高い解像度でのoptical flow の推定を実施している。 coarse-to-fine の考え方は共通している。
optical flow とCNN
OpenCVにもCNNを用いたoptical flow の計算例が加わった。
Tak-Wai Hui, Xiaoou Tang, Chen Change Loy
https://github.com/twhui/LiteFlowNet2
以下のOpenCVのチュートリアルも有用だ
https://docs.opencv.org/3.4/d4/dee/tutorial_optical_flow.html
Youtube [300 Hz real-time optical flow. City ]https://www.youtube.com/watch?v=_Rpi7WS-HTw
OpenCVのcudaoptflowモジュールからNVIDIA Optical Flow SDKを使う
NVIDIA でのOptical flowの例
https://docs.nvidia.com/deeplearning/dali/user-guide/docs/examples/sequence_processing/optical_flow_example.html
Youtube
追記 2023.5.21
Optical flow ベースの障害物回避
Optical flow だけを用いて衝突時間を算出して自動ブレーキをかける記事が書いてあったので紹介する。
Raspberry Piで自動運転やってみる 2.自動ブレーキ
このコードは衝突時間(time to collision) を計算することで、ブレーキをかけるものになっている。
Raspberry Pi で動作するコードになっているので、計算量が少ないロジックになっている。
高精度のOptical flowの計算をしないものになっている。
Optical-Flow-based-Obstacle-Avoidance
SEE ALSO