6

我一直在尝试使用 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)

如果我使用 alpha = 1,我认为它应该给我一个图像,每个原始像素都映射到新图像,我得到以下信息:

图像(alpha = 0)

所以,我的问题是:我做错了什么,为什么我不能从校准中获得未经裁剪、不失真的图像?

感谢大家容忍我,这是我在这里的第一个问题,但我试图尽可能完整。让我知道我是否搞砸了!

4

1 回答 1

4

我相信校正相机矩阵不是为了不失真而应该做的事情,因为这会给你一个相机矩阵,就好像没有失真一样。

如果您不想“丢失”图像信息,最好将地图移动到 x 和 y 并将图像映射到更大的图像。这是因为当不失真时,角落中的像素会向外移动以校正图像。

请记住,鱼眼镜头具有很高的失真,即使使用正确的代码也可能无法完全纠正。

于 2012-11-28T09:58:28.390 回答