假设Canny边缘检测器成功检测到图像中的一条边缘。然后将该边缘旋转θ角,其中原始边缘上一点(x,y)(x,y)
与旋转后边缘上一点(x′,y′)(x′,y′)
之间的关系定义为x′ = xcosθ; y′ = xsinθ;
使用相同的Canny边缘检测器能否检测到旋转后的边缘?
(我认为我们应该考虑到Canny边缘检测器检测边缘仅依赖于其导数的幅度来寻找答案。)
回答:
答案既是肯定的也是否定的,这取决于你如何理解这个问题。
首先,我们处理的是一个矩形网格,因此给定一个整数位置(x,y),在旋转后的图像中对应的点(x’,y’)极有可能不是整数位置。考虑到Canny的输出是一组点,而不是可以插值的平滑函数,因此很难在旋转后的结果集和原始图像的结果集之间建立对应关系。
例如,想想在0度和45度时给定长度的离散线上的像素数量。(提示:45度的线上的像素数是sqrt(2)
倍的少。)
但如果你更宽泛地理解这个问题,并将其解释为“在原始图像中检测到的边缘,在图像旋转θ度后是否也能被检测到?”那么理论上答案是肯定的。
当然,实践总是与理论有些不同。这里实施的细节很重要。而且总是有数值精度的问题需要处理。
让我们先假设旋转是正确计算的,使用精确的插值方案(如立方插值,Lanczos插值)并且没有四舍五入到uint8
或其他类型(即我们使用浮点值进行计算)。
如果你阅读Canny的原始论文,你会看到他提议使用高斯导数作为在紧凑支持和计算精度之间最佳的折衷方案。我见过很少的实现实际上这样做。通常我看到的是先与高斯进行卷积,然后使用Sobel导数。特别是对于较小的sigma值(较少的平滑),差异可能会很大。高斯导数是旋转不变的,而Sobel导数不是。
算法的下一步是非最大值抑制。这是将连续的梯度转换为一组点的步骤。对于每个像素,它会检查它是否是梯度方向上的局部最大值。因为这是按像素进行的,旋转后的图像与原始图像相比,测试了一组不同的位置。尽管如此,它应该在两种情况下都检测到沿着相同脊线的点。
接下来应用滞后阈值。这是一个双阈值操作,只要同一连通组件中至少有一个像素超过第二个阈值,就保留超过一个阈值的像素。这里可能会出现旋转后的图像与原始图像之间的差异。记住我们处理的是一组像素。我们在离散点对连续的梯度函数进行采样。当然,这只会发生在非常接近所选阈值的边缘上。
接下来是细化。因为非最大值抑制可能会产生沿较厚线的点,所以应用了一个细化操作,移除不需要维持线连通性的点。在旋转和原始图像之间选择的像素也会有所不同,但这不会改变解决方案的几何形状,所以我们仍然拥有相同的点集。
所以,答案是肯定的也是否定的。:)
注意,同样的逻辑也适用于平移操作。