Skip to main content
deleted 1070 characters in body
Source Link

Added

OK, guys, simple mistake. I previously used warpPerspective to warp images instead of restoring. Since it works that way, I didn't read the doc thoroughly. It turns out that if it is for restoring, the flag WARP_INVERSE_MAP should be set. Change the function call to this, and that's it.

warpPerspective(tempImgC, imgC, matPerspective, Size(2500, 2000), WARP_INVERSE_MAP);

Here is the new result image C: enter image description here

The only thing concerns me now is the intermediary tempImgC, which is the image after undistort and before warpPerspective. In some tests with different artificial B s, This image could turn out to be a scaled-up version of B with distortion removed. That means a lot of information is lost in the outter area. And there is not much to use for warpPerspective. I'm thinking maybe to scale down the image in undistort and to scale it up in warpPerspective. But I'm not sure yet how to calculate the correct scale to preserve all the information in B.

Added

OK, guys, simple mistake. I previously used warpPerspective to warp images instead of restoring. Since it works that way, I didn't read the doc thoroughly. It turns out that if it is for restoring, the flag WARP_INVERSE_MAP should be set. Change the function call to this, and that's it.

warpPerspective(tempImgC, imgC, matPerspective, Size(2500, 2000), WARP_INVERSE_MAP);

Here is the new result image C: enter image description here

The only thing concerns me now is the intermediary tempImgC, which is the image after undistort and before warpPerspective. In some tests with different artificial B s, This image could turn out to be a scaled-up version of B with distortion removed. That means a lot of information is lost in the outter area. And there is not much to use for warpPerspective. I'm thinking maybe to scale down the image in undistort and to scale it up in warpPerspective. But I'm not sure yet how to calculate the correct scale to preserve all the information in B.

added 693 characters in body
Source Link

Originally I have a image with a perfect circle grid, denoted as A enter image description here I add some lens distortion and perspective transformation to it, and it becomes B. enter image description here In camera calibration, A would be my destination image, and B would be my source image. Let's say I have all the circle center coordinates in both images, stored in stdPts and disPts.

And here is the result image C,which looks like a scaled-up version of which doesn't deal with the perspective transformation at all. enter image description here

So could someone teach me how to recover A? Thanks. enter image description here

SoAdded

OK, guys, simple mistake. I triedpreviously used warpPerspective to experiment with the scale a little bitwarp images instead of restoring. The codeSince it works that way, I didn't read the doc thoroughly. It turns out that if it is changedfor restoring, the flag WARP_INVERSE_MAP should be set. Change the function call to this, and that's it.

// apply distortion
Mat scale = Mat::eye(3, 3, CV_64F);
intrinsic.copyTo(scale);
scale.at<double>(0,0) /= 1.3;
scale.at<double>(1,1) /= 1.3;
undistort(imgB, tempImgC, intrinsic, distCoeffs,scale);

//apply perspective transform
Mat newIntrinsic;
intrinsic.copyTo(newIntrinsic);
newIntrinsic.at<double>(0,0) /= 1.1;
newIntrinsic.at<double>(1,1) /= 1.1;
        
Mat matPerspective = newIntrinsic*transRot3x3;
warpPerspective(tempImgC, imgC, matPerspective, Size(2500, 2000), WARP_INVERSE_MAP);

AndHere is the result looks better, denoted as new result image C'C: enter image description hereenter image description here

So could someone helpThe only thing concerns me explain whatnow is going on with the scaleintermediary tempImgC, which is the image after undistort and calculatebefore warpPerspective. In some tests with different artificial B s, This image could turn out to be a scaled-up version of B with distortion removed. That means a lot of information is lost in the right scaleoutter area. And there is not much to matchuse for warpPerspective. I'm thinking maybe to scale down the grid sizeimage in Cundistort and to scale it up in warpPerspective. But I'm not sure yet how to calculate the onecorrect scale to preserve all the information in AB? Thanks.

Originally I have a image with a perfect circle grid, denoted as A I add some lens distortion and perspective transformation to it, and it becomes B. In camera calibration, A would be my destination image, and B would be my source image. Let's say I have all the circle center coordinates in both images, stored in stdPts and disPts.

And here is the result image C,which looks like a scaled-up version of A. enter image description here

So I tried to experiment with the scale a little bit. The code is changed to

// apply distortion
Mat scale = Mat::eye(3, 3, CV_64F);
intrinsic.copyTo(scale);
scale.at<double>(0,0) /= 1.3;
scale.at<double>(1,1) /= 1.3;
undistort(imgB, tempImgC, intrinsic, distCoeffs,scale);

//apply perspective transform
Mat newIntrinsic;
intrinsic.copyTo(newIntrinsic);
newIntrinsic.at<double>(0,0) /= 1.1;
newIntrinsic.at<double>(1,1) /= 1.1;
        
Mat matPerspective = newIntrinsic*transRot3x3;
warpPerspective(tempImgC, imgC, matPerspective, Size(2500, 2000));

And the result looks better, denoted as C' enter image description here

