python - 如何使用 OpenCV 或任何其他库对图像应用失真?
问题描述
我正在执行校准,如此处所示,但使用 cv.CALIB_RATIONAL_MODEL。
我使用了大约 40 张图像,我的平均重投影误差(由 cv2.calibrateCamera 计算)始终小于 0.5。
现在,我希望能够拍摄任何其他图像并将其应用于我从校准中获得的失真。
我知道我可以使用我在校准过程中保存的角来计算和重新扭曲校准图像,但我想只使用我可以保存和使用的内在和/或外在参数对完全不同的图像应用失真。
可能吗?
我试图传递np.negative(distortion)
希望cv.undistort()
它不会因负值而失真,所以它实际上会失真,但它不起作用并且给我完全搞砸的结果。
我尝试将其他(一、二、三)线程上的答案从 c++ 转换为 Python,并通过研究失真背后的理论来创建自己的函数,但它不起作用。
我可以利用任何其他库或理论来解决这个问题吗?
解决方案
OpenCV 不提供图像扭曲功能,但您可以自己实现。您只需要:
- 内在参数(相机矩阵和失真系数)和失真图像的大小。
表示为cam_mtx
、dis_cef
和image_size
。 - 内在参数(相机矩阵)和未失真图像的大小。
表示为cam_mtx_ud
和image_size_ud
。 - 失真和未失真图像之间的校正变换(旋转矩阵)。
表示为R
。
校正变换矩阵R
可以通过 计算stereoRectify()
,但在单相机系统中,它通常是恒等式(您可以只使用 empty Mat
)。
回想一下对图像进行不失真处理的过程,它需要两个步骤:
- 计算校正图:
initUndistortRectifyMap(cam_mtx, dis_cef, R, cam_mtx_ud, image_size_ud, CV_32FC1, map_x, map_y)
- 重新映射图像以不失真:
remap(image, image_ud, map_x, map_y, INTER_LINEAR);
校正图 (map_x
和map_y
) 描述了从未失真图像到失真图像的像素坐标图。有了它们,未失真图像上的每个像素都可以在失真图像上找到它的位置,然后通过插值检索像素值。就是这样remap
工作的。
因此,要生成不失真的校正图,您需要循环目标(不失真)图像的像素并扭曲点。
现在,在图像上应用失真就像不失真一样。
您需要通过在目标(扭曲)图像的像素上循环并不扭曲点来生成“扭曲贴图” 。然后,使用remap
应用失真。
这是代码:
Mat map_x = Mat(image_size, CV_32FC1);
Mat map_y = Mat(image_size, CV_32FC1);
vector<Point2f> pts_ud, pts_distort;
for (int y = 0; y < image_size.height; ++y)
for (int x = 0; x < image_size.width; ++x)
pts_distort.emplace_back(x, y);
undistortPoints(pts_distort, pts_ud, cam_mtx, dis_cef, R, cam_mtx_ud);
for (int y = 0; y < image_size.height; ++y) {
float* ptr1 = map_x.ptr<float>(y);
float* ptr2 = map_y.ptr<float>(y);
for (int x = 0; x < image_size.width; ++x) {
const auto& pt = pts_ud[y * image_size.width + x];
ptr1[x] = pt.x;
ptr2[x] = pt.y;
}
}
Mat image_distort;
remap(image_ud, image_distort, map_x, map_y, INTER_LINEAR);
我不擅长python,所以我用C++编写了代码。对此感到抱歉,但我认为代码不难阅读。
推荐阅读
- python - 如何纠正 minimumsq() 缺少 1 个必需的位置参数:'x0'
- javascript - 单击按钮时,我正在尝试将输入的内容保存到本地存储中。我究竟做错了什么?
- python - 如何从 BeautifulSoup 的跨度中获取数据?
- android - 如何在 android studio arctic fox 上设置 LLDB
- javascript - isInViewport() 辅助方法不接受多个元素。抛出错误:不是函数。需要 .find() vanilla JS 等价物
- android - 无法在颤动中写入文件
- mongodb - 在一个区域内创建一个视图
- python - 如何以识字的方式从网站中的多个URL中提取特定的表格数据(div\tr\td)到CSV(带示例)
- python - 有没有办法根据 Python 中的一列或多列中具有相似值的行来选择表中的某些行?
- javascript - 文件选择器侧边栏通信错误