5.24. 极坐标变换

极坐标用相对于参考方向的角度和相对于所选中心的距离来标识每个像素,取代了相对于左上角原点的水平和垂直偏移。这种表示之所以有价值,源于一个恒等关系:绕所选中心的旋转变成了沿角度轴的平移,这使得旋转不变算法可以在一个比直接处理旋转简单得多的参数空间中进行搜索。linpolar()logpolar() 负责执行这种重投影。

5.24.1. 两种方法

linpolar() 使用线性距离轴执行从笛卡尔坐标到极坐标的重投影。每个输出列对应绕中心的一个固定角度;每个输出行对应到中心的一个固定距离。

img.linpolar()

logpolar() 使用对数距离轴执行同样的重投影。角度的处理方式相同;不同之处在于距离沿输出的行向下呈指数增长,而非线性增长。这种差异之所以重要,是因为极坐标揭示的第二个几何恒等关系:绕所选中心对源图像进行缩放变成了沿距离轴的平移——但仅当该轴为对数轴时成立。在线性距离轴下,缩放会拉伸极坐标图像;而在对数距离轴下,缩放只会使其平移一个固定量。

img.logpolar()

这两种方法都接受 x=y= 关键字参数,用于以源像素坐标设置极坐标重投影的中心,默认值分别为图像宽度的一半和图像高度的一半。中心的选择很重要:围绕错误的点进行极坐标变换最终会使内容以破坏旋转/平移恒等关系的方式被打乱。

三个面板排成一行。最左边 是一幅笛卡尔源图像,显示一个 钟面——两个同心圆,外缘 以 30 度的倍数分布着十二个 刻度标记,还有一根指向某个 方向的指针。中间的面板显示 该源图像的 linpolar 重投影: 一幅矩形输出图像,其中十二个 刻度标记表现为沿顶行均匀 分布的竖线,两个同心圆 表现为位于不同垂直位置的 两条水平线,钟面指针表现为 一条位于其在源图像中角度 所对应位置的竖线。最右边的 面板显示 logpolar 重投影: 沿水平轴有相同的角度分布, 但由于距离轴是对数的,内圆 与外圆之间的间隔被压缩了。

linpolar()logpolar() 重投影后的钟面。源图像中的同心圆在输出中变为水平线;角度刻度标记变为沿角度轴均匀分布的竖线。对数极坐标变体压缩了径向间距。

5.24.2. 何时使用哪一种

linpolar()logpolar() 之间的选择,取决于应用需要哪种不变性。若仅需旋转不变性——即检测同一场景出现在两帧中,第二帧旋转了一个未知角度——那么 linpolar() 就足够了:旋转在极坐标图像中变成水平偏移,而像 find_displacement() 这样仅处理平移的匹配器可以将该偏移的大小还原为角度。当尺度不变性也很重要时——即第二帧既被旋转被缩放——logpolar() 会将两个未知量都化为平移:水平方向对应旋转,垂直方向对应尺度。

这就是构建一个对旋转和尺度变化都具有鲁棒性的跟踪器的标准方法:将参考帧和每一帧实时画面绕同一中心重投影到对数极坐标,对这一对图像运行 find_displacement(),然后从结果中读取 rotationscale 字段。

5.24.3. 展开圆形特征

极坐标变换的另一种用途是展开图像中本身呈圆形的特征。钟面、仪表盘、设计上就是圆形的检测目标——所有这些在极坐标投影中都会变成线性的,而这种形式是大多数算法更容易处理的。

上图直接展示了这一点:钟面上的十二个刻度标记,在笛卡尔坐标中沿圆周均匀分布,在极坐标图像中变为十二条均匀分布的竖线。在极坐标图像中围绕任意一个刻度标记画一个矩形,便可确定该刻度标记的位置,而无论拍摄时钟面被旋转到哪个方向。在极坐标图像上运行模板匹配器,可以在一次遍历中找到每一个刻度标记。

5.24.4. 逆映射

reverse=True 执行正向极坐标投影的逆运算:给定一幅极坐标图像,生成其极坐标投影所对应的那幅笛卡尔图像。应用先调用正向形式以在极坐标下运行算法,然后调用逆向形式将结果投影回笛卡尔坐标,供需要查看它的下游环节使用。

最常见的用法是修改极坐标图像再投影回去:应用于极坐标图像的滤波器——一种在极坐标意义上跨角度模糊但保留径向结构的水平平滑——会生成一幅在角度方向上被模糊的笛卡尔结果,而这是笛卡尔滤波器无法直接做到的。