如何使用OpenCV处理图像,使文本清晰明了?

时间:2013-07-26 06:11:09

标签: android opencv

想要实现这样的目标:http://www.leptonica.com/binarization.html

在搜索解决方案时,大多数答案都是一般性说明,例如建议查看自适应滤波器,高斯模糊,扩张和侵蚀,但它们都没有提供任何示例代码(因此可以使用值) ..

我知道不同的图像需要不同的方法和值才能达到最佳清晰度,但我只需要一些通用滤镜,这样在对其进行任何OCR之前,图像至少会比原始图像更清晰,噪点更少。

这是我到目前为止所尝试的......

Mat imageMat = new Mat();
Utils.bitmapToMat(photo, imageMat);
Imgproc.cvtColor(imageMat, imageMat, Imgproc.COLOR_BGR2GRAY);
Imgproc.GaussianBlur(imageMat, imageMat, new Size(3, 3), 0);
Imgproc.adaptiveThreshold(imageMat, imageMat, 255, Imgproc.ADAPTIVE_THRESH_MEAN_C, Imgproc.THRESH_BINARY_INV, 5, 4);

但是作为一个图像处理新手,显然我不知道我在做什么XD

原图: original image

申请上述后: image after applying filters

如何正确地做到这一点?

更新:感谢metsburg,berak和Aurelius,让它更加接近

使用medianBlur方法,因为cvSmooth与CV_MEDIAN已被弃用并替换为medianBlur:

Imgproc.medianBlur(imageMat, imageMat, 3);
Imgproc.threshold(imageMat, imageMat, 0, 255, Imgproc.THRESH_OTSU);

结果: using medianblur before applying otsu

使用GaussianBlur方法,结果实际上稍好一些:

Imgproc.GaussianBlur(imageMat, imageMat, new Size(3, 3), 0);
Imgproc.threshold(imageMat, imageMat, 0, 255, Imgproc.THRESH_OTSU);

结果: using gaussianblur before applying otsu

对于这张图片,差异并不明显,所以我尝试了另一张图片,这是从电脑屏幕上拍下的照片。电脑屏幕会产生很多噪音(波浪线),因此很难消除噪音。

示例原始图片: pcscreen original image

直接申请otsu: pcscreen directly apply otsu

在otsu之前使用medianBlur: pcscreen using medianBlur before applying otsu

在otsu之前使用GaussianBlur: pcscreen using GaussianBlur before applying otsu

似乎高斯模糊稍微好一些,但是我还在玩设置.. 如果有人可以建议如何进一步改进电脑屏幕照片,请告诉我们:) 还有一件事......在顶部链接内的图像上使用此方法会产生可怕的结果:(在此处查看:http://imgur.com/vOZAaE0

2 个答案:

答案 0 :(得分:10)

嗯,你快到了。试试这些修改:

而不是

    Imgproc.GaussianBlur(imageMat, imageMat, new Size(3, 3), 0);

尝试:

     cvSmooth(imageMat, imageMat, CV_MEDIAN, new Size(3, 3), 0);

检查语法,可能不完全匹配

您发布的链接使用了Otsu的阈值,请试试这个:

 Imgproc.threshold(imageMat, imageMat, 0, 255, Imgproc.THRESH_OTSU);

进行阈值处理。

尝试在这里和那里调整参数,你应该得到一些非常接近你期望结果的东西。

答案 1 :(得分:1)

仅使用Imgproc.THRESH_BINARY_INV而不是Imgproc.THRESH_BINARY使用Imgproc.adaptiveThreshold(imageMat, imageMat, 255, Imgproc.ADAPTIVE_THRESH_MEAN_C, Imgproc.THRESH_BINARY, 5, 4); ,因为_INV会在二元化后反转您的图像,结果是您的示例中显示的上述输出。

正确的代码:

{{1}}