Temel artırılmış gerçekliği yapmak için OpenCV kullanmaya çalışıyorum. Ben bu konuda bir yol bir kamera görüntüsünden puan almak için findChessboardCorners
kullanıyor. Sonra, z = 0 düzlemi boyunca bir 3D dörtlü yaratıyorum ve görüntülenen noktalar ile düzlemsel noktalar arasında bir homografi elde etmek için solvePnP
kullanın. Bundan sonra, görüntünün üstünde doğru poz ile küp oluşturmamı sağlayacak bir modelview matrisi oluşturabilmem gerektiğini düşünüyorum.OpenCV: Rotasyon/çeviri vektörü OpenGL model görünümü matrisi
solvePnP
için documentation, "(çeviri vektörü ile birlikte), model koordinat sisteminden kamera koordinat sistemine noktalar getirdiği" bir döndürme vektörü çıkardığını belirtir. " Bence istediğimin tam tersi; benim dörtlü z = 0 düzleminde olduğundan, bu dörtgeni uygun 3B düzlemine dönüştürecek bir modelview matrisi istiyorum.
Karşılıklı sırayla ters çevirileri ve çevirileri yaparak, doğru modelview matrisini hesaplayabilirim, ancak işe yaramayacağını düşündüm. İşlenen nesne (bir küp) kamera görüntüsüyle hareket ederken ve çeviri açısından kabaca doğru gibi görünüyor olsa da, döndürme işlemi hiç çalışmıyor; Birden fazla eksenin sadece bir tanesinin üzerinde ve bazen de yanlış yönde dönmesi gerektiğinde. İşte ben bugüne kadar ne yapıyorum: Sonra çizim kodunda
std::vector<Point2f> corners;
bool found = findChessboardCorners(*_imageBuffer, cv::Size(5,4), corners,
CV_CALIB_CB_FILTER_QUADS |
CV_CALIB_CB_FAST_CHECK);
if(found)
{
drawChessboardCorners(*_imageBuffer, cv::Size(6, 5), corners, found);
std::vector<double> distortionCoefficients(5); // camera distortion
distortionCoefficients[0] = 0.070969;
distortionCoefficients[1] = 0.777647;
distortionCoefficients[2] = -0.009131;
distortionCoefficients[3] = -0.013867;
distortionCoefficients[4] = -5.141519;
// Since the image was resized, we need to scale the found corner points
float sw = _width/SMALL_WIDTH;
float sh = _height/SMALL_HEIGHT;
std::vector<Point2f> board_verts;
board_verts.push_back(Point2f(corners[0].x * sw, corners[0].y * sh));
board_verts.push_back(Point2f(corners[15].x * sw, corners[15].y * sh));
board_verts.push_back(Point2f(corners[19].x * sw, corners[19].y * sh));
board_verts.push_back(Point2f(corners[4].x * sw, corners[4].y * sh));
Mat boardMat(board_verts);
std::vector<Point3f> square_verts;
square_verts.push_back(Point3f(-1, 1, 0));
square_verts.push_back(Point3f(-1, -1, 0));
square_verts.push_back(Point3f(1, -1, 0));
square_verts.push_back(Point3f(1, 1, 0));
Mat squareMat(square_verts);
// Transform the camera's intrinsic parameters into an OpenGL camera matrix
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
// Camera parameters
double f_x = 786.42938232; // Focal length in x axis
double f_y = 786.42938232; // Focal length in y axis (usually the same?)
double c_x = 217.01358032; // Camera primary point x
double c_y = 311.25384521; // Camera primary point y
cv::Mat cameraMatrix(3,3,CV_32FC1);
cameraMatrix.at<float>(0,0) = f_x;
cameraMatrix.at<float>(0,1) = 0.0;
cameraMatrix.at<float>(0,2) = c_x;
cameraMatrix.at<float>(1,0) = 0.0;
cameraMatrix.at<float>(1,1) = f_y;
cameraMatrix.at<float>(1,2) = c_y;
cameraMatrix.at<float>(2,0) = 0.0;
cameraMatrix.at<float>(2,1) = 0.0;
cameraMatrix.at<float>(2,2) = 1.0;
Mat rvec(3, 1, CV_32F), tvec(3, 1, CV_32F);
solvePnP(squareMat, boardMat, cameraMatrix, distortionCoefficients,
rvec, tvec);
_rv[0] = rvec.at<double>(0, 0);
_rv[1] = rvec.at<double>(1, 0);
_rv[2] = rvec.at<double>(2, 0);
_tv[0] = tvec.at<double>(0, 0);
_tv[1] = tvec.at<double>(1, 0);
_tv[2] = tvec.at<double>(2, 0);
}
...
GLKMatrix4 modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, 0.0f);
modelViewMatrix = GLKMatrix4Translate(modelViewMatrix, -tv[1], -tv[0], -tv[2]);
modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, -rv[0], 1.0f, 0.0f, 0.0f);
modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, -rv[1], 0.0f, 1.0f, 0.0f);
modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, -rv[2], 0.0f, 0.0f, 1.0f);
ben den yani (menşe etrafında birim uzunlukta bir küp oluşturmak render ediyorum köşe - Her bir kenar boyunca 0,5 ila 0,5 arasında. OpenGL çeviri işlevlerini kullanarak "ters sırayla" dönüşümleri gerçekleştirdiğimi biliyorum, böylece yukarıdaki küpü z, y ve sonra x ekseni boyunca döndürmeli ve sonra çevirmelidir. Ancak, önce çevrildiğini ve sonra döndürülmüş gibi görünüyor, bu yüzden belki de Apple'ın GLKMatrix4
farklı çalışır?
This question, benimkine çok benziyor ve özellikle kodlayıcı9'un cevabı, az çok aradığım şey gibi görünüyor. Ancak, bunu denedim ve sonuçları yöntemimle karşılaştırdım ve her iki durumda da geldiğim matrisler aynıydı. Cevabın doğru olduğunu hissediyorum, ancak bazı önemli ayrıntıları kaçırdığımı düşünüyorum.
Bunu kendim yapmayı deneyin. Bu gönderiyi koordinat sistemi farklılıkları konusuna baktım. http://stackoverflow.com/questions/9081900/reference-coordinate-system-changes-between-opencv-opengl-and-android-sensor – Koobz