問題は次のとおりです。私はOpenGLティーポットを図面付き紙に表示するコードを書いています。このために、用紙の4つのコーナーを追跡します(SURF検出&のマッチングに続いてホモグラフィ行列を計算し、コーナー位置の平均を移動してジッタを減らします)。コーナー座標は、カメラの固有の&(それぞれcalibrateCamera()
およびsolvePnP()
を使用)を計算するために使用されます。回転行列は、Rodrigues()
を使用して計算されます。その後、decomposeProjectionMatrix()
を使用して回転角度を計算しました。ここで、コードのOpenCVの一部です: AR with OpenCV&OpenGL
...
objPoints.push_back(objCorners);
scenePoints.push_back(sceneCorners);
calibrateCamera(objPoints, scenePoints, Size(640,480), camMtx, distortCoeff, RVecs, tVecs);
solvePnP(objCorners, sceneCorners, camMtx, distortCoeff, RVec, tVec);
Rodrigues(RVec, rotMtx);
getAngles(rotMtx, rotAngles);
objCorners
getAngles()
は、次のよう
void getAngles(Mat &rotCamMtx, Vec3d &angles)
{
Mat camMtx, rotMtx, transVec, rotMtxX, rotMtxY, rotMtxZ;
double *r = rotCamMtx.ptr<double>();
double projMtx[12] = {r[0], r[1], r[2], 0,
r[3], r[4], r[5], 0,
r[6], r[7], r[8], 0};
decomposeProjectionMatrix(Mat(3,4,CV_64FC1,projMtx), camMtx, rotMtx, transVec, rotMtxX, rotMtxY, rotMtxZ, angles);
}
そしてIは、OpenGLモデルビュー行列の要素を設定:
modelViewMat[0] = 1.0;
modelViewMat[1] = 0.0;
modelViewMat[2] = 0.0;
modelViewMat[3] = 0.0;
modelViewMat[4] = 0.0;
modelViewMat[5] = 1.0;
modelViewMat[6] = 0.0;
modelViewMat[7] = 0.0;
modelViewMat[8] = 0.0;
modelViewMat[9] = 0.0;
modelViewMat[10] = 1.0;
modelViewMat[11] = 0.0;
modelViewMat[12] = 2*matCenter.x/639 - 641/639;
modelViewMat[13] = 481/479 - 2*matCenter.y/479;
modelViewMat[14] = -0.25;
modelViewMat[15] = 1.0;
matCenter
中心の平均を取ることによって得られる紙の座標であります4つのコーナー。 modelViewMat[12]
およびmodelViewMat[13]
の値は、ピクセル座標([1 640]、[1 480])を([-1 1]、[1 -1])にマッピングすることによって得られます。
...
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
glLoadMatrixd(modelViewMat);
glRotated(-45, 1.0, 0.0, 0.0);
glRotated(rotAngles[2], 0.0, 1.0, 0.0);
glShadeModel(GL_SMOOTH);
glColor3f(1.0, 1.0, 1.0);
glutSolidTeapot(0.3);
私はそれが紙の上に「座って」見える作るためにティーポットにx軸の周りに-45度回転:コードのOpenGLの一部。 結果は次のようになります:私が机の上で紙を翻訳すると、紙の上のティーポットの位置は(同じ場所で)多かれ少なかれ正しいです。紙を回転させると、ティーポットは回転(y軸の周り)に正しく追従しますが、正しい位置にはなりません。質問は、紙の同じ場所にティーポットを「ピン止め」する方法です。私はRodrigues()
とsolvePnP()
の結果をOpenGLモデルビューマトリックス(OpenCV + OpenGL: proper camera pose using solvePnPで示唆)で直接使用しようとしましたが、結果は正しくありません。