.. _py_depthmap: ステレオ画像から距離計測 ****************************** 目的 ======= このチュートリアルでは * ステレオ画像から距離マップを計算する方法を学びます. 基礎 =========== 前のチュートリアルでエピポーラ幾何の概念を学びました.同一シーンを撮影した2枚の画像があれば,そのシーンの距離情報を取得できることは直観的に分かります.以下に,この直観を証明する画像と数式を示します.(画像転載 : *原点での記述無し* ) .. image:: images/stereo_depth.jpg :alt: Calculating depth :align: center 上記のダイアグラムは相似な三角形を含んでいます.この相似関係を式で表現すると以下のようになります: .. math:: disparity = x - x' = \frac{Bf}{Z} ここで :math:`x` と :math:`x'` はそれぞれ,3次元点に対応する画像上の点と光学中心間の距離を表します. :math:`B` は2台のカメラ間の距離(既知), :math:`f` はカメラの焦点距離(既知)です.簡潔に言うと,上式はシーン中の点の距離は光学中心と画像上の点の間の距離に逆比例するということです.この情報を使い,画像中の全点の距離を求めます. 2枚の画像間の対応点を見つけます.エピポーラ拘束がどのようなものか,またこの処理を速くかつ正確に出来る事も理解していますよね.対応点を見つけてしまえば,視差(disparity)が計算できます.OpenCVを使ってどのように視差を計算するか見ていきましょう. 実装(コード) ================ 以下が視差マップ(disparity map)を計算するためのコードです. :: import numpy as np import cv2 from matplotlib import pyplot as plt imgL = cv2.imread('tsukuba_l.png',0) imgR = cv2.imread('tsukuba_r.png',0) stereo = cv2.createStereoBM(numDisparities=16, blockSize=15) disparity = stereo.compute(imgL,imgR) plt.imshow(disparity,'gray') plt.show() 以下の画像に原画像の片方と対応する視差マップを示します.見て分かるように大きなノイズを含んでいます. `` numDisparities`` と ``blockSize`` の値を調整すると,より良い結果が得られるはずです. .. image:: images/disparity_map.jpg :alt: Disparity Map :align: center .. note:: より詳しい情報を載せる予定(翻訳時点(2015/11/16)では特に詳細情報は記載されていない.) 補足資料 ============================= 課題 ============ 1. OpenCVのサンプルの中に視差マップと3次元復元を行うサンプルが含まれています. ``stereo_match.py`` を試しに動かしてみてください.