implementation calibration (zhang) homography problem [closed]

asked 2019-04-01 03:39:59 -0500

Horst gravatar image

updated 2019-04-03 08:52:03 -0500

Hey guys,

i've started to implement zhangs algorithm for a camera-calibration(2D-Rig). Now i've got a fundamental issue at the beginning. I think i'm getting a wrong homography.This can be seen by looking at the image. The red dots are the detected corners by findChessboardCorners() and the blue circles are a transformation (homography) by the 3D-Points to the image-points.image description

I dont know what the problem could be, because the Design-matrix(the matrix to solve homogeneous equation system with svd and so get the homography vec) seems to be right (but i also attach a screenshot of the matrix). The width and height of a square a 20mm. Image size 3200x2400.! Design Matrix: image description

Could anybody pls tell me what the issue may be? I dont have any clue, but i think the computations of the svd should be correct because ive checked it with other online-svd-calulators.

Thanks

cv::Mat calib_img_copy = calibImg->clone();
    //detected corners is output of findChessBoardCorners()
cv::Mat homogenous_image(3, m_detectedCorners.rows,CV_32FC1);
cv::Mat homogenous_world(3, m_detectedCorners.rows, CV_32FC1);

char counter = 0;   char image_row = 1; char image_col = 1;

    //Writes matrices (2D and 3D-Coordinates without z) in desired form
for (int i = 0; i < m_detectedCorners.rows; i++)
{
    cv::Point2f k(m_detectedCorners.at<float>(i,0), m_detectedCorners.at<float>(i, 1));
    cv::circle(calib_img_copy, k, 2, cvScalar(0, 0, 255), 2, 1);

    //put the detected corners in homogeneous form into vector
    homogenous_image.at<float>(0, i) = k.x;
    homogenous_image.at<float>(1, i) = k.y;
    homogenous_image.at<float>(2, i) = 1.0f;

    homogenous_world.at<float>(0, i) = 20*image_col;
    homogenous_world.at<float>(1, i) = 20*image_row;
    homogenous_world.at<float>(2, i) = 1.0f;

    image_col++;

    if (counter == 14)
    {
        image_row++;
        image_col = 1;
        counter = 0;
    }
    counter++;
}

m_homogenous_image = homogenous_image;
m_homogenous_world = homogenous_world;

    //Gets design Matrix, with it the homogeneous equation system can be solved
cv::Mat A_01 = getDesignMatrix_camera(m_homogenous_image, m_homogenous_world);

cv::Mat H_01 = solve_dlt(A_01);   //desired homography
cv::Mat converted = H*m_homogenous_world;    //calculate the "projected 3D Points"

   //draw homogeneous coordinates / convert them to inhomogen
for (int i = 0; i < m_homogenous_world.cols; i++)
{
    float kl = converted.at<float>(2, i);
    cv::Point2d h(converted.at<float>(0, i) / kl, converted.at<float>(1, i) / kl);

    cv::circle(calib_img_copy, h, 5, cvScalar(255, 0, 0), 3);
}
cv::namedWindow("Detected Points", CV_WINDOW_KEEPRATIO);
cv::imshow("Detected Points", calib_img_copy);
cv::waitKey();

cv::Mat cComputerVision::getDesignMatrix_camera(cv::Mat& points2D, cv::Mat& points3D) {

  //should write the matrix as shown in the upper picture
cv::Mat base = points2D;
cv::Mat attach = points3D;
cv::Mat design = cv::Mat::zeros(base.cols * 2, 9, CV_32FC1);

int indx;

for (int i = 0; i < base.cols; ++i)
{
    indx = i * 2;

    for (int j = 0; j < 3; ++j)
    {
        design.at<float>(indx + 1, j + 3) = design.at<float>(indx, j) = -base.at<float>(2, i) * attach.at<float>(j, i);
        design.at<float>(indx, 6 + j) = base.at<float>(0, i) * attach.at<float>(j, i);
        design.at<float>(indx + 1, 6 + j) = base.at<float>(1, i) * attach.at<float>(j, i);
    }
}
return design;

}

cv::Mat cComputerVision::solve_dlt(cv::Mat& A) {

cv::SVD svd(A, cv::SVD::FULL_UV);

cv::Mat H ...
(more)
edit retag flag offensive reopen merge delete

Closed for the following reason duplicate question by Horst
close date 2019-04-03 14:36:12.651298

Comments

Post your code.

swebb_denver gravatar imageswebb_denver ( 2019-04-02 15:08:00 -0500 )edit

Is that printed in a rigid paper? Because it doesn't look so! To start in the best way, I suggest you to print the chessboard in high quality and rigid surface, or at least, attach this paper to something rigid! This will doesn't fix your problem, but is a good start :)

HYPEREGO gravatar imageHYPEREGO ( 2019-04-03 10:11:35 -0500 )edit

I haven't had a chance to look at the code yet, but I did examine the image more closely. One thing that I noticed is that the grid in the calibration target (red circles) is 9x13 = 117 points, but the transformed grid (blue circles) is 8x14 with the top row having 15 dots, and a small bottom row having 4 dots. This gives the same total (117 points) but the structure is different. I would start by figuring out what this issue is and fixing it first. It's possible it is related to (or will shine the light on) your underlying problem.

swebb_denver gravatar imageswebb_denver ( 2019-04-03 10:58:39 -0500 )edit

**, i should have had a closer look to that design matrix..you are completly right, there was a mistake with the dots (mistake in writing my 3D-Point array in the for-loop)..thank you :), stupid mistake

Horst gravatar imageHorst ( 2019-04-03 14:36:00 -0500 )edit

unfortunately closed the question with the wrong reason -.-

Horst gravatar imageHorst ( 2019-04-03 14:37:10 -0500 )edit