OpenCV-canny边缘检测无法正常工作
我是Android版OpenCV的新手。我目前正在开发文档检测演示应用程序。到目前为止,我所做的工作如下: 原始图像->灰度图像->高斯模糊->Canny边缘检测->查找轮廓->绘制轮廓 我能够完美地检测纸张,如下图所示 但是它没有检测到一些文档。下面是其中之一 我对此进行了大量研究,发现问题在于canny边缘检测,下面是canny图像: 如您所见,边缘检测没有完美链接,并且在某些点上没有连接边缘。这就是原因 我曾在以下网站讨论过类似问题: 我遵循了这个解决方案,但它对我不起作用 我的canny检测代码如下:OpenCV-canny边缘检测无法正常工作,opencv,image-processing,edge-detection,opencv4android,Opencv,Image Processing,Edge Detection,Opencv4android,我是Android版OpenCV的新手。我目前正在开发文档检测演示应用程序。到目前为止,我所做的工作如下: 原始图像->灰度图像->高斯模糊->Canny边缘检测->查找轮廓->绘制轮廓 我能够完美地检测纸张,如下图所示 但是它没有检测到一些文档。下面是其中之一 我对此进行了大量研究,发现问题在于canny边缘检测,下面是canny图像: 如您所见,边缘检测没有完美链接,并且在某些点上没有连接边缘。这就是原因 我曾在以下网站讨论过类似问题: 我遵循了这个解决方案,但它对我不起作用 我的ca
double otsu_thresold = Imgproc.threshold(mGray,edged,0,255, Imgproc.THRESH_OTSU);
Imgproc.Canny(mRgba, edged, otsu_thresold*0.5,otsu_thresold);
我不知道我错在哪里!我应该怎么做才能完美地检测文档?首先,执行Canny边缘检测的方法必须改变。您正在
cv2.Canny()中手动设置较低和较高的阈值。您可以自动执行此操作。我用作参考
使用以下代码段:
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来设置下限
和上限
阈值0.33
值通常由统计学家用于数据科学。因此,这里也考虑到了这一点
这就是我得到的:
为了增强这一边缘信息,我使用cv2.MORPH\u CROSS
内核执行了形态扩张:
现在只需执行通常的cv2.findContours()
操作并绘制最大轮廓
:)我对杰鲁·卢克(Jeru Luke)发布的算法进行了一点修改,得到了更好的结果
在文档检测方面,我们更倾向于搜索文档的暗阴影边缘:
- 对于光照图像,如白纸,中值较高,“255-中值”的性能优于仅中值
- 对于较小的值,西格玛太小,无法产生足够大的范围
这是我的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);
}
double s=0.33;
if(imageMedian>191)//灯光图像
{
cannyTh1=(int)Math.Max(0,(1-2*s)*(255-imageMedian));
cannyTh2=(int)数学最大值(85,(1+2*s)*(255-图像中值);
}
否则,如果(图像中值>127)
{
cannyTh1=(int)Math.Max(0,(1-s)*(255-imageMedian));
cannyTh2=(int)Math.Min(255,(1+s)*(255-imageMedian));
}
else if(imageMedian<63)//暗图像
{
cannyTh1=(int)数学最大值(0,(1-2*s)*图像中值);
cannyTh2=(int)数学最大值(85,(1+2*s)*图像中值);
}
其他的
{
cannyTh1=(int)数学最大值(0,(1-s)*图像中值);
cannyTh2=(int)数学最小值(255,(1+s)*图像中值);
}
此外,对于某些文档,可以通过
- 使用中值滤波器后对图像进行锐化
- 使用更强的中值滤波器
- 计算中值并对图像的各个部分执行canny滤波,因为阴影和灯光的影响在图像的各个部分上可能有很大差异
为了增强边缘,使用形态扩张。看,我用大津的方法动态地找到阈值。我也应用了你的解决方案,但它不起作用,也降低了相机帧的速度。你是说查找边缘速度很慢?不,我是说相机预览帧会因为阈值计算而变慢,这可能是因为它正在计算图像的中值并根据该值设置阈值。是,它会降低相机预览的性能。顺便说一下,谢谢你的努力。你有其他的解决方案吗?谢谢你的努力,但我不再从事这个项目了,我会检查你的解决方案,稍后再给你回复。