如何使用OpenCV cvProjectPoints2函数

时间:2009-06-10 05:12:21

标签: 3d opencv

我在使用cvProjectPoints2功能时遇到了一些麻烦。 以下是O'Reilly的“Learning OpenCV”一书的功能概述:

void cvProjectPoints2(
const CvMat* object_points,
const CvMat* rotation_vector,
const CvMat* translation_vector,
const CvMat* intrinsic_matrix,
const CvMat* distortion_coeffs,
CvMat* image_points,
);
     

第一个参数object_points是您想要投射的点数列表;它只是一个包含点位置的N×3矩阵。您可以在对象自己的局部坐标系中给出这些,然后提供3×1矩阵rotation_vector *和translation_vector来关联这两个坐标。如果在您的特定情况下直接在相机坐标中工作更容易,那么您可以在该系统中提供object_points并将rotation_vectortranslation_vector都设置为包含0。†

     

intrinsic_matrixdistortion_coeffs只是相机内在信息和来自cvCalibrateCamera2()的失真系数   11. image_points参数是N-by-2矩阵,计算结果将写入其中。

首先,object_points数组似乎存在错误。如果只有一个点,即N = 1,则程序崩溃。 无论如何,我有几个相机内部参数和投影矩阵。失真系数为0,即没有失真。 为简单起见,假设我有2个摄像头:

double intrinsic[2][3][3] = {
//camera 0
1884.190000,    0, 513.700000,
0.0,    1887.490000,    395.609000,
0.0,    0.0,    1.0,
//camera 4
1877.360000,    0.415492,   579.467000,
0.0,    1882.430000,    409.612000,
0.0,    0.0,    1.0
};

double projection[2][3][4] = {
//camera 0
0.962107,   -0.005824,  0.272486,   -14.832727,
0.004023,   0.999964,   0.007166,   0.093097,
-0.272519,  -0.005795,  0.962095,   -0.005195,
//camera 4
1.000000,   0.000000,   -0.000000,  0.000006,
0.000000,   1.000000,   -0.000000,  0.000001,
-0.000000,  -0.000000,  1.000000,   -0.000003
};

据我了解,此信息足以投影任何相机视图上的任何点(x,y,z)。这里,在x,y,z坐标中,摄像机4的光学中心是世界坐标的原点。

这是我的代码:

#include <cv.h>
#include <highgui.h>
#include <cvaux.h>
#include <cxcore.h>
#include <stdio.h>

double intrinsic[2][3][3] = {
//0
1884.190000,    0, 513.700000,
0.0,    1887.490000,    395.609000,
0.0,    0.0,    1.0,
//4
1877.360000,    0.415492,   579.467000,
0.0,    1882.430000,    409.612000,
0.0,    0.0,    1.0
};

double projection[2][3][4] = {
//0
0.962107,   -0.005824,  0.272486,   -14.832727,
0.004023,   0.999964,   0.007166,   0.093097,
-0.272519,  -0.005795,  0.962095,   -0.005195,
//4
1.000000,   0.000000,   -0.000000,  0.000006,
0.000000,   1.000000,   -0.000000,  0.000001,
-0.000000,  -0.000000,  1.000000,   -0.000003
};


int main() {
    CvMat* camera_matrix[2]; //
    CvMat* rotation_matrix[2]; //
    CvMat* dist_coeffs[2]; 
    CvMat* translation[2];
    IplImage* image[2];
    image[0] = cvLoadImage("color-cam0-f000.bmp", 1);
    image[1] = cvLoadImage("color-cam4-f000.bmp", 1);
    CvSize image_size;
    image_size = cvSize(image[0]->width, image[0]->height);

    for (int m=0; m<2; m++) {
        camera_matrix[m] = cvCreateMat(3, 3, CV_32F);
        dist_coeffs[m] = cvCreateMat(1, 4, CV_32F);
        rotation_matrix[m] = cvCreateMat(3, 3, CV_32F);
        translation[m] = cvCreateMat(3, 1, CV_32F);
    }

    for (int m=0; m<2; m++) {
        for (int i=0; i<3; i++)
            for (int j=0; j<3; j++) {
                cvmSet(camera_matrix[m],i,j, intrinsic[m][i][j]);
                cvmSet(rotation_matrix[m],i,j, projection[m][i][j]);
            }
        for (int i=0; i<4; i++)
            cvmSet(dist_coeffs[m], 0, i, 0);
        for (int i=0; i<3; i++)
            cvmSet(translation[m], i, 0, projection[m][i][3]);
    }

    CvMat* vector = cvCreateMat(3, 1, CV_32F);
    CvMat* object_points = cvCreateMat(10, 3, CV_32F);
    cvmSet(object_points, 0, 0, 1000);
    cvmSet(object_points, 0, 1, 500);
    cvmSet(object_points, 0, 2, 100);

    CvMat* image_points = cvCreateMat(10, 2, CV_32F);
    int m = 0;
    cvRodrigues2(rotation_matrix[m], vector);
    cvProjectPoints2(object_points, vector, translation[m], camera_matrix[m], dist_coeffs[m], image_points);
    printf("%f\n", cvmGet(image_points, 0, 0));
    printf("%f\n", cvmGet(image_points, 0, 1));
    return 0;
}

图像是1024 * 768,z的可见部分知道在44到120之间。因此,应该在两个摄像机上看到该点,对吗?但结果绝对错误。即使m = 1。 我做错了什么?

1 个答案:

答案 0 :(得分:3)