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 になる整数除算を行っています。