You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java-OpenCV中drawContours无法填充轮廓的OCR预处理问题

求助:优化OCR文本识别的OpenCV预处理方案

我正在开发一款基于Tesseract OCR的文档文本提取应用,目前处理的示例图片如下:
待提取文本的图片

因为后续需要单独分析每个矩形区域,所以必须保留线条坐标,同时要去除图片中的干扰线条。我用Java结合OpenCV写了下面这段预处理代码:

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);
        //绘制线条
        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的识别效果是正常的。但我调用Imgproc.drawContours(contourImg, contours, -1, new Scalar(255, 0, 0),-1);这段代码并没有实现填充效果,不过findContours本身是正常工作的,导出的结果和原图片一致。我搜了很多相关问题,但都没找到能用的解决方案。我今年9月才开始学编程,算是纯新手,但这个任务必须完成,实在没办法了才来求助。


编辑:感谢Rick.M的帮助!我把findContours的参数改成CHAIN_APPROX_SIMPLE,并且遍历索引绘制轮廓后,效果有所改善,新的最终图片是:
优化后的最终图片

不过我还是想问问有没有进一步优化的方法?我感觉现在Tesseract应该还是没法正常识别,希望各位能给我一些建议。另外附上Canny处理后的图片:
Canny处理后的图片

内容的提问来源于stack exchange,提问作者DSt

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 06:28:43