So could someone help me explain what is going on with the scale, and calculate the right scale to match the grid size in C to the one in A? Thanks.

Originally I have a image with a perfect circle grid, denoted as A enter image description here I add some lens distortion and perspective transformation to it, and it becomes B enter image description here In camera calibration, A would be my destination image, and B would be my source image. Let's say I have all the circle center coordinates in both images, stored in stdPts and disPts.

And here is the result image C, which doesn't deal with the perspective transformation at all. enter image description here

So could someone teach me how to recover A? Thanks.

Added

OK, guys, simple mistake. I previously used warpPerspective to warp images instead of restoring. Since it works that way, I didn't read the doc thoroughly. It turns out that if it is for restoring, the flag WARP_INVERSE_MAP should be set. Change the function call to this, and that's it.

warpPerspective(tempImgC, imgC, matPerspective, Size(2500, 2000), WARP_INVERSE_MAP);

Here is the new result image C: enter image description here

The only thing concerns me now is the intermediary tempImgC, which is the image after undistort and before warpPerspective. In some tests with different artificial B s, This image could turn out to be a scaled-up version of B with distortion removed. That means a lot of information is lost in the outter area. And there is not much to use for warpPerspective. I'm thinking maybe to scale down the image in undistort and to scale it up in warpPerspective. But I'm not sure yet how to calculate the correct scale to preserve all the information in B.

Tweeted twitter.com/StackRobotics/status/918764396318511104
Source Link

OpenCV get topdown view of planar pattern by using intrinsic and extrinsic from cameraCalibrate

Originally I have a image with a perfect circle grid, denoted as A I add some lens distortion and perspective transformation to it, and it becomes B. In camera calibration, A would be my destination image, and B would be my source image. Let's say I have all the circle center coordinates in both images, stored in stdPts and disPts.

//25 center pts in A
vector<Point2f> stdPts;
for (int i = 0; i <= 4; ++i) {
    for (int j = 0; j <= 4; ++j) {
        stdPts[i * 5 + j].x = 250 + i * 500;
        stdPts[i * 5 + j].y = 200 + j * 400;
    }
}
//25 center pts in B
vector<Point2f> disPts = FindCircleCenter();

I want to generate an image C that is as close as A, from input: B, stdPts and disPts. I tried to use the intrinsic and extrinsic generated by cv::calibrateCamera. Here is my code:

//prepare object_points and image_points
vector<vector<Point3f>> object_points;
vector<vector<Point2f>> image_points;
object_points.push_back(stdPts);
image_points.push_back(disPts);

            
//prepare distCoeffs rvecs tvecs
Mat distCoeffs = Mat::zeros(5, 1, CV_64F);
vector<Mat> rvecs;
vector<Mat> tvecs;


//prepare camera matrix
Mat intrinsic = Mat::eye(3, 3, CV_64F);
            
//solve calibration
calibrateCamera(object_points, image_points, Size(2500,2000), intrinsic, distCoeffs, rvecs, tvecs);


//apply undistortion
string inputName = "../B.jpg";
Mat imgB = imread(imgName);
cvtColor(imgB, imgB, CV_BGR2GRAY)
Mat tempImgC;
undistort(imgB, tempImgC, intrinsic, distCoeffs);


//apply perspective transform
double transData[] = { 0, 0, tvecs[0].at<double>(0), 0, 0,,tvecs[0].at<double>(1), 0, 0,  tvecs[0].at<double>(2) };
Mat translate3x3(3, 3, CV_64F, transData);
Mat rotation3x3;
Rodrigues(rvecs[0], rotation3x3);

Mat transRot3x3(3, 3, CV_64F);
rotation3x3.col(0).copyTo(transRot3x3.col(0));
rotation3x3.col(1).copyTo(transRot3x3.col(1));
translate3x3.col(2).copyTo(transRot3x3.col(2));

Mat imgC;
Mat matPerspective = intrinsic*transRot3x3;
warpPerspective(tempImgC, imgC, matPerspective, Size(2500, 2000));

//write
string outputName = "../C.jpg";
imwrite(outputName, imgC); // A JPG FILE IS BEING SAVED

And here is the result image C,which looks like a scaled-up version of A. enter image description here

So I tried to experiment with the scale a little bit. The code is changed to

// apply distortion
Mat scale = Mat::eye(3, 3, CV_64F);
intrinsic.copyTo(scale);
scale.at<double>(0,0) /= 1.3;
scale.at<double>(1,1) /= 1.3;
undistort(imgB, tempImgC, intrinsic, distCoeffs,scale);

//apply perspective transform
Mat newIntrinsic;
intrinsic.copyTo(newIntrinsic);
newIntrinsic.at<double>(0,0) /= 1.1;
newIntrinsic.at<double>(1,1) /= 1.1;
        
Mat matPerspective = newIntrinsic*transRot3x3;
warpPerspective(tempImgC, imgC, matPerspective, Size(2500, 2000));

And the result looks better, denoted as C' enter image description here

So could someone help me explain what is going on with the scale, and calculate the right scale to match the grid size in C to the one in A? Thanks.