1

OpenCV と OpenGL のコンポーネントを行ったり来たりしていますが、2 つのうちどちらを修正すればよいかわかりません。

OpenCV カメラ キャリブレーションを使用すると、アスペクト比が約 1 の fx、fy が得られます。これは、正方形サイズの画像に相当します。私の校正出力:

...
image_width: 640
image_height: 480
board_width: 6
board_height: 9
square_size: 5.
flags: 0
camera_matrix: !!opencv-matrix
   rows: 3
   cols: 3
   dt: d
   data: [ 6.6244874649105122e+02, 0., 3.4060477796553954e+02, 
        0., 6.4821741696313484e+02, 2.5815418044786418e+02, 
        0., 0., 1. ]
distortion_coefficients: !!opencv-matrix
   rows: 5
   cols: 1
   dt: d
   data: [ -1.1832005538154940e-01, 1.2254891816651683e+00, 3.8133468645674677e-02, 1.3073747832019200e-02, -3.9497162757084490e+00 ]

ただし、キャリブレーション出力でわかるように、画像の幅は 640x480 です。

フレーム内のチェッカーボードを検出し、OpenGL でチェッカーボードを描画すると、OpenGL は高さは問題なくレンダリングされますが、幅方向に引き伸ばされるため、実際のチェッカーボードに収まりません。確かに解決するのは、キャリブレーションのfxコンポーネントに480/640を掛けることですが、それが正しい方法かどうかはわかりません.

これを修正するにはどうすればよいですか?キャリブレーション値を画像サイズでスケーリングするか、OpenGL で何かを修正して修正しますか?

編集

キャプチャと表示には違いがあります。キャリブレーションされたスマートフォンで画像をキャプチャすると、そのスマートフォンは 640x480 の画像を吐き出します。

チェス盤を見つけるために、キャリブレーションされた上記の組み込み関数を使用します。

次に、どのアスペクト比を OpenGL に与えても、それを fx/fy、640/480、または fx/fy * 640/480 とすると、それは間違っています。OpenGL で投影されたものが幅方向に引き伸ばされるような方法で、OpenGL で投影されたチェス盤。

OpenGL で正確に見える唯一の方法は、 chessboard を見つけるために fx=640, fy=480 を使用する場合です。カメラの組み込み関数を完全に無視しているため、これも間違っています...ここに画像の説明を入力

編集2

つまり、gluPerspective に渡すアスペクト比をどのように設定しても、正しく表示されません。

gluPerspective( /* field of view in degree */ m_fovy,
   /* aspect ratio */ 1.0/m_aspect_ratio,
   /* Z near */ 1.0, /* Z far */ 1000.0);

m_aspect_ratio の値に対して私が試したこと:

  • OpenCVのcalibrationMatrixValuesの出力アスペクト比
  • 為替/年度
  • 640/480
  • 為替/年度 * 640/480
  • キャリブレーションマトリックス値の出力 * 640/480

すべてが幅を台無しにしているようです。私のスクリーンショットでは、チェス盤の原点が画像の一番上の内側の角であることに注意してください。正しく配置されており、画像の一番下の内側の角もそうです。縮尺の問題です..

編集3

それは本当に、本当にばかげたものでした.. OpenGLのアスペクト比を次のように設定していました:

gluPerspective( /* field of view in degree */ m_fovy,
    /* aspect ratio */ 1.0/m_aspect_ratio,
    /* Z near */ 1.0, /* Z far */ 1000.0);

と設定

m_aspect_ratio = viewportpixelheight / viewportpixelwidth;

viewportpixelheightとが整数であることを認識していないviewportpixelwidthため、1 または (それらを交換すると) 0 になる整数除算を行っています。

4

2 に答える 2

1

カメラ キャリブレーション マトリックスは、ワールド座標を画像座標にマッピングします。OpenGL は、画像座標を画面座標にマップします。問題が画像の表示方法にある場合は、OpenGL で処理する必要があります。

混乱させて申し訳ありません。私がやろうとしていたのは、画像のキャプチャと表示を区別することです。物理カメラの縦横比は焦点距離から計算できることは正しいです。これらの焦点距離とその縦横比は、カメラのハードウェアによって固定されています。その画像をキャプチャしたら、OpenGL で選択した縦横比で自由に表示できます。表示されるものの縦横比を変更するために、画像を好きなだけトリミングおよびストレッチできます。カメラの縦横比が画面の縦横比と一致するとは限りません。OpenCV は、物理カメラから直接生の測定値を使用してカメラ キャリブレーション マトリックスを計算します。それらが正しく一定であると仮定した場合 (ズームがない場合はどちらも妥当と思われます)、アスペクト比のさらなる変更は OpenGL の責任です。fx と fy は縦横比を決定しないと言いましたが、表示された縦横比について言及していましたが、まったく明確ではありませんでした。

また、焦点距離からアスペクト比を計算できる理由は、焦点距離がピクセル単位で表され、それらの単位が x 軸と y 軸で異なる可能性があるためです。簡単な説明はここにあります

カメラ マトリックスの焦点距離について私が見つけた最良の説明は、Computer Vision Algorithms and Applicationsのカメラの組み込みに関するセクションにあります。PDFでは、本の72ページ、50ページから始まります。

于 2012-11-02T14:58:47.180 に答える
1

アスペクト比 1.0 は正方形の画像を示すのではなく、正方形のピクセルを示します(これが、ほぼ常に 1.0 である理由を説明しています。非正方形のピクセルは、アナモフィック形式でキャプチャするカメラを除いて比較的まれです)。カメラ マトリックスには、画像の絶対寸法や物理的なカメラの寸法 に関する情報は含まれていません。

一方、gluPerspective のアスペクト比画像のサイズを表します。アスペクト比を混同しないことが重要です。

gluPerspective を使用したい場合は可能ですが、gluPerspective では固有のカメラ パラメータ (軸の傾きと主点のオフセット) のすべてをモデル化できないことを理解する必要があります。この記事では、アスペクト比と fovy を正しく設定する方法について説明します。

ただし、gluFrustum (非ゼロの主点オフセットを許可) または glLoadMatrix を直接使用することを強くお勧めします (非ゼロの軸スキューも許可します)。この記事では、両方のアプローチについて説明します。

于 2013-06-28T19:19:38.533 に答える