31 ステレオビジョン
人間には両眼があるため、どの物体がより近いかを一目で判別できる——大脳は両眼の網膜上に写る同一対象の微小な位置差を距離に換算している。マシンビジョンでもこの機構をそのまま利用できる。一定の間隔を置いて配置された2台のカメラで同時に撮影すると、同一の空間点は2枚の画像内で異なる水平位置に結像する。この位置差が視差(disparity)であり、視差は直接深度を符号化している。双眼ステレオビジョン(binocular stereo vision)は、1組の画像から各画素の深度を推定する技術である。チャプター 30 で列挙された複数の3次元イメージング方式の中で、最も人間の視覚に近く、最も「パッシブ」な方式でもある。シーンに対して一切のエネルギーを投射せず環境光のみに依存するため、低消費電力で相互干渉がなく、長距離での動作も可能である。その代償として、回避不可能な前提条件が存在する——被測定表面には固有のテクスチャがなければならない。視差を求める処理は本質的に2枚の画像内で同一のパターンの対応付けを行うものであり、テクスチャがなければ対応付けが不可能だからである。本章では、対極幾何から始め、ブロックマッチング、信頼性検定、サブピクセル化とウィンドウ設定を経て、最終的に深度再構成に至るまでの一連の流れを、一組の合成された補正済みステレオペア(図 31.1)を通して解説する。
31.1 対極幾何と視差
2台のカメラで同一点を観測する場合、幾何学的に何の制約もないわけではない。空間点と2つのカメラの光学中心が共通して1つの平面を定め、この平面が2つの像面と交差して一対の対極線(epipolar line)を形成する——これが対極幾何(epipolar geometry)の核心的な結論である。左画像内のある画素に対応する右画像内の点は、画像全体を探索するのではなく、必ず対応する対極線上に存在する。これにより2次元探索が1次元探索に削減される。工学的にはさらに一歩進め、補正(rectification)によって2枚の画像に射影変換を施し、すべての対極線を画像の行と厳密に平行にし、かつ行番号を一対一で対応させる。補正後、左画像の第\(y\)行にある画素の対応点は、右画像の同じ第\(y\)行上に必ず存在し、\(x\)方向にのみオフセットを持つ。これがまさに本章のステレオペアの状態であり、対応付けの探索は同じ行に沿った1次元のスライド処理に縮退される。
本例のステレオペアは合成段階で既に補正済みの状態である(2台のカメラは\(X\)軸方向に並進しているだけで内部パラメータは同一)ため、行内探索を直接実行できる。実際のシステムでは、まず チャプター 5 で述べる双眼キャリブレーションを実施し、2台のカメラの相対的な位置姿勢と歪みを求めた上で補正用のマッピングを計算する必要がある——補正の品質はその後のマッチングの成否を直接左右し、半画素分の垂直方向の位置ずれが残留しただけでも、ブロックマッチングの精度は系統的に低下する。
2台のカメラの光軸が平行で、間隔が基線(baseline)\(B\)、焦点距離が\(f\)(画素単位)であるとする。深度\(Z\)にある点の左右画像での横座標の差が視差\(d\)である。相似三角形より\(d/f = B/Z\)が得られ、すなわち
\[ Z = \frac{fB}{d}. \tag{31.1}\]
視差は深度に反比例する——物体が近いほど視差は大きく、遠いほど小さくなる。本例では\(f=600\) px、\(B=60\) mmであるため\(fB=36000\) mm·pxとなり、真値の視差は36.0~51.4 px(\(Z\)が1000 mmから700 mmに対応)の範囲に収まる。図 31.1 において近くの物体が顕著に左にシフトし、背景がほとんど移動していないのは、まさにこの反比例関係の直感的な現れである。
この反比例関係には、さらに影響の大きな帰結がある。式 31.1 を微分すると、1画素分の視差誤差に対応する深度誤差、すなわち深度分解能が
\[ \Delta Z = \frac{Z^2}{fB}. \tag{31.2}\]
と求まる。深度分解能は\(Z^2\)に比例して増大する——これが「ステレオビジョンは遠方で精度が低下する」ことの数学的な本質である。本例では\(Z=1000\) mmの位置で1 pxの視差が27.8 mmの深度に対応するのに対し、\(Z=800\) mmでは17.8 mm、\(Z=700\) mmでは13.6 mmにまで減少する。同じ視差測定誤差でも、遠方では数倍の深度誤差に増幅される。この式は精度向上の2つの方向性も示している——\(fB\)を大きくする(より長焦点のレンズを用いるか基線を長くする)か、視差をサブピクセル精度で測定することであり、後者は セクション 31.4 の主題である。
図 31.2 は本シーンの真値視差場であり(既知の深度から 式 31.1 を用いて各画素ごとに逆算されたもの)、以降のすべてのマッチング結果はこれを基準に評価される。直方体と球冠(近くの物体)が全体的に明るく(視差が大きい)、背景が暗く(視差が小さい)、スロープが近くから遠くへ連続的に階調変化している点に注目されたい——これはまさに 式 31.1 の反比例関係の画像化された表現であり、ブロックマッチングが接近すべき目標でもある。
基線\(B\)は典型的なトレードオフの対象となる量である。式 31.2 より、基線が長いほど深度分解能は高くなるが、基線が長いほど2台のカメラの視点差が大きくなり、前景に遮蔽されて片方の眼でしか見えないオクルージョン(occlusion)領域が拡大する。また、同一表面が2枚の画像内で受ける透視歪みが大きくなり、マッチングが困難になる。産業用ステレオカメラの基線選定では「精度」と「オクルージョン・マッチングの難易度」の間で妥協点を探る必要があり、通常は作業距離の数分の1程度に設定される。
31.2 ブロックマッチング
補正後、視差を求める処理は次のように単純化される:左画像の各画素について、右画像の同じ行に沿ってスライドさせ、最も類似する位置を探索する。「類似度」を評価するにはコスト関数が必要である。最も素朴なものは絶対差和(sum of absolute differences、SAD)であり——画素を中心とする小さなウィンドウを設定し、各点ごとに左右の輝度値の絶対差を計算して総和をとる。コストが小さいほど類似度が高い。これは チャプター 16 のテンプレートマッチングと同源の手法であるが、テンプレートが「左画像の局所ウィンドウ」に置き換えられ、探索範囲が対極幾何によって1行内に制限される点が異なる。照明変動に対してよりロバストな手法には正規化相互相関(NCC)があるが、計算コストはより高くなる。本例ではSADを使用し、探索範囲を視差区間\([30, 56]\) pxに制限する(シーンの既知の深度範囲に余裕を持たせて設定したものである)。
すべての画素とすべての候補視差についてウィンドウコストを計算すると、3次元のコストボリューム(cost volume)\(C(x,y,d)\)が得られる。\(d\)次元に沿ってコストが最小となる位置を選択すると、その画素の整数視差が得られる——このステップは「総取り(winner-take-all)」と呼ばれる。図 31.3 は11×11ウィンドウを用いた場合の生の整数視差結果である。直方体、スロープ、球冠の形状はいずれも正しく現れており、近くの物体は明るく(視差が大きい)、背景は暗く(視差が小さい)なっている。しかしスロープと球冠をよく見ると、明らかな量子化帯(quantization banding)が観察される——本来滑らかに変化するはずの深度が階段状に切り分けられており、これはまさに整数視差の離散化による痕跡である。真の視差は連続的な小数値であるのに対し、総取り法は整数値しか出力できないからである。
定量的に見ると、この11×11 SADは画像全体で91.8%の有効率、平均絶対誤差(MAE)0.362 px、(誤差 > 1 pxの)不良画素率3.93%を達成している。オクルージョンのない領域のみで集計すると、MAEは0.299 pxに低下する——これは誤差の主要な原因の1つがオクルージョンであることを裏付けている。前景に遮蔽された背景の画素は右画像に対応点が存在しないため、総取り法は誤った最小コストの対応付けを行うしかない。本例では真のオクルージョンは0.92%を占め、近くの物体の左縁に沿った背景の帯状領域に集中している。こうした信頼性の低い視差をどのように識別するかは、次節の課題である。
31.3 不具合と信頼性
勝者総取りは、その領域に信頼できる対応が全く存在しない場合でも、常に「最良」の視差を出力する。単純だが効果的な識別手法は左右一致性検査(left-right consistency check)である:左画像を参照として視差図 \(d_L\) を求め、次に右画像を参照として \(d_R\) を求めた上で照合を行う。左画像の画素 \(x\) の視差が \(d_L(x)\) である場合、右画像での対応点は \(x-d_L\) となるため、\(d_R(x-d_L)\) は \(d_L(x)\) とほぼ等しいはずである。両者が不一致(本例では閾値を 1 px とする)である画素は、信頼できないと判定されて除外される。遮蔽領域はこの検査によって自然に検出される。遮蔽された画素の「対応点」は実際には前景に属するため、左右の2回のマッチング結果はそれぞれ異なり、必然的に一致しない。
図 31.4 は検査後の視差図である。遮蔽帯(近接物体の左縁)と無テクスチャ領域の大部分は黒(無効)として除外され、保持された視差はより鮮明になっている。代償として、画像全体の有効率は 91.8% から 88.6% に低下したが、保持された画素の品質は大幅に向上した。MAE が 0.362 px から 0.134 px に改善し、不良画素率は 3.93% から 1.26% に圧縮されている。信頼性検査は精度を生み出すものではなく、「不明」な箇所を誠実に標示するだけであるが、工業的には、見かけ上は密だが実質的には信頼性の低い視差図よりもはるかに有用である。
最も代表的な例は右下隅にある 90×90 px の無テクスチャ領域であり、これは意図的に設計された不具合領域である。図 31.3 ではこの領域は無秩序なランダム視差として表示され、元の統計によると、この領域の元の有効率は 100% と高いものの、そのうち 82.2% が不良画素である。理由は単純である。均一な灰色の領域上の各位置はすべて同じに見えるため、SAD コスト曲線は探索範囲全体でほぼ平坦となり、勝者総取りによって選ばれた「最小値」は純粋にセンサノイズによって決定される、全くのランダムな解となる。さらに興味深いのは、左右検査後の結果である。無テクスチャ領域の画素のうち、生存したのはわずか 43.3% であり、生存した画素の中でも依然として 82.5% が不良画素である。つまり、2回のランダムマッチングが「偶然」一致したとしても、その一致した結果は依然として誤りである——テクスチャなしにステレオは成立しない。
無テクスチャ領域の教訓は、チャプター 32 で能動的にテクスチャを投影する動機を直接的に説明している。受動ステレオが無テクスチャ表面で無力であるならば、シーンに人工的なランダムスペックルや符号化縞を能動的に投影し、マッチングに利用可能なテクスチャを人為的に作り出せばよい。これは「能動ステレオ」センサの核心的な考え方でもある。ステレオの幾何学的枠組みはそのままに、プロジェクタによってテクスチャという前提条件を補うのである。
31.4 サブピクセルと窓サイズ
整数視差による量子化による縞状のムラ(図 31.3)は、勝者総取りが整数値しか選択できないことに起因する。この補救方法は、チャプター 14 および チャプター 20 におけるサブピクセルエッジ位置推定と全く同様である。コストが最小となる整数視差 \(d_0\) において、それと左右の隣接視差 \(d_0\pm1\) の3つのコスト値 \(C_{-1},C_0,C_{+1}\) を用いて放物線補間を行う。放物線の頂点の \(d_0\) からのオフセットは次式で与えられる。
\[ \delta = \frac{C_{-1}-C_{+1}}{2\,(C_{-1}-2C_0+C_{+1})}, \tag{31.3}\]
サブピクセル視差は \(d_0+\delta\) となる。3つの標本点から放物線が1つ決まり、頂点の公式は閉形式であり、計算コストは無視できるほど小さい——再び、ほぼ無償で精度が得られる。この効果は(真値が連続的な分数視差となる)斜面領域で最も直感的にわかる。この領域での整数視差の MAE は 0.252 px であったが、サブピクセル補間後には 0.070 px に急減している。画像全体の非遮蔽領域の誤差ヒストグラムもそれに伴って変化し、\(|\text{err}|\le 0.125\) px の画素の割合が、整数視差の場合の 80.4% からサブピクセルの場合の 91.6% に上昇した。画像全体の MAE は 0.362 から 0.342 px に改善し、非遮蔽領域では 0.299 から 0.278 px に改善して——量子化による縞状のムラは平滑化された。
もう1つ、シーンに応じて調整しなければならないパラメータは窓サイズである。窓が大きいと、取り込まれるテクスチャが多くなりノイズの平均化がより十分に行われるが、「窓全体が同一の深度に属する」ことを前提としているため、深度の不連続箇所(物体のエッジ)では前景と背景が混ざり合ってしまう。下表は、非遮蔽領域(サブピクセル視差)における 5×5、11×11、21×21 の3種類の窓の比較である。
| 窓サイズ | MAE (px) | 不良画素率 | エッジ周辺の不良画素率 | 無テクスチャ領域の不良画素率 |
|---|---|---|---|---|
| 5×5 | 0.336 | 3.69% | 3.95% | 90.5% |
| 11×11 | 0.278 | 3.38% | 4.26% | 86.7% |
| 21×21 | 0.251 | 3.24% | 5.17% | 65.5% |
この表は領域ごとに読み取る必要がある。全体的な MAE は窓が大きくなるほど低下する(0.336 → 0.251)が、これは大きな窓がノイズをより強く抑圧するためである。一方、エッジ周辺領域(箱の境界の両側 12 px の領域)の不良画素率は逆に悪化している(3.95% → 5.17%)。これはエッジブリーディング(edge bleeding)と呼ばれる現象である。大きな窓が前景のエッジの外側にある背景の画素も計算に含めてしまうため、エッジが前景によって「太く」なってしまうのである。図 31.5 は 5×5 と 21×21 の2つの極端な例を比較している。win5 はノイズが多いがエッジが鮮明であるのに対し、win21 は滑らかで鮮明だが、箱と斜面の輪郭は明らかに膨張している。興味深いことに、無テクスチャ領域の不良画素率は win5 の 90.5% から 65.5% に低下している。これは大きな窓が外部の隣接するテクスチャを流用し、本来であればマッチング不能な灰色の領域に、マッチング可能なわずかな内容を作り出しているためであるが、これは流用したものであり信頼できない。
エッジブリーディングは具体的な画素単位で定量化できる。\(y=195\) 行で箱のエッジにおける視差の遷移位置を計測すると、箱の左縁の真値は \(x=155\) であるのに対し、3種類の窓では 148/151/152 と計測された。窓が大きくなるほど左外側(前景の外側)に偏っている。右縁の真値は \(x=290\) であるのに対し、計測値は 291/292/293 となり、同様に外側に膨張している。窓サイズが1段階大きくなるごとに、前景のエッジはおよそ窓幅の半分だけ外側に膨張する。このことから、工業的に前景のエッジ付近の視差を特に信頼しない、あるいは適応的窓や大域的な平滑化拘束を導入したアルゴリズムに切り替えることが多い理由が説明できる。
31.5 深度再構成
信頼できる視差図が得られれば、式 31.1 を各画素に適用し \(Z=fB/d\) と計算することで深度図(図 31.6)が得られる。この図の本質は2.5D 距離画像であり、カメラから見た各画素方向の最近接表面までの距離を記録したものであって、完全な3次元モデル(裏面や遮蔽された箇所にはデータがない)ではない。これは チャプター 30 における 2.5D の定義と一致している。さらに計量的な3次元点を得るためには、カメラ内部パラメータを用いて各 \((x,y,Z)\) を \((X,Y,Z)\) に逆投影する必要があり、これは チャプター 37 の点群の領域となる。
精度の面では、計測結果は信頼に足るものである。背景の中央値深度は 1000.0 mm(真値 1000 mm)、箱の面の深度は 800.0 mm(真値 800 mm)であり、再構成された箱の高さは 200.1 mm(真値 200 mm)——数十分の1ミリメートルの誤差である。ここでまさに セクション 31.4 のサブピクセルの効果が活かされている。式 31.2 によると、\(Z=1000\) mm における深度分解能は 27.8 mm/px であり、整数視差のみでは深度は約 28 mm の段差に固定されてしまい、200 mm の箱の高さを小数点第1位まで計測することは不可能である。しかし、0.1 px のサブピクセル精度によって実効的な深度分解能は 2.78 mm(10倍)に向上し、箱の高さを 200.1 mm まで精密に計測できるようになる。サブピクセルは付加的な機能ではなく、ステレオビジョンが計量計測を行えるかどうかの分水嶺である。
31.6 SciVision 実装
率直に述べる必要がある:SciVision SDK は双眼ステレオマッチングライブラリを提供していない——レクティフィケーション、コストボリューム、視差求解、左右一致検査のための既製 API は存在しない。そのため本章の付属プロジェクト code/stereo_vision/ は完全に独立した C++ 実装となっており、SDK は画像の読み書き(SciImage::SaveImage による PNG 出力)にのみ使用されている。以下に 3 つのコアコードを示す。
コストボリュームに対するウィナーテイクオール(SAD は積分画像を用いたボックスフィルタで高速化される。ここでは積分画像の詳細を省略し、最適視差の求解とサブピクセル処理のみを示す):
int best = BIG, bi = -1; // 視差次元に沿って最小コストを探索
for (int di = 0; di < ND; ++di) {
int c = cost[((size_t)di * H + y) * W + x];
if (c < best) { best = c; bi = di; }
}
m.id[i] = D0 + bi; m.d[i] = (float)(D0 + bi); m.valid[i] = 1;
if (bi > 0 && bi < ND - 1) { // 放物線によるサブピクセル補間
double cm = cost[((size_t)(bi-1)*H + y)*W + x];
double cp = cost[((size_t)(bi+1)*H + y)*W + x];
double denom = cm - 2.0 * best + cp;
if (denom > 1e-9) {
double offd = 0.5 * (cm - cp) / denom; // すなわち式 @eq-sv-subpix
if (offd > 0.5) offd = 0.5; else if (offd < -0.5) offd = -0.5;
m.d[i] = (float)(D0 + bi + offd);
}
}左右一致検査(左と右の 2 回のマッチング結果を相互に検証する):
auto bmR = blockMatch(right, left, false, 11); // 右画像を基準に再度マッチング
for (int y = 0; y < H; ++y)
for (int x = 0; x < W; ++x) {
int i = y * W + x;
if (!bm11.valid[i]) continue;
int xr = x - (int)std::lround(bm11.d[i]); // 左画像の画素に対応する右画像上の点
if (xr < 0 || xr >= W || !bmR.valid[y*W+xr]) continue;
if (std::fabs((double)bm11.d[i] - bmR.d[y*W+xr]) <= 1.0) // 一致した場合のみ残す
lrValid[i] = 1;
}blockMatch(left, right, true, 11) と blockMatch(right, left, false, 11) はそれぞれ \(d_L\)、\(d_R\) を求める。win=11 はウィンドウの一辺の長さであり、D0=30、D1=56 が探索範囲を定めている。この「アルゴリズムが SDK の外部に存在する」という構成は偶然ではない。産業用ステレオビジョンは計算量と遅延に極めて敏感であり、実際の製品ではステレオマッチングの多くが専用センサまたは FPGA にオフロードされる——視差求解は規則的で大規模並列化が可能な画素単位の演算であり、ハードウェアパイプラインに適している。これは汎用 CV SDK の「ライブラリを呼び出す」パラダイムとは異なるレイヤーに属する。SciVision のようなライブラリの位置づけは、視差/深度マップが生成された後である。同ライブラリのフィルタ、モルフォロジー、Blob、計測ツールを用いて深度マップを処理し、寸法計測や欠陥検査といった下流タスクを実行する。
産業事例:物流仕分けにおけるテクスチャ依存性
物流仕分けラインでは、課金や梱包計画のために、ステレオカメラを用いて荷物の体積(縦・横・高さ)をオンラインで計測することが一般的である。実際の現場では、成否はほぼ完全に表面のテクスチャに依存する。クラフト段ボール箱の表面には印刷、テープ、繊維のテクスチャが存在するため、視差は密で信頼でき、体積は高速かつ正確に計測される。しかし、黒いビニール袋、反射する封緘テープ、鏡面包装に遭遇すると、表面にテクスチャがないか、鏡面反射によってランバートの仮定が崩れるため、視差が広範囲で無効となり、計測される体積は不完全になるか、ばらつくようになる。対策は 2 つある。1 つはアクティブステレオに切り替え、スペックル投影を追加して表面に人為的にテクスチャを作成する方法である(チャプター 32 と関連する)。もう 1 つはマルチモーダルな穴埋めであり、飛行時間(ToF)や構造化光を用いてステレオが無効な箇所を補間する。教訓は明確である:パッシブステレオの前提条件は「被測定面が固有のテクスチャを持つこと」であるため、導入前には必ず対象表面のテクスチャ特性を検証し、パッシブステレオ、アクティブステレオ、あるいは別の技術経路を選択する必要がある。
31.7 まとめ
- 視差は深度である:エピポーラ幾何は対応点探索を 1 本のエピポーラ線に制約し、レクティフィケーション後は行内の 1 次元探索に縮退する。深度は \(Z=fB/d\) で与えられ、視差と深度は反比例の関係にある。
- 深度分解能は \(Z^2\) に比例して悪化する(\(\Delta Z=Z^2/(fB)\)):本例では 1000 mm 地点で 27.8 mm/px であり、遠方で精度が低下するのはステレオビジョンの本質的な限界である。これは \(fB\) を大きくするか、サブピクセル処理によって緩和される。
- ブロックマッチング + ウィナーテイクオールは整数視差を与える(11×11 SAD:MAE 0.362 px)が、整数量子化によって階段状の縞が生じる。放物線によるサブピクセル補間はほぼコストなしで縞を滑らかにし、斜面部の MAE を 0.252 px から 0.070 px に低下させ、有効深度分解能を 27.8 mm から 2.78 mm に向上させる——サブピクセルはステレオビジョンが計測用途に耐えるための分水嶺である。
- 左右一致検査はオクルージョンとテクスチャのない領域を誠実に除外する(有効率 91.8% → 88.6% だが、残った画素の MAE は 0.134 px に改善する)。テクスチャなしではステレオマッチングは成立しない——テクスチャのないブロックは生では 100% 有効とされるが 82% が不良点であり、検査後も 82.5% が不良点のままである。これが構造化光などの能動的なテクスチャ投影方式の動機となっている。
- ウィンドウサイズは精度とエッジの忠実度のトレードオフである:大きなウィンドウは全体的に精度が高い(MAE 0.251)が、前景のエッジが滲んで膨張する(エッジの不良点 3.95% → 5.17%)。ボックスのエッジはウィンドウの拡大に伴って約半ウィンドウ幅だけ外側に広がるため、現場ではシーンごとに妥協点を探すか、適応的または大域的な手法に切り替える必要がある。
エピポーラ幾何と多視点幾何の古典的な解説については、Hartley と Zisserman の専門書 (Hartley と Zisserman 2004) を参照されたい。稠密ステレオマッチングのコストとアルゴリズムの体系的な分類と評価については、Scharstein と Szeliski の古典的な総説 (Scharstein と Szeliski 2002) に記載されている。また、精度と効率の両立を実現し産業界の主力となっているセミグローバルマッチング(SGM)は、Hirschmüller によって提唱された (Hirschmüller 2008)。産業用ビジョンにおけるステレオマッチングのエンジニアリング実装と不確かさ解析については、Steger らの著作 (Steger, Ulrich, と Wiedemann 2018) も参照されたい。







