Undistort function is cropping photo

I am running an undistort routine in my code. It is undistorting but the image is being cropped. I have tried the intrinsic matrix Fx, Fy (0,0) & (1,1) from the camera calibration program and also Fx = 1, Fy = 1. Still cropped.

Is this normal? If not what can I do to fix?

1 Like

you’re gonna have to provide details.

Ok so my app takes a single shot and sometimes video of a scene. The camera is about 130 degrees fisheye and I use the code to snap about 50 snaps of a checker board test pattern of 9 x 6 internal corners. I calibrate with

calibrateCamera(object_points, image_points, gray_image.size(), intrinsic, distCoeffs, rvecs, tvecs)

and saved. I then display the original image and the undistorted side by side.

Mat imageUndistorted;
			while (1)
			{
				undistort(gray_image, imageUndistorted, intrinsic, distCoeffs);

				imshow("distorted image", gray_image);
				imshow("undistorted image", imageUndistorted);
				waitKey(1);
                          }

Is it possible the sensor formats are different where the optical format of the lens is oversized?

imageUndistorted is cropped but undistorted.
I then migrate the results to other apps. For example:

double	CV_CX = 388.7006986754312,
		CV_CY = 256.263330213388,
		CV_FX = 251.2948616331513,
		CV_FY = 251.7462825743613;

	cv::Mat cam_intrinsic(3, 3, CV_64FC1);
	cam_intrinsic.at<double>(0, 0) = CV_FX;
	cam_intrinsic.at<double>(1, 0) = 0.0;
	cam_intrinsic.at<double>(2, 0) = 0.0;

	cam_intrinsic.at<double>(0, 1) = 0.0;
	cam_intrinsic.at<double>(1, 1) = CV_FY;
	cam_intrinsic.at<double>(2, 1) = 0.0;

	cam_intrinsic.at<double>(0, 2) = CV_CX;
	cam_intrinsic.at<double>(1, 2) = CV_CY;
	cam_intrinsic.at<double>(2, 2) = 1.0;
	// new coeffs 11.29.19

	double	CV_K1 = -0.2625519217437085,
		CV_K2 = 0.06420791311470325,
		CV_P1 = -0.0004198556583919676,
		CV_P2 = -0.001233205211600967,
		CV_P3 = -0.006391088209028103;

	cv::Mat distCoeffs(5, 1, CV_64FC1);
	distCoeffs.at<double>(0) = CV_K1;
	distCoeffs.at<double>(1) = CV_K2;
	distCoeffs.at<double>(2) = CV_P1;
	distCoeffs.at<double>(3) = CV_P2;
	distCoeffs.at<double>(4) = CV_P3;

Thanks for the reply. Hope this will help.

Could it be that the sensor formats are different where one is oversized creating both the circular cropping and the zoom effect?

Poor quality is just temporary.

there’s a special fisheye submodule

Ok, so I started digging into the fisheye submodule. So far this is my test code:

while (1)
						{
							Mat mapx = Mat(size, CV_32FC1);
							Mat mapy = Mat(size, CV_32FC1);
							Mat R = Mat::eye(3, 3, CV_32F);

							
							cv::fisheye::initUndistortRectifyMap(cam_intrinsic, distCoeffs, R, cam_intrinsic, size, CV_32FC1, mapx, mapy);
							
							Mat t = single_image.clone();
							cv::remap(single_image, t, mapx, mapy, INTER_LINEAR);
							
							//The 4 distortion coefficients of the camera : k1, k2, k3, k4
						
							cv::imshow("undist", t);
							waitKey(1);
							
						}

The function cv::fisheye::initUndistortRectifyMap requires 4 K distortion coefficients: K1, K2, K3, K4. I am bringing K1, K2, P1, P2, P3. (at beginning of post).

double	CV_K1 = -0.2625519217437085,
		CV_K2 = 0.06420791311470325,
		CV_P1 = -0.0004198556583919676,
		CV_P2 = -0.001233205211600967,
		CV_P3 = -0.006391088209028103;

How do I resolve the distCoeffs issue?