在OpenCV中getOptimalNewCameraMatrix有什么作用?

voase2hg  于 2022-11-15  发布在  其他
关注(0)|答案(4)|浏览(174)

我正在按照教程对相机进行标定,我已经了解了用棋盘来求相机的内参数和畸变系数的整个过程,但我不明白的是,为什么在那之后我们还要叫getOptimalNewCameraMatrix?特别是alpha参数,我已经看过文档了,但可能是因为缺乏相机标定的知识,我真的不明白。
这是原始图像。x1c 0d1x
下面是上述图像的未失真图像的示例(使用OpenCV的undistort)。
对于这一个,我只是直接使用获得的固有相机和失真系数来消除图像失真。

对于这一个,我在恢复扭曲之前用alpha=0(左)和alpha=1(右)调用getOptimalNewCameraMatrix

从我所看到的,getOptimalNewCameraMatrix是保留原始图像而不丢失信息?我希望有人能解释这个函数真正的作用。
如果我想用来自这台相机的图片构建一个3D模型,我应该首先调用getOptimalNewCameraMatrix吗?

  • 谢谢-谢谢
a14dhokn

a14dhokn1#

我也有同样的问题。我在网上搜索找不到明确的直接答案,但在运行了一些测试后,我知道X1 M0 N1 X函数实际上为用户做了什么。
我使用了openCV calibration tutorial中提到的相同图像(您可以在here中找到名为left01.jpg到left14.jpg的图像(实际上left10.jpg似乎丢失了,但这很好))校准步骤后-假设正方形大小为30毫米-在教程中,我得到了这个相机矩阵:

mtx = [[534.07088364   0.         341.53407554]
       [  0.         534.11914595 232.94565259]
       [  0.           0.           1.        ]]

另一方面,使用命令newcameramtx, roi = cv2.getOptimalNewCameraMatrix(mtx, dist, (w,h), 1, (w,h))获得的新摄像机矩阵为

newcameramtx = [[457.92434692   0.         342.55548195]
                [  0.         456.2421875  233.34661351]
                [  0.           0.           1.        ]]

注意这里的alpha=1,但它可能是[0,1]之间的另一个值。使用另一个值将给予不同的newcameramtx
到目前为止没有什么新的。然后,我“未扭曲”所有使用的图像在校准和保存到两个新的文件夹。一个文件夹(让我们称之为第一文件夹)直接使用获得的固有相机填充无失真图像(即mtx)和失真系数(dist),另一个(我们称之为第2个文件夹)填充了使用newcameramtx和相同失真系数的未失真图像(dist)。为了明确起见,我分别使用了命令cv2.undistort(img, mtx, dist, None, mtx)cv2.undistort(img, mtx, dist, None, newcameramtx),并将结果图像保存到上述两个文件夹中。在保存之前,我没有使用roi裁剪未失真的图像。结果图像就像您在问题中找到并给出的一样。
然后,使用第一个文件夹中的未失真图像,我重新执行校准过程,并找到以下相机矩阵:
第一次
对第2个文件夹进行相同操作,得到以下摄像机矩阵:
第一个
现在,请注意mtxmtx_1stFoldernewcameramtx_1stFolder之间的距离,同样,请注意newcameramtxmtx_2ndFoldernewcameramtx_2ndFolder之间的距离。
基于这些观察,我的想法是,直接使用获得的相机固有系数和失真系数对图像进行去失真处理不会影响相机矩阵,并且它会相应地返回相同大小的图像,但这些结果图像会丢失一些像素。如果你对丢失的像素没有意见,你可以完全不使用cv2.getOptimalNewCameraMatrix。但是,如果你需要丢失像素中给出的信息,您也可以选择将您的图像反扭曲为相同的图像大小或您想要的任何大小。但是,肯定会破坏你的相机矩阵,你将需要一个新的校准后,新的未失真的图像。cv2.getOptimalNewCameraMatrix函数可以估计新的摄像机矩阵,而无需重新校准。这解释了为什么newcameramtxmtx_2ndFolder彼此非常接近。
这似乎也解释了为什么mtx_2ndFoldernewcameramtx_2ndFolder彼此接近,因为没有太多的东西可以去扭曲(mtx_1stFoldernewcameramtx_1stFolder也是如此)。
到目前为止,我还没有提到每个校准过程的失真系数(dist)。这实际上使我不能说我的想法是肯定的,所以我完全可以对我的想法进行修正。直观地说,我希望第一次校准会有一些失真系数,因为图像明显失真。正如预期的那样,失真系数矢量如下:

