什么是对可能模糊和不均匀亮度的图像进行阈值处理的快速可靠的方法?
示例(模糊但亮度均匀):
由于不能保证图像具有均匀的亮度,因此使用固定阈值是不可行的。自适应阈值可以正常工作,但由于模糊性,它会在特征中产生中断和扭曲(这里,重要的特征是数独数字):
我也尝试过使用直方图均衡(使用 OpenCV 的equalizeHist
函数)。它在不减少亮度差异的情况下增加对比度。
我发现的最佳解决方案是将图像除以其形态闭合(归功于此帖子)以使亮度均匀,然后重新归一化,然后使用固定阈值(使用 Otsu 的算法来选择最佳阈值水平):
这是 OpenCV for Android 中的代码:
Mat kernel = Imgproc.getStructuringElement(Imgproc.MORPH_ELLIPSE, new Size(19,19));
Mat closed = new Mat(); // closed will have type CV_32F
Imgproc.morphologyEx(image, closed, Imgproc.MORPH_CLOSE, kernel);
Core.divide(image, closed, closed, 1, CvType.CV_32F);
Core.normalize(closed, image, 0, 255, Core.NORM_MINMAX, CvType.CV_8U);
Imgproc.threshold(image, image, -1, 255, Imgproc.THRESH_BINARY_INV
+Imgproc.THRESH_OTSU);
这很好用,但关闭操作非常慢。减小结构元素的大小会提高速度,但会降低准确性。
编辑:根据 DCS 的建议,我尝试使用高通滤波器。我选择了 Laplacian 滤波器,但我希望使用 Sobel 和 Scharr 滤波器得到类似的结果。该滤波器在不包含特征的区域中拾取高频噪声,并且由于模糊而遭受与自适应阈值相似的失真。它也需要大约与关闭操作一样长的时间。这是一个使用 15x15 过滤器的示例:
编辑 2:根据 AruniRC 的回答,我使用建议参数对图像使用 Canny 边缘检测:
double mean = Core.mean(image).val[0];
Imgproc.Canny(image, image, 0.66*mean, 1.33*mean);
我不确定如何可靠地自动微调参数以获得连接的数字。