8

カメラからの 2 つの連続した画像があり、カメラの姿勢の変化を推定したい: カメラの動きのある 2 つの写真

オプティカル フローを計算します。

Const MAXFEATURES As Integer = 100
imgA = New Image(Of [Structure].Bgr, Byte)("pic1.bmp")
imgB = New Image(Of [Structure].Bgr, Byte)("pic2.bmp")
grayA = imgA.Convert(Of Gray, Byte)()
grayB = imgB.Convert(Of Gray, Byte)()
imagesize = cvGetSize(grayA)
pyrBufferA = New Emgu.CV.Image(Of Emgu.CV.Structure.Gray, Byte) _
    (imagesize.Width + 8, imagesize.Height / 3)
pyrBufferB = New Emgu.CV.Image(Of Emgu.CV.Structure.Gray, Byte) _
    (imagesize.Width + 8, imagesize.Height / 3)
features = MAXFEATURES
featuresA = grayA.GoodFeaturesToTrack(features, 0.01, 25, 3)
grayA.FindCornerSubPix(featuresA, New System.Drawing.Size(10, 10),
                       New System.Drawing.Size(-1, -1),
                       New Emgu.CV.Structure.MCvTermCriteria(20, 0.03))
features = featuresA(0).Length
Emgu.CV.OpticalFlow.PyrLK(grayA, grayB, pyrBufferA, pyrBufferB, _
                          featuresA(0), New Size(25, 25), 3, _
                          New Emgu.CV.Structure.MCvTermCriteria(20, 0.03D),
                          flags, featuresB(0), status, errors)
pointsA = New Matrix(Of Single)(features, 2)
pointsB = New Matrix(Of Single)(features, 2)
For i As Integer = 0 To features - 1
    pointsA(i, 0) = featuresA(0)(i).X
    pointsA(i, 1) = featuresA(0)(i).Y
    pointsB(i, 0) = featuresB(0)(i).X
    pointsB(i, 1) = featuresB(0)(i).Y
Next
Dim Homography As New Matrix(Of Double)(3, 3)
cvFindHomography(pointsA.Ptr, pointsB.Ptr, Homography, HOMOGRAPHY_METHOD.RANSAC, 1, 0)

右に見えますが、カメラは左と上に移動しました: オプティカル フロー 次に、カメラがどれだけ移動して回転したかを調べたいと思います。カメラの位置とカメラが見ているものを宣言すると、次のようになります。

' Create camera location at origin and lookat (straight ahead, 1 in the Z axis)
Location = New Matrix(Of Double)(2, 3)
location(0, 0) = 0 ' X location
location(0, 1) = 0 ' Y location
location(0, 2) = 0 ' Z location
location(1, 0) = 0 ' X lookat
location(1, 1) = 0 ' Y lookat
location(1, 2) = 1 ' Z lookat

新しい位置とルックアットを計算するにはどうすればよいですか?

私がこれをすべて間違っている場合、またはより良い方法がある場合は、どんな提案も大歓迎です、ありがとう!

4

2 に答える 2

8

純粋なカメラの回転の場合、R = A -1 HA。これを証明するには、画像から平面へのホモグラフィ H1=A および H2=AR を考えます。ここで、A はカメラの固有行列です。すると H12=H2*H1 -1 =A -1 RA となり、そこから R を得ることができます

カメラの移動は推定が困難です。カメラが平行移動する場合は、最初に (ホモグラフィではなく) 基本行列を見つける必要があります。次に、E を回転と平行移動 E=t x R に分解できます。ここで、t xはベクトル積行列を意味します。分解は明らかではありません。これを参照してください。

得られる回転は正確ですが、並進ベクトルはスケールまでしか見つかりません。直観的には、このスケーリングは、2 つの画像だけでは、オブジェクトが近くて小さいか、遠く離れて大きいかを実際に判断できないことを意味します。あいまいさを解消するために、おなじみのサイズのオブジェクト、2 点間の既知の距離などを使用できます。

最後に、人間の視覚系にも同様の問題があることに注意してください。私たちは目の間の距離を「知っています」が、それらがオブジェクトに収束するとき、視差は常にゼロであり、視差だけでは距離が何であるかを知ることはできません. 人間の視覚は、目バージョンの信号からの三角測量に依存して、絶対距離を計算します。

于 2014-03-12T00:15:56.750 に答える
5

さて、あなたが見ているのは、簡単に言えば、ピタゴラスの定理問題a^2 + b^2 = c^2 です。ただし、カメラベースのアプリケーションに関しては、正確に判断するのは簡単ではありません。「a」に必要な詳細の半分を見つけましたが、「b」または「c」を見つけるのははるかに困難です。

短い答え

基本的にカメラ単体ではできません。しかし、それは2台のカメラで行うことができます。

長々 とした答え

画像内の 2 点を選択し、カメラを左に移動するとします。各ポイント B1 のカメラからの距離は 20mm で、ポイント B2 は 40mm であることがわかっています。ここで、画像を処理し、測定値が A1 が (0,2) で、A2 が (0,4) であると仮定します。これらはそれぞれ B1 と B2 に関連しています。ここで、A1 と A2 は測定値ではありません。それらは動きのピクセルです。