dist = [[-0.29297164  0.10770696  0.00131038 -0.0000311   0.0434798 ]]

另一方面,我希望对未失真图像进行校准会给予更少的系数,理想情况下为0,因为所有失真都被理想地去除了。然而,对第一个文件夹进行校准会给出:

dist = [[ 0.00760897 -0.07313015  0.0002162   0.0003522   0.1605208 ]]

第二个文件夹上的校准给出:

dist = [[ 0.00135068 -0.02390678  0.0001996   0.0003413   0.0580141 ]]

对于前三项,结果与期望值一样,在幅度上向零变小,但它们并没有急剧接近0。同样,对于最后两项,系数增加,这与我的期望相反。如果有人知道为什么会出现这种情况,我将非常感谢。

xdnvmnnf

xdnvmnnf2#

如果您想得到与原始图像形状相同的图像,则必须丢失一些像素。
opencv文档中的“alpha”参数描述指出...
自由缩放参数,介于0(未失真图像中的所有像素均有效时)和1(未失真图像中保留所有源图像像素时)之间
对我来说,这意味着如果值为0,所有的像素都将进行几何变换,径向和切向失真将被消除,但图像的几何形状将不正确。
getOptimalNewCameraMatrix用于使用来自具有相同校准的相同相机的不同分辨率。
当我使用getOptimalNewCameraMatrix,然后对返回的感兴趣区域应用裁剪时,我得到了最佳结果。
下面是我用于此目的的python代码片段。

newcameramtx, roi = cv2.getOptimalNewCameraMatrix(mtx, dist, (w, h), 1, (w, h))
mapx, mapy = cv2.initUndistortRectifyMap(mtx, dist, None, newcameramtx, dim, 5)
image = cv2.remap(image, mapx, mapy, cv2.INTER_LINEAR)

x, y, w, h = roi
image = image[y:y + h, x:x + w]

这应该采取你的最后一个图像(针垫一个在右边),并给予你最有用的图像。
我还将undistort方法分为两部分,因为只要从摄像头接收到的新图像具有相同的分辨率,就可以继续调用remap

nsc4cvqm

nsc4cvqm3#

  • 当我们使用原始相机矩阵“mtx”对图像进行去失真处理时,未失真输出图像的视场/焦距与原始图像保持相同,即在本例中为~534。因此,边界处的一些像素丢失。
  • 通过指定自由缩放参数〉0,我们实际上是要求算法缩小一点,以便边界像素也被包括在内。
  • 与源图像相比,这会产生更大的视场和更小的未失真图像焦距
  • 因此,如新矩阵(newcameramtx)中所示,焦距已减少至**~457**(从~534),从而产生缩小效果。
ff29svar

ff29svar4#

正如您自己已经正确认识到的,原则上不需要调用getOptimalNewCameraMatrix函数。但是,使用此函数有一些优点:
1.α = 1。当调用α = 1时,失真图像的所有原始区域也包含在校正图像中。新的摄像机矩阵以这样的方式确定,即失真图像的角点Map到校正图像的角点。这是函数的设计标准。但是,使用alpha = 1有一个缺点,即校正后的图像还包含无效区域,在您的示例中这些区域被着色为黑色。如果您不想使用这些区域,您可以使用函数返回的ROI值。

  1. Alpha = 0。当使用alpha = 0调用时,您将得到一个没有无效区域并尽可能多地保留原始图像内容的图像(考虑到这一条件)。原则上,它包含可以在alpha = 1的图像中选择的矩形区域。因此没有无效区域被确定。alpha = 0的调用生成的图像与中心区域中的原始图像非常相似,具有轻微失真。如果可以不使用外围角区域的信息,我建议使用alpha = 0。

另请参阅https://answers.ros.org/question/392890/why-the-left-3x3-portion-of-projection-matrixp-is-different-from-the-intrinsic-camera-matrixk/

相关问题