【问题标题】:How to use OpenCV to process image so that the text become sharp and clear?如何使用OpenCV对图像进行处理,使文字清晰清晰?
【发布时间】:2013-07-26 07:09:28
【问题描述】:

想要实现这样的目标: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

原图:

应用上述内容后:

如何正确做?

更新:多亏了 metsburg、berak 和 Aurelius,让我们更接近了

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

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

结果:

使用回GaussianBlur方法,效果其实稍微好一点:

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

结果:

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

示例原始图像:

直接应用大津:

在 otsu 之前使用 medianBlur:

在 otsu 之前使用 GaussianBlur:

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

【问题讨论】:

  • 你是如何得到输出图像的?与本地图像一样,我们转换为 mat 格式,但从 img.proc 中如何查看输出图像?

标签: android opencv


【解决方案1】:

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

代替

    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);

用于阈值。

试着在这里和那里调整参数,你应该会得到非常接近你想要的结果的东西。

【讨论】:

  • THRESH_OTSU 无需调整,这是另一种“自动”方法
  • 嗯,它应该这样工作。问题是,我在您在问题中发布的最终图像中看到了很多噪音......所以我建议您调整 cvSmooth 参数以实现噪音较小的结果。这应该消除最终图像中的颗粒。并更改阈值函数中的高值和低值,这应该交换黑白通道,这会给您提供与您提供的链接大致相同的结果。
  • 是的,你是对的@Aurelius:它需要是 Imgproc.threshold(imageMat, imageMat, low, high, Imgproc.THRESH_OTSU);
  • @metsburg 如果您编辑您的问题以更正它,我会投赞成票。我刚刚在高斯模糊后尝试了 Otsu;效果很好。
  • 哇,感谢您的回复,你们太棒了!我刚刚格式化了我的电脑,所以我需要重新安装 Eclipse 和所有的 android 库,所以我可能只能在明天尝试这些。抱歉没有早点回来,因为通常我的问题没有得到太多回应所以这次只是碰碰运气:) 另外,你们都是从哪里学的这些 THRESH_OTSU、阈值和自适应阈值术语?由于我数学不好,看OpenCV教程的时候看不懂数学方程XD
【解决方案2】:

不要使用Imgproc.THRESH_BINARY_INV,而是仅使用Imgproc.THRESH_BINARY,因为_INV会在二值化后反转您的图像,结果是您的示例中显示的上述输出。

正确的代码:

Imgproc.adaptiveThreshold(imageMat, imageMat, 255, Imgproc.ADAPTIVE_THRESH_MEAN_C, Imgproc.THRESH_BINARY, 5, 4);

【讨论】:

  • 什么是 imageMat?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-09-27
  • 2013-03-25
  • 1970-01-01
相关资源
最近更新 更多