OpenCV:对图像的部分进行去畸变

3
我正在尝试理解如何仅在图像的子集上应用cv2.undistort函数。
通过cv2.findChessboardCorner进行了相机校准,并且似乎工作正常。然而,我发现失真校正非常慢,在1080x1920图像上平均约为9 fps。对于项目的目的,我只对固定的图像子集感兴趣,通常类似于img[100:400]
如何解决这个问题?在需要100像素条纹时仅对整个图像进行失真校正似乎是浪费的。

也许您可以先裁剪图像,然后对其运行去畸变函数。 - v.coder
@v.coder 这是我尝试的第一件事 - 如果你裁剪图像,失真校正将无法很好地工作(甚至可能使情况更糟)。 - ymoiseev
1个回答

2

docs中:

该函数是cv :: initUndistortRectifyMap(使用统一的R)和cv :: remap(使用双线性插值)的组合。有关执行的转换的详细信息,请参见前一个函数。

因此,在循环中调用undistort会反复重新计算未失真的映射 - 没有缓存,它们的计算是昂贵的,因为它涉及为每个像素解决多项式方程。如果我理解正确,您的校准是固定的,因此您应该仅使用initUndistortRectifyMap()计算一次它们,然后将地图传递给主循环中的remap()。

你所描述的“裁剪”是可行的,但可能需要一些工作和小的实验,因为OpenCV使用的去畸变映射与未经扭曲的图像具有1:1对应关系,并存储像素(向量)偏移量。这意味着您需要裁剪地图部分,相应地对应于您关心的图像矩形,然后编辑它们的值,这些值是从未经扭曲到扭曲图像的x和y偏移量。具体来说,您需要将带有您关心的矩形的二维平移的逆应用于它们,以将其带到图像画布的左上角。然后,您应该能够调用remap(),将未经扭曲的裁剪矩形大小的空白图像作为目标图像。
总的来说,我首先会尝试第一个建议(不要调用undistort,将map生成与remapping分开),只有当真的跟不上帧率时才会尝试第二步。

好的,谢谢。仅使用您的第一个建议就足以实时消除畸变了。 - ymoiseev

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接