ステレオカメラを使用して特定のオブジェクトまでの距離を計算する方法はありますか?視差や角度を使って距離を求める方程式などはありますか?
注:ここで説明されていることはすべて、LearningOpenCVの本のカメラキャリブレーションとステレオビジョンの章にあります。以下の手順をよりよく理解するには、これらの章を読む必要があります。
すべてのカメラの内因性と外因性を自分で測定する必要がない1つのアプローチは、openCVのキャリブレーション機能を使用することです。カメラの内因性(レンズの歪み/スキューなど)はcv :: calibrateCameraで計算でき、外因性(左右のカメラの関係)はcv :: stereoCalibrateで計算できます。これらの関数は、ピクセル座標でいくつかの点を取り、それらを実世界のオブジェクト座標にマッピングしようとします。 CVには、そのようなポイントを取得し、白黒のチェスボードを印刷し、cv :: findChessboardCorners/cv :: cornerSubPix関数を使用してそれらを抽出するための優れた方法があります。チェス盤の約10〜15枚の画像ペアで十分です。
キャリブレーション関数によって計算されたマトリックスはディスクに保存できるため、アプリケーションを起動するたびにこのプロセスを繰り返す必要はありません。ここでは、後でcv :: remapを使用して画像に適用できる修正マップ(cv :: stereoRectify/cv :: initUnConstraintRectifyMap)を作成できるいくつかのきちんとしたマトリックスを取得します。また、視差から深さへの行列であるQと呼ばれるきちんとした行列も得られます。
画像を修正する理由は、画像のペアのプロセスが完了すると(キャリブレーションが正しいと仮定して)、一方の画像のすべてのピクセル/オブジェクトが、もう一方の同じ行にあるためです。画像。
画像で探している機能の種類に応じて、ここから移動できる方法がいくつかあります。 1つの方法は、ステレオブロックマッチングやセミグローバルブロックマッチングなどのCVステレオ対応機能を使用することです。これにより、Qマトリックス(cv :: reprojectImageTo3D)を使用して3Dポイントに変換できる画像全体の視差マップが得られます。
これの欠点は、画像に多くのテクスチャ情報がない限り、CVは密な視差マップを作成するのがあまり得意ではないことです(特定のピクセルの正しい視差を見つけることができなかった場所にギャップが生じます) 、したがって、別のアプローチは、自分に一致させたいポイントを見つけることです。左の画像でx = 40、y = 110、右の画像でx = 22にフィーチャ/オブジェクトが見つかったとします(画像は修正されているため、同じy値を持つ必要があります)。視差は、d = 40-22 = 18として計算されます。
この場合(40,110,18)のcv :: Point3f(x、y、d)を作成します。同じ方法で他の興味深い点を見つけてから、すべての点をcv :: PerspectiveTransformに送信します(変換行列としてQ行列を使用します。基本的に、この関数はcv :: reprojectImageTo3Dですが、スパース視差マップの場合)。出力は次の点になります。左のカメラを中央にしたXYZ座標系。
私はまだそれに取り組んでいるので、私はまだソースコード全体を投稿しません。しかし、私はあなたに概念的な解決策を与えます。
入力として次のデータが必要になります(両方のカメラの場合)。
カメラを紙の上に置き、2本の線を引き、これらの線の間の角度を測定することで、最後の線を自分で測定できます。
カメラを整列させる必要はありません。両方のカメラでオブジェクトを表示できる必要があるだけです。
次に、各カメラからオブジェクトまでのベクトルを計算します。各カメラからのオブジェクトの(X、Y)ピクセル座標があり、ベクトル(X、Y、Z)を計算する必要があります。オブジェクトがカメラの真ん中に見える単純なケースでは、解決策は単純に(camera.PointOfInterest --camera.Position)になることに注意してください。
両方のベクトルがターゲットを指していると、これらのベクトルによって定義された線は、理想的な世界では1点で交差するはずです。現実の世界では、測定誤差が小さく、カメラの解像度が限られているため、そうはなりません。したがって、以下のリンクを使用して、2つの線の間の距離ベクトルを計算します。
そのリンクでは、P0は最初のカム位置、Q0は2番目のカム位置、uとvはカメラ位置から始まり、ターゲットを指すベクトルです。
あなたは実際の距離には興味がなく、彼らは計算したいと思っています。ベクトルが必要ですWc-オブジェクトはWcの真ん中にあると想定できます。3D空間でオブジェクトの位置を取得すると、好きな距離を取得できます。
ソースコード全体をすぐに投稿します。
私は人間の顔を検出するためのソースコードを持っており、深度だけでなく、左カメラ(または右カメラ、私は思い出せませんでした)を原点として実世界の座標も返します。これは「LearningOpenCV」のソースコードを基に作成されており、いくつかのWebサイトを参照して機能させます。結果は一般的に非常に正確です。