ここでやらなければならないことは、A1 と A2 の変化に、B1 と B2 での実世界の距離になる計算された定数を掛けることです。注: これらは、測定 B * に従ってそれぞれ異なります。これはすべて、さまざまな距離での写真の視野角、またはより一般的には視野角に関連しています。カメラの CCD の各ピクセルのサイズと、カメラ内にあるレンズの F 値がわかっている場合は、定数を正確に計算できます。

これは当てはまらないので、さまざまな距離で、長さがわかっているオブジェクトを配置し、それが占めるピクセル数を確認する必要があります。クローズアップすると、定規を使用して作業が簡単になります。これらの測定で。このデータを取得し、最適な線で曲線を形成します。X 軸はオブジェクトの距離になり、Y 軸はピクセルと距離の比率の定数になり、移動に掛ける必要があります。

では、この曲線をどのように適用しますか。まあ、推測作業です。理論的には、動き A* の測定値が大きいほど、オブジェクトがカメラに近づきます。この例では、A1 > A2 の比率はそれぞれ 5mm と 3mm であり、ポイント B1 が 10mm (2x5mm) 移動し、B2 が 6mm (2x6mm) 移動したことがわかります。しかし、それに直面しましょう - 私たちは B を知ることは決してなく、移動した距離が 20 ピクセルの近くにあるオブジェクトが遠くに移動していないのか、遠くにあるオブジェクトが非常に長い距離を移動しているのかを判断することはできません。これが、Xbox Kinect のようなものが追加のセンサーを使用して、画像内のオブジェクトに関連付けることができる深度情報を取得する理由です。

これらのカメラ間の距離がわかっているため、2 台のカメラを使用して試行できることは、動きをより正確に計算できるためです (効果的に深度センサーを使用しなくても)。この背後にある数学は非常に複雑であり、この件に関するジャーナル論文を調べることをお勧めします. 理論を説明してほしいなら、そうすることができます。

私の経験はすべて、PHD 用の高速ビデオ取得と画像処理の設計から得たものなので、信頼してください。1 台のカメラではできません。申し訳ありません。これがいくつか役立つことを願っています。

乾杯

クリス

[編集]

コメントを追加するつもりでしたが、大量の情報があるため、これは簡単です。

これは Kinect であるため、各ポイントに関連付けられた関連する深度情報があると仮定します。そうでない場合は、これを取得する方法を理解する必要があります。

最初に必要な方程式は、視野 ( FOV ) です。

o/d = i/f

どこ:

fはレンズの焦点距離に等しく、通常は mm で表されます (つまり、18 28 30 50 が標準的な例です)。

dは、kinect データから収集されたレンズからの物体距離です

oは物体の寸法 (または光軸に垂直で光軸によって二等分される「視野」) です。

iは画像の寸法 (または光軸に垂直で、光軸によって二等分される「視野絞り」) です。

iを計算する必要があります。ここで、oは未知数なので、i (対角線の測定値) については、

ccd のピクセルのサイズが必要になります。これは、マイクロメートルまたは µm で表されます。この情報を見つける必要があります。ミッドレンジ エリア スキャン カメラの標準である 14um であると見なします。

したがって、最初に i 水平方向の寸法 ( ih ) を計算する必要があります。これは、カメラの幅のピクセル数に ccd ピクセルのサイズを掛けたものです (640 x 320 を使用します)。

そう: ih = 640*14um = 8960um

   = 8960/1000 = 8.96mm

ここで、縦方向の寸法 ( iv ) 同じプロセスですが、高さが必要です

そう: iv = (320 * 14um) / 1000 = 4.48mm

ピタゴラスの定理ピタゴラスの定理 a^2 + b^2 = c^ 2

つまり: i = sqrt(ih^2 _ iv^2)

  = 10.02 mm

ここで、レンズが 28 mm であると仮定します。繰り返しますが、この正確な値を見つける必要があります。したがって、方程式を再編成してoを得ると、次のようになります。

o = (i * d) / f

oは対角線になることを覚えておいてください(オブジェクトまたはポイントが 50mm 離れていると想定します)。

o = (10.02mm * 50mm) / 28mm

17.89mm

次に、オブジェクトが移動したピクセルあたりの距離が得られるため、水平方向の寸法 ( oh ) と垂直方向の寸法 ( ov ) を計算する必要があります。FOV α CCDまたはiはoに正比例するので、比率kを計算します。

k = i/o

= 10.02 / 17.89 

= 0.56

それで:

o水平寸法 ( oh ):

ああ=私/k

= 8.96mm / 0.56 = 16mm/ピクセル

o垂直方向 ( ov ):

ov = iv / k

= 4.48mm / 0.56 = 1 ピクセルあたり 8mm

必要な定数が揃ったので、例で使用してみましょう。50mm のオブジェクトが位置 (0,0) から (2,4) に移動した場合、実際の測定値は次のようになります。

(2*16mm、4*8mm) = (32mm、32mm)

ここでも、ピタゴラスの定理: a^2 + b^2 = c^2

合計距離 = sqrt(32^2 + 32^2)

           = 45.25mm

複雑なのはわかっていますが、これをプログラムに組み込むと、簡単になります。したがって、すべてのポイントについて、 dが変化するため、プロセスの少なくとも半分を繰り返す必要があります。

これでうまくいくことを願っています。

乾杯クリス

于 2011-09-12T18:57:00.807 に答える