有谁知道为什么 MatLab Canny (MLC) 与 OpenCV Canny (OCC) 相比如此不同?ML-C 提供比 OCC 更精确且连接更多的边缘,但这怎么可能呢?我问的原因是,我需要将我的 ML 代码原型实现为 C++,并且我想使用 OpenCV。就我所尝试的而言,导出 ML 的代码是不可能的。
亲切的问候,
有谁知道为什么 MatLab Canny (MLC) 与 OpenCV Canny (OCC) 相比如此不同?ML-C 提供比 OCC 更精确且连接更多的边缘,但这怎么可能呢?我问的原因是,我需要将我的 ML 代码原型实现为 C++,并且我想使用 OpenCV。就我所尝试的而言,导出 ML 的代码是不可能的。
亲切的问候,
如上所述,Matlab Canny 边缘检测器使用“高斯滤波器的导数”计算梯度(如文档中所述)。换句话说,Matlab 对图像进行高斯模糊,然后找到该平滑图像的梯度……所有这些都使用一个花哨的滤波器。[如果您想了解详细信息,只需edit edge
按照 Andrey 的建议输入,然后向下滚动到该smoothGradient()
功能。]
模糊操作显着减少了图像中存在的噪声量,消除了许多虚假边缘并留下了好的东西。
不幸的是,OpenCV Canny 函数不允许您通过函数参数更改它使用的过滤器内核。然而。您可以通过首先模糊输入图像,然后将此模糊图像传递给 Canny 函数来生成相同的结果。
这显着清理了生成的边缘图。为了模糊输入图像,我个人使用 OpenCV 的GaussianBlur()
函数 with sigmaX=2
. 这模仿了 Matlab 中的默认 sigma。最佳模糊内核大小可能因情况而异,但在 Matlab 中,它是使用 计算的filterLength = 8*ceil(sigma);
,因此对于 2 的 sigma,这意味着内核大小为(16,16)
由于高斯模糊和索贝尔滤波器都是线性的,将模糊的输入图像传递给 OpenCVCanny()
函数在数学上等同于 Matlab 所做的,因为叠加原理,如下伪代码所示(注意:*
是卷积算子):
// The Matlab method: the sobel and blur operations are combined into
// a single filter, and that filter is then convolved with the image
matlabFancyFilter = (sobel * blur);
gradient = matlabFancyFilter * image;
// Equivalent method: image is first convolved with the blur filter, and
// then convolved with the sobel filter.
gradient = sobel * (blur * image); // image is filtered twice
这里有一个OpenCV Canny 教程,演示了如何使用 C++ 来做到这一点。我是一个 python 人,所以这就是我所做的:
smoothedInput = cv2.GaussianBlur(image, (7,7), 2);
edges = cv2.Canny(smoothedInput, 25, 50);