相机校准中的Homography矩阵计算的3D-2D点对应

时间:2015-11-25 18:33:47

标签: c++ opencv image-processing computer-vision camera-calibration

我一直在努力了解相机校准背后的概念,但现在已经停留了一段时间。我计划实施张的相机校准算法(不使用Opencv库函数)。现在根据我的理解,为了计算相机内在参数,我需要计算Homography矩阵' H' (H = K [R | t]),它需要3D-2D点对应计算(因为每个pt。对应产生2个eqs。我们需要12个未知数至少6个),然后是SVD矩阵以获得相机矩阵' K'。现在对我来说很难的部分是获得这些3D-2D pt。对应。请纠正我,如果我错在这里,但这是否意味着我需要使用Harris角点检测算法找到角落,导致像素坐标中的棋盘角落,并设置3D物理点的原点(0,0)作为某些点通往pt的棋盘图案。对应的地方,让我说一些(x',y')作为像素的图像坐标和(X,Y)作为物理坐标,例如板的中心的原点?

修改

下面是一个代码片段,用于计算归一化的互相关,以获得图像角坐标(由哈里斯角检测算法找到)与自定义世界角坐标之间的点对应关系。

void ncc(Mat &img, vector< vector<Point3f> >phy_corners, vector< vector<Point2f> >img_corners)
{

    float ncc       = 0;
    Size window;
    window.width    = 5;
    window.height   = 5;
    int pad_y       = (window.width - 1)  + img.cols;
    int pad_x       = (window.height - 1) + img.rows;
    int idx_y       = (window.height - 1) / 2;
    int idx_x       = (window.width - 1)  / 2;

    Mat T           = Mat::zeros(5*50+2, 8*50+2 , CV_32FC1);
    Mat I           = Mat::zeros(pad_x, pad_y, CV_32FC1);
    Mat NCC         = Mat::zeros(img.size(), CV_32FC1);

    double numer    = 0.0, denom = 0.0;
    double _I       = 0.0, _T = 0.0;

    // Defining an image with original world corners in world coordinates "This image will be used as a template for Norm-cross-correl."
    for(int i = 0; i < phy_corners[0].size(); ++i){
            T.at<float>(phy_corners[0][i].x , phy_corners[0][i].y) = 255;
    }

    // Defining an image with Harris detected corners in image coordinates "This image will be used for Norm-cross-correl."
    for(int i = 0; i < img_corners[0].size(); ++i){
            I.at<float>(img_corners[0][i].y , img_corners[0][i].x) = 255;
    }


    /******** NCC-COMPUTATION *******/

    for (int i = idx_y; i < (img.rows - idx_y); ++i){
            for (int j = idx_x ; j < (img.cols - idx_x); ++j){

                    for (int k = -idx_y; k <= idx_y; ++k){
                            for (int l = -idx_x; l <= idx_x; ++l){

                                    _I += I.at<float>(i+k, j+l);
                                    _T += T.at<float>(idx_y+k, idx_x+l);

                            }
                    }

                    _I /= (window.width * window.height);
                    _T /= (window.width * window.height);

                    for (int k = -idx_y; k <= idx_y; ++k){
                            for (int l = -idx_x; l <= idx_x; ++l){

                                    numer += (I.at<float>(i+k,j+l) - _I)*(T.at<float>(idx_y + k,idx_x + l) - _T);

                                    denom += pow((I.at<float>(i+k,j+l) - _I), 2)*pow((T.at<float>(idx_y + k,idx_x + l) - _T),2);
                                    denom = sqrt(denom);
                            }
                    }

                    NCC.at<double>(i-idx_y,j-idx_x) = (numer) / (denom) ;

            }
    }

}

0 个答案:

没有答案
相关问题