我是Android的OpenCV新手。我目前正在研究文档检测演示应用程序。到目前为止我所做的如下:
原始图片 - > 灰度图像 - > GaussianBlur - > Canny边缘检测 - > 寻找轮廓 - > 绘制轮廓
我能够完美地检测出纸张,如下图所示。
但它没有检测到某些文件。以下是其中一个
我对此进行了大量研究,发现问题在于精确边缘检测,下面是精确图像:
正如您所看到的,边缘检测并未完美链接,并且在某些时候不会连接边缘。这就是原因。
我在How to select the best set of parameters in Canny Edge detection algorithm implemented in OpenCV?处遇到了类似的问题 我已经按照解决方案但它对我没有用。
我的精确检测代码如下:
double otsu_thresold = Imgproc.threshold(mGray,edged,0,255, Imgproc.THRESH_OTSU);
Imgproc.Canny(mRgba, edged, otsu_thresold*0.5,otsu_thresold);
我不知道我哪里错了!我该怎么做以完美地检测文件?
答案 0 :(得分:4)
首先,执行 Canny边缘检测的方法必须改变。您在cv2.Canny()
手动设置的阈值越来越低。您可以自动执行此操作。我使用THIS LINK作为参考。
使用以下代码段:
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()
操作并绘制最大轮廓。
:)
答案 1 :(得分:1)
仅对Jeru Luke发布的算法进行少量修改,我的结果就会更好。
在文档检测中,我们宁愿搜索文档的深色阴影边缘:
这是我的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);
}
此外,某些文档的结果可以通过以下方式得到改善