我正在尝试了解如何仅在图像的子集上应用cv2.undistort
函数。
相机校准是通过cv2.findChessboardCorner
完成的,它似乎工作得很好。然而,我发现不失真的速度非常慢,在1080x1920的图像上平均约为每秒9帧。为了这个项目的目的,我只对图像的固定子集感兴趣,通常是像img[100:400]
这样的东西。
解决这个问题的好方法是什么?只有当需要100像素的条纹时,才不破坏整个图像似乎是浪费。
来自文档:
函数只是cv::initUnstortRectifyMap(带单位R)和cv::remap(带双线性插值)的组合。有关正在执行的转换的详细信息,请参见前一个函数。
因此,通过在循环中调用Undeficity,您可以一遍又一遍地重新计算未失真映射-没有缓存,而且它们的计算成本很高,因为它涉及到为每个像素求解多项式方程。IIUC您的校准是固定的,所以您应该使用initUnstortRectifyMap()只计算一次,然后将映射传递到主循环中的remap()。
你描述的那种"裁剪"是可行的,但它可能需要一些工作和少量实验,因为OpenCV使用的未失真贴图与未失真的图像1:1对应,并存储像素(矢量)偏移。这意味着您需要裁剪出与您关心的图像矩形相对应的贴图部分,然后编辑它们的值,即从未失真图像到失真图像的x和y偏移。具体来说,您需要对它们应用2D平移的反向,该平移将您关心的矩形带到图像画布的左上角。然后,您应该能够调用remap(),将一个未失真的裁剪矩形大小的空图像作为目标图像传递。
总而言之,我会首先尝试第一个推荐(不要称之为无侵权,将地图生成与重新映射分开),只有在真的跟不上帧速率的情况下才会尝试第二步。