目標
このセッションでは、
基礎
前回のセッションでは、エピポーラ制約やその他の関連する用語といった基本的な概念を見た。また、同じシーンの2枚の画像があれば、そこから直感的な方法で深度情報を得られることも見た。以下はその直感を証明する画像といくつかの簡単な数式である。(画像提供 :
image
上の図には相似三角形が含まれている。それらの相似の式を書くと次の結果が得られる:
\[disparity = x - x' = \frac{Bf}{Z}\]
\(x\) と \(x'\) は、3Dシーン点に対応する画像平面上の点とそれぞれのカメラ中心との間の距離である。\(B\) は2台のカメラ間の距離 (既知) であり、\(f\) はカメラの焦点距離 (これも既知) である。要するに、上の式は、シーン内のある点の深度が、対応する画像点とそれぞれのカメラ中心との距離の差に反比例することを示している。したがって、この情報があれば画像内のすべてのピクセルの深度を導出できる。
そこで、2枚の画像間で対応するマッチを見つける。エピライン制約によってこの操作がより高速かつ正確になることはすでに見た。マッチが見つかると、視差を求める。OpenCV でこれをどのように行えるか見てみよう。
コード
以下のコードスニペットは、視差マップを作成する簡単な手順を示している。
import numpy as np
import cv2 as cv
from matplotlib import pyplot as plt
imgL =
cv.imread(
'tsukuba_l.png', cv.IMREAD_GRAYSCALE)
imgR =
cv.imread(
'tsukuba_r.png', cv.IMREAD_GRAYSCALE)
disparity = stereo.compute(imgL,imgR)
plt.imshow(disparity,'gray')
plt.show()
static Ptr< StereoBM > create(int numDisparities=0, int blockSize=21)
Creates StereoBM object.
Mat imread(const String &filename, int flags=IMREAD_COLOR_BGR)
Loads an image from a file.
以下の画像には、元の画像 (左) とその視差マップ (右) が含まれている。見て分かるように、結果は高度なノイズで汚染されている。numDisparities と blockSize の値を調整することで、より良い結果を得られる。
image
StereoBM に慣れてくると、いくつかの引数があり、より良く滑らかな結果を得るためにこれらの引数を微調整する必要が出てくるかもしれない。引数:
- texture_threshold: 信頼性の高いマッチングに十分なテクスチャを持たない領域を除外する
- Speckle range と size: ブロックベースのマッチャーは、マッチングウィンドウが片側で前景を、もう片側で背景を捉えるようなオブジェクトの境界付近で、しばしば「スペックル」を生成する。このシーンでは、マッチャーがテーブルに投影されたテクスチャの中に小さな誤ったマッチも見つけているように見える。これらのアーティファクトを取り除くために、speckle_size と speckle_range 引数で制御されるスペックルフィルタによって視差画像を後処理する。speckle_size は、視差の塊が「スペックル」として除外される基準となるピクセル数である。speckle_range は、同じ塊の一部とみなされるために視差値がどれだけ近くなければならないかを制御する。
- 視差数: ウィンドウをスライドさせるピクセル数。大きいほど可視深度の範囲が広がるが、より多くの計算が必要となる。
- min_disparity: 探索を開始する位置を、左ピクセルのx座標からどれだけずらすかのオフセット。
- uniqueness_ratio: もう一つの後処理ステップ。最良のマッチング視差が探索範囲内の他のすべての視差より十分に優れていない場合、そのピクセルは除外される。texture_threshold とスペックルフィルタリングを行ってもなお誤ったマッチが通過してしまう場合は、これを調整してみるとよい。
- prefilter_size と prefilter_cap: ブロックマッチングの準備として、画像の明るさを正規化しテクスチャを強調する前処理フェーズ。通常はこれらを調整する必要はない。
これらの引数は、アルゴリズムの初期化後に setTextureThreshold、setSpeckleRange、setUniquenessRatio などの専用のセッターおよびゲッターで設定する。詳細は cv::StereoBM のドキュメントを参照。
追加のリソース
演習
- OpenCV のサンプルには、視差マップとその3D再構成を生成する例が含まれている。OpenCV-Python のサンプルにある stereo_match.py を確認すること。