c - OpenCV 将坐标传递给 OpenGL 但 OpenGL 无法绘制它

标签 c opengl opencv

下面是我的程序,它通过 OpenCV 计算棋盘的旋转 vector 、旋转矩阵。然后通过从这个 vector 和矩阵创建 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 

最佳答案

        glViewport(0, 0, 640,480);
        glMatrixMode(GL_PROJECTION);
        glLoadMatrixd(toGLMatrix);

        glMatrixMode(GL_MODELVIEW);
        // Loading the calculated matrix from OpenCV rotation matrix and vector
        glLoadMatrixd(toGLMatrix);

您在这里加载矩阵两次。这没有道理。它将把顶点转换为

v' = M M v = M² v

绝对不是你想要的。

OpenCV 提供的矩阵结合了投影和模型 View 。理想情况下,您不会使用固定功能 OpenGL,而是使用顶点着色器。这会让事情变得更清楚。

对于简单的应用程序,只需将 OpenCV 中的矩阵加载到模型 View 中,并使投影成为恒等变换。

如果你希望它是正确的,请将 OpenCV 中的矩阵分成两部分:正交模型 View 部分和匹配投影部分,其中 Z 列的 x 和 y 分量为零。令 C 为 OpenCV 的矩阵。为此求解方程组:

C = P M

P.zx = 0
P.zy = 0
P.zz =/= 0
P.zw =/= 0

M.x · M.y = 0
M.y · M.z = 0
M.z · M.x = 0

M.xw = 0
M.yw = 0
M.zw = 0
M.ww = 1

| M.x | = 1
| M.y | = 1
| M.z | = 1

关于c - OpenCV 将坐标传递给 OpenGL 但 OpenGL 无法绘制它,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9247515/

相关文章:

c - vfprintf 导致运行时错误

c - printf () 的奇怪行为

winapi - 获取在其中运行 OpenGL 的子窗口的屏幕截图(Windows)

c++ - openCV 中的彩色对象跟踪不断检测皮肤

c++ - 获取和设置相机设置

集群上带有 SLURM 的 C 库函数 exit()

c - 如何从主函数调用dll文件?

python - 如何在 pyglet/pyopengl 中使用透明层而不是纯色来清除屏幕

opengl - 从 Cygwin 下的 OpenGL 开始

c - OpenCV - 显示网络摄像头视频时出错