计算并使用 OpenCV 畸变参数的逆

vwe*_*uzy 1 python opencv computer-vision distortion camera-calibration

所以基本上我想知道我所做的校准的反转失真参数是什么,如下所示

注意:我知道我们可以执行不失真,然后使用重新映射来执行我在下面所做的操作,但我的目标是能够找出实际的反转失真参数并使用它们来扭曲其他图像,而不仅仅是能够恢复 cv2.unactor() 的作用


概述:

我尝试传递失真参数的否定:

# _, mat, distortion, _, _ = cv2.calibrateCamera(...)
# undistorted_image = cv2.undistort(with distortion) 
# redistorted_image = cv2.undistort(with np.negative(distortion))
Run Code Online (Sandbox Code Playgroud)

理论上,我在想,如果重新扭曲的图像与原始图像相似,那么np.negative(distortion)参数就是我正在寻找的,但结果证明是错误的。


我实际使用的方法:

def save_undistorted_images(image, matrix, distortion):
    test_image_su = cv.imread(image)
    height, width = test_image_su.shape[:2]
    new_camera_mtx, roi = cv.getOptimalNewCameraMatrix(matrix, distortion, (width, height), 1, (width, height))

    distortion_u = np.negative(distortion)

    # unsure if this line helps
    new_camera_mtx_inv, roi = cv.getOptimalNewCameraMatrix(matrix, distortion_u, (width, height), 1, (width, height))

    # undistort the image
    undistorted_image = cv.undistort(test_image_su, matrix, distortion, None, new_camera_mtx)
    cv.imwrite('undistorted_frame.png', undistorted_image)

    # redistort trying to get something like original image (image_test_su) 
    distorted_image = cv.undistort(undistorted_image, matrix, distortion_u, None, new_camera_mtx_inv)
    cv.imwrite('redistorted_frame.png', distorted_image)

Run Code Online (Sandbox Code Playgroud)

结果:

(左a:原始)(右b:未失真)

在此输入图像描述 在此输入图像描述

(左c : 使用 ) 扭曲np.negative(distortion)(右d :使用)重新扭曲未扭曲的图像np.negative(distortion))

在此输入图像描述 在此输入图像描述

这里的图像 d 基本上是 c 在 b 上执行的,我期望它类似于 a

为什么b在这里压倒了c的效果?


我尝试过的其他计算逆的方法:

以下是我对这篇论文的python实现

    distortion_u = distortion

    k1 = distortion_u[0][0]
    k2 = distortion_u[0][1]
    k3 = distortion_u[0][4]

    b1 = -1 * k1
    b2 = 3 * (k1 * k1) - k2
    b3 = (8 * k1 * k2) + (-1 * (12 * (k1 * k1 * k1))) - k3
    
    # radial:
    distortion_u[0][0] = b1
    distortion_u[0][1] = b2
    distortion_u[0][4] = b3
   
    # tangential: 
    #distortion_u[0][2] = -1 * distortion_u[0][2]
    #distortion_u[0][3] = -1 * distortion_u[0][3]
Run Code Online (Sandbox Code Playgroud)

使用上述畸变参数对未畸变图像应用畸变的结果也不好,看起来与上面的结果非常相似。


所以,这让我们想到:

为什么正常失真的效果总是压倒np.负(失真)或其他什么?

所有的失真都是如此吗?(负值并不等于相反的效果)

如何得到实际上相反的畸变参数?

Fra*_*ari 6

就怕你做错了。您已校准的opencv 畸变模型可根据畸变图像计算未畸变和归一化的图像坐标。它是一个非线性模型,因此对其进行反演涉及求解非线性(多项式)方程组。

据我所知,封闭形式(参数)解仅适用于单参数纯径向畸变的情况,即当唯一的非零畸变参数为 k1(即 r^2 的系数)时。在这种情况下,模型反演方程简化为 r 中的三次方程,然后您可以使用卡尔达诺三次方程的解公式来表达反演模型。

在所有其他情况下,人们都会使用各种算法来求解非线性方程组,从而对模型进行数值反转。OpenCV 使用迭代“假位置”方法。

由于您想要使用逆模型来对一组图像进行去畸变(这是正常的用例),因此您应该使用initUn DistaultRectifyMap一次性计算图像的去畸变解,然后将每个图像的去畸变解传递给重新映射以实际消除图像扭曲。

如果您确实需要逆模型的参数模型,我的建议是考虑使用一对高阶多项式或薄板样条来近似 initUn DistorifyMap 返回的映射。