我一直在尝试使用OpenCV的相机校准套件使鱼眼镜头的图像失真(如果相关,我正在使用GoPro)。我已经完成了大部分流程,并且可以生成未失真的图像。但是,在使用重映射时,未失真的图像是“有效矩形”-换句话说,返回的图像是原始图像的裁剪版本,以避免未失真帧中固有的弯曲黑色边框。
我试图使用getOptimalNewCameraMatrix()纠正这种情况,但结果很奇怪。我希望你们中的一个能阐明我的问题。
我目前按以下方式校准相机:
double error = calibrateCamera(worldPoints, sensorPoints, process_size, cameraMatrix, distCoeffs, rvecs, tvecs, calibration_flags);
生成我需要的cameraMatrix。这部分工作正常(我认为),因为如果我先通过initUndistortRectifyMap()然后再通过remap()运行它,则会得到一个有效的图像。但是,我正在寻找完整的图像,因此,我要做的下一件事是尝试按以下方式校正我的cameraMatrix:
int alpha = 1;
cameraMatrix_corr = getOptimalNewCameraMatrix(cameraMatrix, distCoeffs, image.size(), alpha);
然后,我生成X和Y映射以进行重新映射,如下所示(这是直接从OpenCV 2.0 Cookbook借来的,因此我相当有信心它也可以工作)。
initUndistortRectifyMap(
cameraMatrix_corr, // computed camera matrix
distCoeffs, // computed distortion matrix
Mat(), // optional rectification (none)
Mat(), // camera matrix to generate undistorted
image.size(), // size of undistorted
CV_32FC1, // type of output map
map1, map2); // the x and y mapping functions
最后,我重新映射了我的形象!
// Apply mapping functions
remap(image, undistorted, map1, map2, INTER_LINEAR);
到目前为止,这是我的结果。如果我使用alpha = 0(不更改矩阵),我将得到合理的结果(尽管被裁剪)。
如果我使用alpha = 1,我认为应该给我一张图像,每个原始像素都映射到新图像,我得到以下信息:
所以,我的问题是:我在做错什么,为什么我不能仅仅从校准中得到未裁剪,未失真的图像?
谢谢大家的支持,这是我在这里的第一个问题,但我尝试尽可能地完善。让我知道我是否以某种方式搞砸了!
最佳答案
我相信校正相机矩阵不是您不应该做的事情,因为那样会使相机矩阵看起来没有失真。
如果您不想“丢失”图像信息,则最好将 map 在x和y中移动,然后将图像映射到更大的图像。这是因为当不失真时,角落中的像素将向外移动以校正图像。
请记住,鱼眼镜头畸变很大,即使使用正确的代码也可能无法完全矫正。