Stereo Matching をハードウェアで加速する

この記事の本文は2017年時点のものです。

---------------------------------------------------
Stereo Matching　は計算量が多くなりがちです。
リアルタイムでのStereo Matching を可能にするには、GPUやFPGAを使うことも考えて見ましょう。

（それ以前に、Stereo計測済みの結果を返す機器を使うことで、自力でStereo matching をしないという選択肢もあります。アクティブな方式を用いていないステレオ計測の場合だと、精度の低い計算結果を返す場合がある。）



FPGAでの利用は、ある時点での設計が数年後にはすぐに時代遅れになりがちです。まずはGPUでの利用を考えてみましょう。
組み込みのステレオマッチングについてZEDとNividiaのチップを用いた組み込みを利用するというアプローチがあります。
[ZED with Jetson TK1] (http://qiita.com/nonbiri15/items/d341e68f9aa9345211a2)

ここに書いたものよりもよい実装が既に公開されていないかNVidiaのサイトやOpenCVのサイトを必ずチェックしてみてください。

「１０倍程度の高速化を目標としてHW化を進めるのはリスクがある」SlideShare[動き検出のSW実装とHW実装について]
(http://www.slideshare.net/minorunatsutani/tech20160827)
p.12 にその状況が述べられています。

汎用的なアプローチでできる高速化をまず考えるべきでしょう。
HWへの制限が少なく、無駄になる危険が少ないのは
マルチコアによる実装 ＞= GPGPUによる実装 > FPGAによる実装 > ASICによる実装
という順番になるのでしょうか。


他に解決すべき内容を持っている人にとっては、FPGAによる実装は自分で書いていいものとは思えません。
OpenCVの特定のライブラリに対応するFPGA実装の提供を利用して高速化する分には十分ありだと思っていますが、
FPGAと連動するCPUのバスやIOなどの部分が、既存のGPGPUマシンに比べて扱いにくさを持っている可能性があるので
だれにでも勧められる代物とは考えていません。



### Fixstars 社による実装 [libSGM](https://github.com/fixstars/libSGM)
A CUDA implementation performing Semi-Global Matching.


### OpenCV 2.4での実装
[gpu::StereoBM_GPU](http://docs.opencv.org/2.4/modules/gpu/doc/camera_calibration_and_3d_reconstruction.html)

(opencv_2.4.11)\sources\modules\gpu\src の下のソースコードを参照をしよう。
(opencv_2.4.11)\sources\modules\ocl\src


[gpu::StereoBeliefPropagation](http://docs.opencv.org/2.4/modules/gpu/doc/camera_calibration_and_3d_reconstruction.html#gpu-stereobeliefpropagation)
このクラスは，Pedro F. Felzenszwalb のアルゴリズム felzenszwalb_bp を実装しています


###OpenCV 3.0 [Stereo Correspondence](http://docs.opencv.org/3.0-beta/modules/cudastereo/doc/stereo.html)
(opencv_3.1)\sources\modules\cudastereo\src の下のソースコードを参照しよう。

GPUを使うステレオマッチング関係のモジュールが、2.4系統と3.x系統で大きく変更になっていることはわかった。



[cuda::StereoBM]


###[CUDA Stereo](https://www.cs.unc.edu/~gallup/cuda-stereo/)
 NVIDIA Research Summit 2009. で公開されたもののようです。




###[implementation of stereo matching](https://github.com/abhisg/CUDA-project)

###[Real-time Spatiotemporal Stereo Matching Using the Dual-Cross-Bilateral Grid](https://www.cl.cam.ac.uk/research/rainbow/projects/dcbgrid/)


[Efficient dense stereo matching using CUDA](http://www.nvidia.com/content/events/sc11/pdf/ke-zhu.pdf)

NVidia [VisionWorks](https://developer.nvidia.com/embedded/visionworks) Semi-Global Matching, Stereo Block Matching


### [FPGA向けStereo Vision IP Suite](http://www.fsi-embedded.jp/_emb/sv/index.html)
　富士重工でアイサイトを開発した實吉准 氏(現　東工大准教授)が監修したFPGAでの実装です。
　[ステレオビジョン評価キット](http://www.fsi-embedded.jp/_emb/sv/evaluationkit.html)


Xilinx [Gimme2 stereovision system](http://japan.xilinx.com/products/boards-and-kits/1-3bwl4k.html)


[Open-source FPGA Stereo Vision Core released](https://danstrother.com/2011/06/10/fpga-stereo-vision-core-released/)

[SGM Stereovision FPGA IP](https://www.scs.ch/blog/en/2013/01/sgm-stereovision-fpga-ip-2/)

---------------------------

[OpenCV 3.0.0での独自カーネルOpenCL](http://qiita.com/tackson5/items/8dac6b083071d31baf00)
[cv::cuda::GpuMat Class Reference](http://docs.opencv.org/3.1.0/d0/d60/classcv_1_1cuda_1_1GpuMat.html#gsc.tab=0)

[Where are the GPU functions on OpenCV 3.0?](http://stackoverflow.com/questions/26909194/where-are-the-gpu-functions-on-opencv-3-0)



--------------------------------
Stereo Matching　は　計算する画像の解像度や範囲、 視差　Disparityの探索する範囲によって計算量が著しく変わります。
そのため、どのような画角で、どのくらいの奥行きで視差を求めるのかという、各人のかかえている問題に対してパラメータを最適化することを必ず評価してください。そのような評価で計算量が桁の範囲で変わります。

------------------------------------------------------------------

Youtube上にstereo vision 関係の動画が多数存在している。
以下はその一例。

Stereo Vision System - implemented on FPGA
https://www.youtube.com/watch?v=bPcr0mHbgpQ

Vivado
Hardware Accelerated Stereo Vision
https://www.youtube.com/watch?v=tKJJ_IrZ834

SP1: Real-Time Stereo Matching Through FPGA-Technology
https://www.youtube.com/watch?v=6pxP56vOFPI

Real-Time Direct Dense Matching on Fisheye Images Using Plane-Sweeping Stereo
https://www.youtube.com/watch?v=eWOhLhqVXSI

Automatic Camera Re-Calibration for Robust Stereo Vision
https://www.youtube.com/watch?v=2QGnOwfQKYo

この動画は、ステレオキャリブレーションを自動でやり直すことで、
ステレオカメラの状況が変わってしまっても、適切な視差画像が得られるようにする手法について議論されている。

-----------------------------------------------------------------------

関連記事

[OpenCV-Python Tutorialsの「カメラ校正」への補足](http://qiita.com/nonbiri15/items/e36c12d444d7cc4a00b7)

[Jetson TK1　TX1について調査中](http://qiita.com/nonbiri15/items/f18d0aab15a0c8590f96)

----
## 追記
- ZED2 では深層学習を利用した深度の算出ができるようになっています。
- NVIDIA にはステレオカメラのアルゴリズムをNVIDIAのGPUに対して最適化したライブラリが提供されています。
それらを利用することも視野においてください。

## SGBM ベースのロジックをjetsonで動作させるためには
[Jetson Stereo Depth](https://github.com/NVIDIA-AI-IOT/jetson-stereo-depth)
- Camera パラメータを算出する方法が含まれています。
- SGBM ベースのアルゴリズムなので、最近の深層学習は反映していません。
- 対応点が算出できない領域は欠損になります。