内核大小 > 7 的 Canny 边缘检测器

man*_*tta 3 c++ opencv edge-detection

为什么不能在内核大小大于 7 的 OpenCV 中执行 Canny 边缘检测?

例如,

// This works
cv::Canny(src_image, out_edges, th1, 2 * th1, 3);
cv::Canny(src_image, out_edges, th1, 2 * th1, 7);

// This raises an exception
cv::Canny(src_image, out_edges, th1, 2 * th1, 9);
Run Code Online (Sandbox Code Playgroud)

我知道 Sobel 只采用 1、3、5 或 7 的内核大小。但我见过使用内核大小为 9 的论文。这在 OpenCV 中是不可能的吗?

* 编辑 *

我一直在编辑 Canny 代码以支持更大的内核。问题出在这里(canny.cpp):

if (L2gradient)
{
  low_thresh = std::min(32767.0, low_thresh);
  high_thresh = std::min(32767.0, high_thresh);
  if (low_thresh > 0) low_thresh *= low_thresh;
  if (high_thresh > 0) high_thresh *= high_thresh;
}
Run Code Online (Sandbox Code Playgroud)

if (L2gradient)
{
  low_thresh = std::min(32767.0, low_thresh);
  high_thresh = std::min(32767.0, high_thresh);

  if (low_thresh > 0) low_thresh *= low_thresh;
  if (high_thresh > 0) high_thresh *= high_thresh;
}
Run Code Online (Sandbox Code Playgroud)

我想这与他们正在使用一些移位操作有关,

#define CANNY_SHIFT 15
const int TG22 = (int)(0.4142135623730950488016887242097*(1<<CANNY_SHIFT) + 0.5);
Run Code Online (Sandbox Code Playgroud)

因此将精度限制为 16 位,因此限制为 32767.... 我该如何解决这个问题?

Mik*_*iki 5

看看 OpenCV 文档:

对于康妮

孔径大小 Sobel 算子的孔径大小。

对于索贝尔

ksize:扩展 Sobel 核的大小;它必须是 1、3、5 或 7。

所以孔径大小CannySobel内核大小的限制。

这在源代码中得到验证:

 if ((aperture_size & 1) == 0 || (aperture_size != -1 && (aperture_size < 3 || aperture_size > 7)))
    CV_Error(CV_StsBadFlag, "Aperture size should be odd");
Run Code Online (Sandbox Code Playgroud)

因此,除非您自己重写一些代码,否则无法使用具有更大光圈尺寸的 Canny。您可以使用filter2d应用您的自定义大型 sobel 过滤器,然后对 Canny 非最大值抑制进行编码。

然而,掩码大于 3x3 的 Sobel 在实践中很少使用。