Original Image from webcam is undistorted. Undistort actually distorts.

My friend and I are doing a sample camera calibration using the webcam on his Alienware laptop. We cannot understand why the original image is undistorted and we get a distorted image when we call undistort with the camera intrinsics. The attached picture shows that the results are backwards from expectations. When he first showed this to me I laughed at him and said he just switched the images by mistake. If so, I can't find how he did it.

DistortedUndistorted.JPG

We used the cpp-example-calibration to get the camera intrinsics:

windows> cpp-example-calibration.exe -w=8 -h=6 -pt=chessboard -n=30 -d=2000 -s=0.13


I know that the 8x6 chessboard expressed in the parameters is different than in the picture. We actually used a huge posterboard sized chessboard to do the calibration and we took the pictures with a smaller board that is easier to hold. The side by side pictures are meant to show where distortion exists. They were not a part of calibration.

The calibration resulted in this data:

    %YAML:1.0
calibration_time: "Thu Oct 20 20:25:14 2016"
image_width: 640
image_height: 480
board_width: 8
board_height: 6
square_size: 1.2999999523162842e-01
aspectRatio: 1.
flags: 2
camera_matrix: !!opencv-matrix
rows: 3
cols: 3
dt: d
data: [ 8.4125490263403651e+02, 0., 3.1179038300397195e+02, 0.,
8.4125490263403651e+02, 1.2247027042886921e+02, 0., 0., 1. ]
distortion_coefficients: !!opencv-matrix
rows: 5
cols: 1
dt: d
data: [ 2.4482174065616116e-01, -5.9553709824779455e-01,
-8.4895736453074480e-02, 7.9072223119576700e-03,
1.3055992934480314e+00 ]
avg_reprojection_error: 8.5143610263133207e-01


Then we used this code to capture one frame of data from the camera and show the original capture and the results of applying undistort(). The hard-coded values are the cut/pasted camera intrinsics.


VideoCapture inputVideo;

inputVideo.open( 0 );
inputVideo.grab();
Mat image;
inputVideo.retrieve( image );

double intr[ 9 ] = { 8.4125490263403651e+02, 0., 3.1179038300397195e+02, 0.,
8.4125490263403651e+02, 1.2247027042886921e+02, 0., 0., 1. };

cv::Mat intrsc( 3, 3, CV_64F, intr );

double distc[ 5 ] = { 2.4482174065616116e-01, -5.9553709824779455e-01,
-8.4895736453074480e-02, 7.9072223119576700e-03,
1.3055992934480314e+00 };

cv::Mat distoCoeff( 1, 5, CV_64F, distc );

cv::Mat undist;

undistort( image, undist, intrsc, distoCoeff );
imshow( "Distorted Image", image );
imshow( "Undistorted", undist );


I expect that if the captured images from the camera have no distortion that the calibration procedure would result in distortion coefficients that are very near zero. That is not what happened. Yet the re-projection error is pretty small indicating a good calibration.

What is going on?

edit retag close merge delete