OpenCV - 精明的边缘检测无法正常工作
Posted
技术标签:
【中文标题】OpenCV - 精明的边缘检测无法正常工作【英文标题】:OpenCV - canny edge detection not working properly 【发布时间】:2017-06-13 01:54:16 【问题描述】:我是 android 的 OpenCV 新手。我目前正在开发文档检测演示应用程序。到目前为止我所做的如下:
原始图像 -> 灰度图像 -> 高斯模糊 -> Canny边缘检测 -> 寻找轮廓 -> 绘制轮廓
如下图所示,我能够完美地检测纸张。
但它没有检测到某些文档。以下是其中之一
我对此进行了很多研究,发现问题在于精明的边缘检测,下面是精明的图像:
如您所见,边缘检测没有完美链接,并且在某些点上没有连接边缘。这就是原因。
我在 How to select the best set of parameters in Canny Edge detection algorithm implemented in OpenCV? 遇到过类似的问题 我遵循了解决方案,但它对我不起作用。
我的canny检测代码如下:
double otsu_thresold = Imgproc.threshold(mGray,edged,0,255, Imgproc.THRESH_OTSU);
Imgproc.Canny(mRgba, edged, otsu_thresold*0.5,otsu_thresold);
我不知道我错在哪里!我应该怎么做才能完美地检测到文档?
【问题讨论】:
为了增强边缘使用形态膨胀。见THIS PAGE。 【参考方案1】:首先必须改变执行 Canny 边缘检测 的方法。您在cv2.Canny()
手动中设置了越来越低的阈值。您可以自动执行此操作。我使用THIS LINK 作为参考。
使用下面的sn-p:
v = np.median(gray_image)
#---- apply automatic Canny edge detection using the computed median----
lower = int(max(0, (1.0 - sigma) * v))
upper = int(min(255, (1.0 + sigma) * v))
edged = cv2.Canny(gray_image, lower, upper)
cv2.imshow('Edges',edged)
那我在这里做什么?
我正在取灰度图像的中值。选择 sigma
值 0.33 来设置 lower
和 upper
阈值。 0.33
值通常被统计学家用于数据科学。所以这里也考虑一下。
这是我得到的:
为了增强这个边缘信息,我使用cv2.MORPH_CROSS
内核执行了形态膨胀:
现在只需执行通常的cv2.findContours()
操作并绘制最大轮廓。
:)
【讨论】:
我是用大津的方法动态查找阈值的。我也应用了您的解决方案,但没有奏效,并且降低了相机帧数。 你的意思是寻找边缘很慢? 不,我的意思是相机预览帧由于阈值计算而变慢 这可能是因为它正在计算图像的中值并根据该值设置阈值 是的,它会降低相机预览的性能。顺便说一句,感谢您的努力。您还有其他解决方案吗?【参考方案2】:对 Jeru Luke 发布的算法稍作修改后,我得到了更好的结果。
在文档检测中,我们宁愿搜索文档的深色阴影边缘:
对于浅色图像,例如白纸,中值较高,“255 - 中值”的表现优于中值 对于较小的值,sigma 太小,无法产生足够宽的范围。这是我的 C# 算法:
double s = 0.33;
if (imageMedian > 191) // light images
cannyTh1 = (int)Math.Max(0, (1 - 2*s) * (255 - imageMedian));
cannyTh2 = (int)Math.Max(85, (1 + 2*s) * (255 - imageMedian));
else if (imageMedian > 127)
cannyTh1 = (int)Math.Max(0, (1 - s) * (255 - imageMedian));
cannyTh2 = (int)Math.Min(255, (1 + s) * (255 - imageMedian));
else if (imageMedian < 63) // dark images
cannyTh1 = (int)Math.Max(0, (1 - 2*s) * imageMedian);
cannyTh2 = (int)Math.Max(85, (1 + 2*s) * imageMedian);
else
cannyTh1 = (int)Math.Max(0, (1 - s) * imageMedian);
cannyTh2 = (int)Math.Min(255, (1 + s) * imageMedian);
另外,一些文档的结果可以通过
使用中值滤波器后锐化图像 使用更强的中值滤波器 计算中值并对图像的各个部分执行 canny 滤波器,因为阴影和光线的影响在图像的各个部分可能会有很大差异【讨论】:
感谢您的努力,但我不再从事此项目,将检查您的解决方案并稍后回复您。以上是关于OpenCV - 精明的边缘检测无法正常工作的主要内容,如果未能解决你的问题,请参考以下文章
如何针对低分辨率/模糊素材优化 OpenCV 的 Canny 边缘检测