计算并使用opencv失真参数的逆

mnowg1ta  于 2021-07-14  发布在  Java
关注(0)|答案(1)|浏览(438)

所以基本上我想找出,对于我在这里所做的校准,反转失真参数是什么。
注意:我知道我们可以执行不失真,然后使用重Map来完成我在下面所做的工作,但我的目标是能够找出实际的反转失真参数,并使用它们来扭曲其他图像,而不仅仅是能够还原cv2.undistort()所做的事
概述:
我尝试过传递失真参数的否定:


# _, mat, distortion, _, _ = cv2.calibrateCamera(...)

# undistorted_image = cv2.undistort(with distortion)

# redistorted_image = cv2.undistort(with np.negative(distortion))

理论上,我在想,如果重新扭曲的图像与原始图像相似,那么 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)

结果是:
(左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]

利用上述畸变参数对未畸变图像进行畸变处理的效果也不好,看起来与上述结果非常相似。
所以,这让我们想到:
为什么正态失真的影响总是压倒负的np(失真)或其他什么?
所有的扭曲都是这样的吗(负值不等于相反的效果)
如何得到实际相反的畸变参数?

7vhp5slm

7vhp5slm1#

恐怕你做错了。已校准的opencv失真模型从失真的图像坐标计算未失真和标准化的图像坐标。它是一个非线性模型,所以反演它需要求解一个非线性(多项式)方程组。
仅在单参数纯径向畸变的情况下,即当唯一的非零畸变参数为k1时,r^2的系数才存在闭式(参数)解。在这种情况下,模型反演方程简化为r中的一个立方方程,然后可以使用cardano的立方解公式来表示反演模型。
在所有其他情况下,使用各种算法求解非线性方程组,以数值方式反转模型。opencv使用迭代的“假位置”方法。
因为您想使用逆模型来消除一组图像的失真(这是正常的用例),所以应该使用initundortorrectitymap一次性地计算图像的不失真解决方案,然后将其传递给每个图像以重新Map以实际消除图像的失真。
如果你真的需要逆模型的参数模型,我的建议是用一对高阶多项式或薄板样条函数来近似initundortrectitymap返回的Map。

相关问题