gpt4 book ai didi

java - 如何去除 OpenCV 中不需要的线条/噪音?

转载 作者:太空狗 更新时间:2023-10-29 16:03:33 28 4
gpt4 key购买 nike

我正在为 android 开发一个 OCR 应用程序(构建为 java 应用程序)。我想从相机捕获的图像中检测文本并进行预处理我正在使用 OpenCV,但我得到了一些额外的行,这些行被读取为文本,我采用了这种方法:

1-RGB 到灰度2-阈值3-高斯模糊4-中值模糊5-扩张6-侵 eclipse

结果至少比以前好,但仍然没有得到正确的结果。我怎样才能消除这种噪音,像这样的过滤器的一般序列是什么,可以应用于任何图像以改善 OCR 的结果。我是 OpenCV 的新手,所以请指导我。谢谢。

old Image


Updated Image


从上图中我可以找到 3 号的结果,但只有当所有轮廓都被绘制出来时,这是我不想要的东西,因为还有噪音。我在这里错过了什么。不知道该怎么做。修改后的代码:

package simple_contours;

import java.util.ArrayList;
import java.util.List;

import org.opencv.core.Core;
import org.opencv.core.CvType;
import org.opencv.core.Mat;
import org.opencv.core.MatOfPoint;
import org.opencv.core.Point;
import org.opencv.core.Rect;
import org.opencv.core.Scalar;
import org.opencv.core.Size;
import org.opencv.highgui.Highgui;
import org.opencv.imgproc.Imgproc;

public class Main {

public static void main(String[] args) {
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
Mat src_img,src_grey,src_blur,src_thresh,src_dilate,dest_img;
src_img=Highgui.imread("n_num.jpg",Imgproc.COLOR_BGR2GRAY);


src_grey=new Mat(src_img.size(), Core.DEPTH_MASK_8U);
src_blur=new Mat(src_img.size(), Core.DEPTH_MASK_8U);
src_thresh=new Mat(src_img.size(), Core.DEPTH_MASK_8U);
src_dilate=new Mat(src_img.size(), Core.DEPTH_MASK_8U);
dest_img=Mat.zeros(640,480, CvType.CV_8UC3);
Core.bitwise_not(dest_img, dest_img);
Highgui.imwrite("dest.jpg", dest_img);

Imgproc.cvtColor(src_img, src_grey, Imgproc.COLOR_BGR2GRAY);
Imgproc.GaussianBlur(src_grey, src_blur, new Size(3, 3), 0);
Imgproc.threshold(src_blur, src_thresh, 80, 255, Imgproc.THRESH_BINARY_INV);
Imgproc.dilate(src_thresh, src_dilate, Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new Size(2, 2)));

Highgui.imwrite("Threshold.jpg", src_thresh);
Highgui.imwrite("Dilate.jpg", src_dilate);




List<MatOfPoint> contours = new ArrayList<MatOfPoint>();
Mat heirarchy= new Mat();
Point shift=new Point(150,0);
Imgproc.findContours(src_dilate, contours,heirarchy, Imgproc.RETR_TREE,Imgproc.CHAIN_APPROX_SIMPLE,shift);
double[] cont_area =new double[contours.size()];

for(int i=0; i< contours.size();i++)
{
Rect rect = Imgproc.boundingRect(contours.get(i));
cont_area[i]=Imgproc.contourArea(contours.get(i));

System.out.println("Hight: "+rect.height);
System.out.println("WIDTH: "+rect.width);
System.out.println("AREA: "+cont_area[i]);
//System.out.println(rect.x +","+rect.y+","+rect.height+","+rect.width);

Core.rectangle(src_img, new Point(rect.x,rect.y), new Point(rect.x+rect.width,rect.y+rect.height),new Scalar(0,0,255));
Imgproc.drawContours(dest_img, contours, i, new Scalar(0,0,0),-1,8,heirarchy,2,shift);
Core.rectangle(dest_img, new Point(rect.x,rect.y), new Point(rect.x+rect.width,rect.y+rect.height),new Scalar(0,255,0));
}

Highgui.imwrite("Final.jpg", dest_img);
Highgui.imwrite("Original.jpg", src_img);
}

}

最佳答案

我认为您只能使用侵 eclipse /扩张选项走这么远。问题是噪音不仅仅是噪音,还包含不一定与您尝试检测的某些字符不同的 Artifact 。

我建议解决方案需要涉及检测图像中的轮廓。首先,您应该准备好图像,使其更易于轮廓绘制过程的管理。

我过去使用过以下序列:

  • 高斯模糊
  • 自适应阈值
  • 负片
  • 膨胀

现在您可以找到轮廓。这应该挑出字母和不需要的 Artifact 。然后您需要消除 Artifact ,您可能需要多种策略,例如:

  • 算出边界框的面积,剔除那些面积太小不能成为字母的
  • 检查边界框的宽度与高度:剔除那些高度太小的

可能有更复杂的方法,例如尝试找到穿过较大轮廓中间的轴,这将为您提供字符的位置和方向(比如旋转的矩形);您可以使用该信息来忽略不在区域中的所有其他像素。

抱歉,这不是一个简单的解决方案,而是一个复杂的问题,因此您可能需要进行一些试验并制定多种策略来移除不需要的 Artifact 。

关于java - 如何去除 OpenCV 中不需要的线条/噪音?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22898996/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com