2017-01-15 10 views
0

私はsolvePnPを使用してビューマトリックスを取得しようとする私のiOSアプリケーションに問題があり、最新のOpenGLを使用して3dキューブをレンダリングします。私のコードが検出されたマーカーの上に直接3Dキューブをレンダリングしようとするが、右下の(OpenCV + OpenGLを使用するsolvePnPカメラポーズ - オブジェクトが検出されたマーカーからオフセットされました

https://www.youtube.com/watch?v=HhP5Qr3YyGI&feature=youtu.be

(例えばビデオを参照)マーカーからのオフセットを特定してレンダリングするようですあなたはトラッカーマーカーの周りのホモグラフィのopencvレンダリングを見ることができます。スクリーンの残りは、カメラ入力フレームのOpenGLレンダリングと位置(0,0,0)の3dキューブです。

キューブが回転します私はマーカーを動かすたびに正確に翻訳します。翻訳のスケールには多少の違いがあるとは言いますが(IE、現実世界で5cmのマーカーを動かすと、1cmだけ移動することはほとんどありませんスクリーン)

これらは、私はエラーから来ることができ、コードの関連部分であると信じるものです:ホモグラフィからビュー行列を抽出

AVCaptureDevice *deviceInput = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo]; 
AVCaptureDeviceFormat *format = deviceInput.activeFormat; 
CMFormatDescriptionRef fDesc = format.formatDescription; 
CGSize dim = CMVideoFormatDescriptionGetPresentationDimensions(fDesc, true, true); 

const float cx = float(dim.width)/2.0; 
const float cy = float(dim.height)/2.0; 

const float HFOV = format.videoFieldOfView; 
const float VFOV = ((HFOV)/cx)*cy; 

const float fx = abs(float(dim.width)/(2 * tan(HFOV/180 * float(M_PI)/2))); 
const float fy = abs(float(dim.height)/(2 * tan(VFOV/180 * float(M_PI)/2))); 


Mat camIntrinsic = Mat::zeros(3, 3, CV_64F); 
camIntrinsic.at<double>(0, 0) = fx; 
camIntrinsic.at<double>(0, 2) = cx; 
camIntrinsic.at<double>(1, 1) = fy; 
camIntrinsic.at<double>(1, 2) = cy; 
camIntrinsic.at<double>(2, 2) = 1.0; 

std::vector<cv::Point3f> object3dPoints; 
object3dPoints.push_back(cv::Point3f(-0.5f,-0.5f,0)); 
object3dPoints.push_back(cv::Point3f(+0.5f,-0.5f,0)); 
object3dPoints.push_back(cv::Point3f(+0.5f,+0.5f,0)); 
object3dPoints.push_back(cv::Point3f(-0.5f,+0.5f,0)); 


cv::Mat raux,taux; 
cv::Mat Rvec, Tvec; 
cv::solvePnP(object3dPoints, mNewImageBounds, camIntrinsic, Mat(),raux,taux); //mNewImageBounds are the 4 corner of the homography detected by perspectiveTransform (the green outline seen in the image) 
raux.convertTo(Rvec,CV_32F); 
taux.convertTo(Tvec ,CV_64F); 

Mat Rot(3,3,CV_32FC1); 
Rodrigues(Rvec, Rot); 

// [R | t] matrix 
Mat_<double> para = Mat_<double>::eye(4,4); 
Rot.convertTo(para(cv::Rect(0,0,3,3)),CV_64F); 
Tvec.copyTo(para(cv::Rect(3,0,1,3))); 

Mat cvToGl = Mat::zeros(4, 4, CV_64F); 
cvToGl.at<double>(0, 0) = 1.0f; 
cvToGl.at<double>(1, 1) = -1.0f; // Invert the y axis 
cvToGl.at<double>(2, 2) = -1.0f; // invert the z axis 
cvToGl.at<double>(3, 3) = 1.0f; 

para = cvToGl * para; 

Mat_<double> modelview_matrix; 
Mat(para.t()).copyTo(modelview_matrix); // transpose to col-major for OpenGL 
glm::mat4 openGLViewMatrix; 
for(int col = 0; col < modelview_matrix.cols; col++) 
{ 
    for(int row = 0; row < modelview_matrix.rows; row++) 
    { 
     openGLViewMatrix[col][row] = modelview_matrix.at<double>(col,row); 
    } 
} 

私は確信してカメラ内部行列を作りました正しい値が入っています。キューブが平行移動して正しい方向に回転するので、opencv MatをOpenGLビューの行列に変換する部分が正しいと思います。

ビュー行列が計算されると、私は次のようにキューブを描画するためにそれを使用します。

_projectionMatrix = glm::perspective<float>(radians(60.0f), fabs(view.bounds.size.width/view.bounds.size.height), 0.1f, 100.0f); 
_cube_ModelMatrix = glm::translate(glm::vec3(0,0,0)); 
const mat4 MVP = _projectionMatrix * openGLViewMatrix * _cube_ModelMatrix; 
glUniformMatrix4fv(glGetUniformLocation(_cube_program, "ModelMatrix"), 1, GL_FALSE, value_ptr(MVP)); 

glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_INT, BUFFER_OFFSET(0)); 

は私の誤りを発見することができ、誰ですか?ここで説明したように

答えて

0

あなたは透視行列を作成する必要があります。http://ksimek.github.io/2013/08/13/intrinsic

:固有行列の詳細については

const float fx = intrinsicParams(0, 0); // Focal length in x axis 
const float fy = intrinsicParams(1, 1); // Focal length in y axis 
const float cx = intrinsicParams(0, 2); // Primary point x 
const float cy = intrinsicParams(1, 2); // Primary point y 

projectionMatrix(0, 0) = 2.0f * fx; 
projectionMatrix(0, 1) = 0.0f; 
projectionMatrix(0, 2) = 0.0f; 
projectionMatrix(0, 3) = 0.0f; 

projectionMatrix(1, 0) = 0.0f; 
projectionMatrix(1, 1) = 2.0f * fy; 
projectionMatrix(1, 2) = 0.0f; 
projectionMatrix(1, 3) = 0.0f; 

projectionMatrix(2, 0) = 2.0f * cx - 1.0f; 
projectionMatrix(2, 1) = 2.0f * cy - 1.0f; 
projectionMatrix(2, 2) = -(far + near)/(far - near); 
projectionMatrix(2, 3) = -1.0f; 

projectionMatrix(3, 0) = 0.0f; 
projectionMatrix(3, 1) = 0.0f; 
projectionMatrix(3, 2) = -2.0f * far * near/(far - near); 
projectionMatrix(3, 3) = 0.0f; 

http://ksimek.github.io/2013/06/03/calibrated_cameras_in_openglここ

が速いコードです

関連する問題