python - 计算和使用 OpenCV 失真参数的逆
问题描述
所以基本上我想找出我在这里显示的校准的反转失真参数是什么。
注意:我知道我们可以执行不失真,然后使用重新映射来完成我在下面所做的事情,但我的目标是能够找出实际的反转失真参数并使用它们来扭曲其他图像,而不仅仅是能够恢复 cv2.undistort() 的作用
概述:
我试过传入对失真参数的否定:
# _, mat, distortion, _, _ = cv2.calibrateCamera(...)
# undistorted_image = cv2.undistort(with distortion)
# redistorted_image = cv2.undistort(with np.negative(distortion))
理论上,我在想如果redistorted_image与原始图像相似,那么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.negative(distortion) 或其他任何东西?
所有的失真都是这样工作的吗?(负值不等于反效果)
如何获得实际相反的失真参数?
解决方案
怕你做错了。您校准的opencv 失真模型会根据失真坐标计算未失真和归一化的图像坐标。它是一个非线性模型,因此对其进行反演需要求解非线性(多项式)方程组。
仅在单参数纯径向畸变的情况下,AFAIK 存在封闭形式(参数)解,即当唯一的非零畸变参数为 k1 时,r^2 的系数。在这种情况下,模型反演方程简化为 r 中的三次方程,然后您可以使用 Cardano 的三次求解公式来表达逆模型。
在所有其他情况下,使用各种算法求解非线性方程组,以数值方式反转模型。OpenCV 使用迭代的“错误位置”方法。
由于您想使用逆模型对一组图像进行不失真处理(这是他的正常用例),因此您应该使用initUndistortRectifyMap来一劳永逸地计算图像的不失真解决方案,然后将其传递给每个图像重新映射以实际不扭曲图像。
如果您确实需要逆模型的参数模型,我的建议是研究使用一对高阶多项式或薄板样条线来近似 initUndistortRectifyMap 返回的映射。
推荐阅读
- node.js - 在节点 js 中检查 docker swarm 容器状态
- php - 已经有 MySQL WorkBench,所以在安装 XAMPP 时没有选择 MySQL,如何从 XAMPP 连接到 WorkBench
- arrays - 逆向工程和解释汇编代码
- apache-kafka - 在使用 Flink Stateful 函数时,是否有一种简单的方法来处理来自同一个 kafka 入口主题的多种消息类型
- python-3.x - 这个错误是什么以及如何摆脱它。TypeError:“NoneType”类型的参数不可迭代
- python - TabError:创建函数时缩进中制表符和空格的使用不一致
- javascript - 如何将嵌套表中的问题id与主表匹配
- javascript - 使用猫鼬,如何添加新项目并将数组返回到同一端点
- c++ - 我使用单链表在这个“在列表开头插入节点”中找不到错误
- node.js - 尝试使用 node-postgres 事务时出现问题 - 使用 async/await 的池化客户端