OpenCV 将坐标传递给 OpenGL 但 OpenGL 无法绘制它
下面是我的程序,它通过 OpenCV 计算棋盘的旋转向量、旋转矩阵。然后通过从这个向量和矩阵创建 16 个值的数组,我将其传递给 OpenGL。但OpenGL窗口无法显示任何内容。 这种连接OpenCV和OpenGL的方法正确吗? 为什么OpenGL不绘制形状?
// this function for calculating rotation matrix and vector
void calculateOpenCVPoints(IplImage* image)
{
board_w = 4; // Board width in squares
board_h = 5; // Board height
n_boards =3; // Number of boards
board_n = board_w * board_h;
CvSize board_sz = cvSize( board_w, board_h );
CvMat* warp_matrix = cvCreateMat(3,3,CV_32FC1);
CvPoint2D32f* corners = new CvPoint2D32f[ board_n ];
int corner_count;
char pressedChar;
//cvNamedWindow("Livevideo",CV_WINDOW_AUTOSIZE);
imgPoints = cvCreateMat(n_boards*board_n,2,CV_32FC1) ;
objectPoints=cvCreateMat(n_boards*board_n,3,CV_32FC1);
pointCounts = cvCreateMat(n_boards,1,CV_32SC1);
intrinsicMatrix = cvCreateMat(3,3,CV_32FC1);
distortionCoeffs = cvCreateMat(5,1,CV_32FC1);
corners = new CvPoint2D32f[ board_n ];
IplImage *grayImage = cvCreateImage(cvGetSize(image),8,1);//subpixel
successes = 0;
while(successes < n_boards)
{
printf("\nIn calculateOpenCVPoints function for calculating image points ==%d",successes);
//Skip every board_dt frames to allow user to move chessboard
if(frame++ % board_dt == 0)
{
//Find chessboard corners:
int found = cvFindChessboardCorners(image, board_sz, corners, &cornerCount,
CV_CALIB_CB_ADAPTIVE_THRESH | CV_CALIB_CB_FILTER_QUADS);
cvCvtColor( image, grayImage, CV_BGR2GRAY );
cvFindCornerSubPix( grayImage, corners, cornerCount, cvSize( 11, 11 ),
cvSize( -1, -1 ), cvTermCriteria( CV_TERMCRIT_EPS+CV_TERMCRIT_ITER, 30, 0.1 ));
cvDrawChessboardCorners(image, board_sz, corners,cornerCount, found);
cvShowImage("Calibration", image );
if( cornerCount == board_n )
{
step = successes*board_n;
for( int i=step, j=0; j < board_n; ++i, ++j )
{
CV_MAT_ELEM( *imgPoints, float, i, 0 ) = corners[j].x;
CV_MAT_ELEM( *imgPoints, float, i, 1 ) = corners[j].y;
CV_MAT_ELEM( *objectPoints, float, i, 0 ) = j/board_w;
CV_MAT_ELEM( *objectPoints, float, i, 1 ) = j%board_w;
CV_MAT_ELEM( *objectPoints, float, i, 2 ) = 0.0f;
}
CV_MAT_ELEM( *pointCounts, int, successes, 0 ) = board_n;
successes++;
}
}//if(frame++ % board_dt == 0)
image = cvQueryFrame( cvCapture );
//cvShowImage("liveVideo",image);
presssedChar=cvWaitKey(5);
} //while(successes < n_boards)
cvFindExtrinsicCameraParams2(objectPoints,imgPoints,intrinsic,distortion,rotationVector,translationVector,0);
cvRodrigues2(rotationVector,rotationMatrix,NULL);
printf("\nRotation Vector and Rotation Matrx are calculated\n");
float rv[]={rotationVector->data.fl[0],rotationVector->data.fl[1],rotationVector->data.fl[2]};
float tv[]={translationVector->data.fl[0],translationVector->data.fl[1],translationVector->data.fl[2]};
float rm[9];
for(int i=0;i<9;i++)
rm[i]=rotationMatrix->data.fl[i];
for (int f=0; f<3; f++)
{
for (int c=0; c<3; c++)
{
toGLMatrix[c*4+f] = rm[f*3+c]; //transposed
}
}
toGLMatrix[3] = 0.0;
toGLMatrix[7] = 0.0;
toGLMatrix[11] = 0.0;
toGLMatrix[12] = -tv[0];
toGLMatrix[13] = -tv[1];
toGLMatrix[14] = tv[2];
toGLMatrix[15] = 1.0;
}
// openGL dispaly function
void display
{
calculateOpenCVPoints("Image from camera");
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
//argDraw3dCamera( 0, 0 );
glViewport(0, 0, 640,480);
glMatrixMode(GL_PROJECTION);
glLoadMatrixd(toGLMatrix);
glClearDepth( 1.0 );
glClear(GL_DEPTH_BUFFER_BIT);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
glMatrixMode(GL_MODELVIEW);
// Loading the calculated matrix from OpenCV rotation matrix and vector
glLoadMatrixd(toGLMatrix);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glLightfv(GL_LIGHT0, GL_POSITION, light_position);
glLightfv(GL_LIGHT0, GL_AMBIENT, ambi);
glLightfv(GL_LIGHT0, GL_DIFFUSE, lightZeroColor);
glMaterialfv(GL_FRONT, GL_SPECULAR, mat_flash);
glMaterialfv(GL_FRONT, GL_SHININESS, mat_flash_shiny);
glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient);
glMatrixMode(GL_MODELVIEW);
glColor3d(1.0f,1.0f,1.0f);
glTranslatef( 0.0, 0.0,0.0 );
glutSolidCube(140);
glDisable( GL_LIGHTING );
glDisable( GL_DEPTH_TEST );
glutSwapBuffers();
}
// and remaining as initialize glut etc
Below is my program which calculates the rotation vector, rotation matrix from chessboard through OpenCV. And then by creating array of 16 values from this vector and matrix I am passing this to OpenGL. But OpenGL window cant show anything.
Is this way is correct to connect OpenCV and OpenGL?
Why OpenGL not drawing the shape?
// this function for calculating rotation matrix and vector
void calculateOpenCVPoints(IplImage* image)
{
board_w = 4; // Board width in squares
board_h = 5; // Board height
n_boards =3; // Number of boards
board_n = board_w * board_h;
CvSize board_sz = cvSize( board_w, board_h );
CvMat* warp_matrix = cvCreateMat(3,3,CV_32FC1);
CvPoint2D32f* corners = new CvPoint2D32f[ board_n ];
int corner_count;
char pressedChar;
//cvNamedWindow("Livevideo",CV_WINDOW_AUTOSIZE);
imgPoints = cvCreateMat(n_boards*board_n,2,CV_32FC1) ;
objectPoints=cvCreateMat(n_boards*board_n,3,CV_32FC1);
pointCounts = cvCreateMat(n_boards,1,CV_32SC1);
intrinsicMatrix = cvCreateMat(3,3,CV_32FC1);
distortionCoeffs = cvCreateMat(5,1,CV_32FC1);
corners = new CvPoint2D32f[ board_n ];
IplImage *grayImage = cvCreateImage(cvGetSize(image),8,1);//subpixel
successes = 0;
while(successes < n_boards)
{
printf("\nIn calculateOpenCVPoints function for calculating image points ==%d",successes);
//Skip every board_dt frames to allow user to move chessboard
if(frame++ % board_dt == 0)
{
//Find chessboard corners:
int found = cvFindChessboardCorners(image, board_sz, corners, &cornerCount,
CV_CALIB_CB_ADAPTIVE_THRESH | CV_CALIB_CB_FILTER_QUADS);
cvCvtColor( image, grayImage, CV_BGR2GRAY );
cvFindCornerSubPix( grayImage, corners, cornerCount, cvSize( 11, 11 ),
cvSize( -1, -1 ), cvTermCriteria( CV_TERMCRIT_EPS+CV_TERMCRIT_ITER, 30, 0.1 ));
cvDrawChessboardCorners(image, board_sz, corners,cornerCount, found);
cvShowImage("Calibration", image );
if( cornerCount == board_n )
{
step = successes*board_n;
for( int i=step, j=0; j < board_n; ++i, ++j )
{
CV_MAT_ELEM( *imgPoints, float, i, 0 ) = corners[j].x;
CV_MAT_ELEM( *imgPoints, float, i, 1 ) = corners[j].y;
CV_MAT_ELEM( *objectPoints, float, i, 0 ) = j/board_w;
CV_MAT_ELEM( *objectPoints, float, i, 1 ) = j%board_w;
CV_MAT_ELEM( *objectPoints, float, i, 2 ) = 0.0f;
}
CV_MAT_ELEM( *pointCounts, int, successes, 0 ) = board_n;
successes++;
}
}//if(frame++ % board_dt == 0)
image = cvQueryFrame( cvCapture );
//cvShowImage("liveVideo",image);
presssedChar=cvWaitKey(5);
} //while(successes < n_boards)
cvFindExtrinsicCameraParams2(objectPoints,imgPoints,intrinsic,distortion,rotationVector,translationVector,0);
cvRodrigues2(rotationVector,rotationMatrix,NULL);
printf("\nRotation Vector and Rotation Matrx are calculated\n");
float rv[]={rotationVector->data.fl[0],rotationVector->data.fl[1],rotationVector->data.fl[2]};
float tv[]={translationVector->data.fl[0],translationVector->data.fl[1],translationVector->data.fl[2]};
float rm[9];
for(int i=0;i<9;i++)
rm[i]=rotationMatrix->data.fl[i];
for (int f=0; f<3; f++)
{
for (int c=0; c<3; c++)
{
toGLMatrix[c*4+f] = rm[f*3+c]; //transposed
}
}
toGLMatrix[3] = 0.0;
toGLMatrix[7] = 0.0;
toGLMatrix[11] = 0.0;
toGLMatrix[12] = -tv[0];
toGLMatrix[13] = -tv[1];
toGLMatrix[14] = tv[2];
toGLMatrix[15] = 1.0;
}
// openGL dispaly function
void display
{
calculateOpenCVPoints("Image from camera");
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
//argDraw3dCamera( 0, 0 );
glViewport(0, 0, 640,480);
glMatrixMode(GL_PROJECTION);
glLoadMatrixd(toGLMatrix);
glClearDepth( 1.0 );
glClear(GL_DEPTH_BUFFER_BIT);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
glMatrixMode(GL_MODELVIEW);
// Loading the calculated matrix from OpenCV rotation matrix and vector
glLoadMatrixd(toGLMatrix);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glLightfv(GL_LIGHT0, GL_POSITION, light_position);
glLightfv(GL_LIGHT0, GL_AMBIENT, ambi);
glLightfv(GL_LIGHT0, GL_DIFFUSE, lightZeroColor);
glMaterialfv(GL_FRONT, GL_SPECULAR, mat_flash);
glMaterialfv(GL_FRONT, GL_SHININESS, mat_flash_shiny);
glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient);
glMatrixMode(GL_MODELVIEW);
glColor3d(1.0f,1.0f,1.0f);
glTranslatef( 0.0, 0.0,0.0 );
glutSolidCube(140);
glDisable( GL_LIGHTING );
glDisable( GL_DEPTH_TEST );
glutSwapBuffers();
}
// and remaining as initialize glut etc
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您在这里加载矩阵两次。这没有道理。它将把顶点转换为
绝对不是你想要的。
OpenCV 提供的矩阵结合了投影和模型视图。理想情况下,您不会使用固定功能 OpenGL,而是使用顶点着色器。这会让事情变得更清楚。
对于简单的应用程序,只需将 OpenCV 中的矩阵加载到模型视图中,并使投影成为恒等变换。
如果您希望它正确,请将 OpenCV 中的矩阵分成两部分:正交模型视图部分和匹配投影部分,其中 Z 列的 x 和 y 分量为零。令 C 为 OpenCV 的矩阵。为此求解方程组:
You're loading the matrix two times here. That doesn't make sense. It would transform the vertices as
Definitely not what you want.
The matrix delivered by OpenCV combines projection and modelview. Ideally you wouldn't use fixed function OpenGL, but use a vertex shader for this. This would make things clearer.
For a simple drop in application, load the matrix from OpenCV just into modelview and make projection a identity transform.
If you want it to be correct, separate the matrix from OpenCV into two parts: A orthonormal modelview part and a matching projection one, with the x and y components of the Z column being zero. Let C be the matrix from OpenCV. For this solve the system of equations: