【发布时间】:2018-10-28 14:54:46
【问题描述】:
需要堆栈溢出的强大帮助。我实际上在开发一个应用程序,该应用程序必须通过 OCR(我正在使用 tesseract)文档进行分析并提取我可以从中提取的所有文本。这是图像类型的示例:
Image including text to extract
这是我在预处理中所做的以消除所有线条。将来我可能还必须分别分析每个“矩形”(将由给定线定义的区域提供给 tesseract)所以我想有比这更简单的方法,但我不会有“线”坐标。
package formRecog;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import org.opencv.core.Core;
import org.opencv.core.Mat;
import org.opencv.core.Point;
import org.opencv.core.Scalar;
import org.opencv.core.Size;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.imgproc.Imgproc;
import static org.opencv.core.Core.bitwise_not;
import org.opencv.core.MatOfPoint;
public class testMat {
public static void main(String[] args) {
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
Mat source = Imgcodecs.imread("./image.png",Imgcodecs.CV_LOAD_IMAGE_ANYCOLOR);
Mat destination = new Mat(source.rows(), source.cols(), source.type());
Imgproc.cvtColor(source, destination, Imgproc.COLOR_RGB2GRAY);
Imgcodecs.imwrite("gray.jpg", destination);
Imgproc.GaussianBlur(destination, destination, new Size(3, 3), 0, 0, Core.BORDER_DEFAULT);
Imgproc.Canny(destination, destination, 30, 90);
Imgcodecs.imwrite("postcanny.jpg", destination);
Mat houghlines = new Mat();
Imgproc.HoughLinesP(destination, houghlines, 1, Math.PI / 180, 250, 185,5);
//DESSINER LES LIGNES
Mat result = new Mat(source.rows(), source.cols(), source.type());
for (int i = 0; i < houghlines.rows(); i++) {
double[] val = houghlines.get(i, 0);
Imgproc.line(destination, new Point(val[0], val[1]), new Point(val[2], val[3]), new Scalar(0, 0, 255), 5);
Imgproc.line(result, new Point(val[0], val[1]), new Point(val[2], val[3]), new Scalar(0, 0, 255),5);
}
Imgcodecs.imwrite("lines.jpg", result);
Mat contourImg = new Mat(source.rows(), source.cols(), source.type());
List<MatOfPoint> contours = new ArrayList<MatOfPoint>();
Mat hierarchy = new Mat();
//Point offset = new Point();
Imgproc.findContours(destination, contours, hierarchy, Imgproc.RETR_LIST, Imgproc.CHAIN_APPROX_NONE );
Imgproc.drawContours(contourImg, contours, -1, new Scalar(255, 0, 0),-1);
Imgcodecs.imwrite("contour.jpg", contourImg);
bitwise_not(destination,destination);
Imgcodecs.imwrite("final.jpg", destination);
}
}
这是最终的图像
问题是,tesseract 没有读取任何内容:
11m ËEZË@ÜDS@ 7 C@mpû@ 515 îf@5@??ûäû ©©m@@@ @@ vësw??a? PF©@MÜGS @"@X@Ü©ÜÎÊQÜ©IÏÙ 1111 175515
是我得到的第一条“线”。
我认为这是因为字母不再“填充”并且 tesseract 无法读取它们,因为 tesseract 实际上之前给了我很好的结果,但是删除行的方法并不好。 我想用黑色填充字母,但是
Imgproc.drawContours(contourImg, contours, -1, new Scalar(255, 0, 0),-1);
什么都不做,虽然我很确定 findContours 工作得很好,因为如果我将它的结果写下来,我会得到和以前一样的图像。
我搜索了类似的问题,例如 cv2.drawContours will not draw filled contour 和 Contour shows dots rather than a curve when retrieving it from the list, but shows the curve otherwise 但没有找到我可以使用的任何东西(也许没有得到它)。
您知道,我从 9 月份开始编程课程,所以我对这件事很陌生(如果这里写了一些可怕的东西,请原谅我),但我没有选择我所从事的主题工作:)
我希望我说得够清楚,而且我的英语还不错。
谢谢。
编辑:感谢 Rick.M 它变得越来越好,在 findcontours 中使用 CHAIN_APPROX_SIMPLE 并在 drawcontours 中通过 ldx 进行迭代就可以了。 New final
有没有办法改善这个结果?我猜tesseract也不会吃这个? 谢谢
上传postcanny图片:Image after canny
【问题讨论】:
-
您是否尝试过使用 contourIdx 而不是 -1 来绘制轮廓?
-
您的意思是通过迭代 contoursldx 来分别绘制每个轮廓吗?我刚刚尝试了 (int ldx = 0; ldx
-
是的,我是这个意思。 contours.size() 说什么?
-
System.out.println(contours.size());渲染:5369
-
和 contourImg.type()?