内核大小 > 7 的 Canny 边缘检测器
Posted
技术标签:
【中文标题】内核大小 > 7 的 Canny 边缘检测器【英文标题】:Canny edge detector with kernel size > 7 【发布时间】:2015-11-24 11:30:53 【问题描述】:为什么不能在内核大小大于 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);
我知道 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;
和
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;
我猜这与他们使用了一些移位操作有关,
#define CANNY_SHIFT 15
const int TG22 = (int)(0.4142135623730950488016887242097*(1<<CANNY_SHIFT) + 0.5);
因此将精度限制为 16 位,因此限制为 32767.... 我该如何解决这个问题?
【问题讨论】:
【参考方案1】:查看 OpenCV 文档:
对于Canny:
apertureSize: Sobel 算子的孔径大小。
对于Sobel:
ksize:扩展Sobel核的大小;它必须是 1、3、5 或 7。
所以Canny
中的孔径大小受Sobel
内核大小的限制。
这在source code 中得到验证:
if ((aperture_size & 1) == 0 || (aperture_size != -1 && (aperture_size < 3 || aperture_size > 7)))
CV_Error(CV_StsBadFlag, "Aperture size should be odd");
因此,除非您自己重写一些代码,否则无法使用具有更大光圈尺寸的 Canny。您可以使用 filter2d 应用您的自定义 large sobel 过滤器,然后对 Canny 非极大值抑制进行编码。
然而,实际中很少使用掩码大于 3x3 的 Sobel。
【讨论】:
嘿三木!我发现了它们限制内核大小的原因。我编辑了我的问题。你知道我该如何解决这个问题吗? @manatttta 我不完全确定这种转变是否符合您的意思。代码经过优化,很难阅读。但是,如果您重写 NMS 部分,您应该能够使用更大的内核大小。再说一次,我认为这不值得。 在 Opencv 3.1.0 及更高版本中,您可以将梯度作为输入传递给 canny 边缘检测器。使用所需的内核查找梯度并将其作为输入传递给 Canny... [参见此处] (@ 987654325@)以上是关于内核大小 > 7 的 Canny 边缘检测器的主要内容,如果未能解决你的问题,请参考以下文章