使用OpenCV Mat通过tesseract阅读文本(Java)

时间:2018-12-20 10:13:04

标签: java opencv tesseract leptonica

我需要使用tesseract读取文本,以处理使用OpenCV完成的图像。我已经尝试了以下链接中提到的方法,但无济于事:

方法1

使用MatOfBytes SO Link

进行转换
public static PIX convertMatToPix(Mat mat) {

        LOGGER.info("Size of image: " + mat.size());
        MatOfByte bytes = new MatOfByte();
        Imgcodecs.imencode(".jpg", mat, bytes);
        ByteBuffer buff = ByteBuffer.wrap(bytes.toArray());
        LOGGER.info("Size for pixReadMem: " + new NativeSize(buff.capacity()).intValue());
        return pixReadMem(buff, new NativeSize(buff.capacity()).intValue());
    }

此方法从我的输入图像中创建一个白色图像。

方法2

使用字节数组进行转换

byte[] imageBuffer = new byte[(int) (input.rows()*input.cols()*input.channels())];
        input.get(0, 0, imageBuffer);
PIX image = pixReadMem(imageBuffer, (int) (input.rows()*input.cols()*input.channels()));

此方法无法创建图像,因为我使用以下方法输出图像:

int writingFromPix = pixWriteAutoFormat("/home/abhishekkeshri/Pictures/ocr/pixOutput.jpg", image);
LOGGER.info("Writing from PIX returns: " + writingFromPix);

它返回1,表示写图像时出错。

方法3

逐像素复制值(SO link

PIX mat8ToPix(Mat mat8)
    {
        PIX pixd = pixCreate(mat8.width(), mat8.height(), mat8.depth());
        for(int y=0; y<mat8.rows(); y++) {
            for(int x=0; x<mat8.cols(); x++) {
                double[] pixelDouble = mat8.get(y,x);
                int[] pixelInt = new int[pixelDouble.length];
                for(int i=0;i<pixelDouble.length;i++) {
                    pixelInt[i] = (int) pixelDouble[i];
                }
                pixSetPixel(pixd, y, x, pixelInt[0]);
            }
        }
        return pixd;
    }

此方法的问题在于get方法返回一个像素数组,该像素数组取决于通道。因此,仅使用0th值应该是错误的。逻辑似乎是正确的,但是我在这种方法上做错了什么?

方法4

在Tesseract中直接使用MatsetImage

api.SetImage(imageBuffer, input.width(), input.height(), input.channels(), (int)input.step1());

该方法也无法从Tesseract获得任何输出,因为打印的输出为空白。

方法5

通过简单地读取预处理的图像,然后使用tesseract读取图像,给出的输出是正确的:

PIX image = pixRead("/home/abhishekkeshri/Pictures/ocr/clean.jpg");
api.SetImage(image);

这将给出正确的结果。但是我不能使用它,因为磁盘操作将非常昂贵(编写opencv的输出并将其保存在文件中,然后使用PIX打开该文件)

任何帮助将不胜感激,因为自2天以来我一直在这个问题上陷入困境。

我的Maven依赖项:

    <dependency>
        <groupId>org.bytedeco.javacpp-presets</groupId>
        <artifactId>tesseract-platform</artifactId>
        <version>4.0.0-rc2-1.4.3</version>
    </dependency>
    <dependency>
        <groupId>org.openpnp</groupId>
        <artifactId>opencv</artifactId>
        <version>3.4.2-1</version>
    </dependency>
    <dependency>
        <groupId>net.sourceforge.lept4j</groupId>
        <artifactId>lept4j</artifactId>
        <version>1.10.0</version>
    </dependency>

1 个答案:

答案 0 :(得分:0)

我已经使用下面的代码将Mat转换为BufferImage。

Tesseract代码:

Tesseract tesseract1 = new Tesseract();
tesseract1.setDatapath(datapath);
tesseract1.doOCR(Mat2BufferedImage(mat);

垫子到BufferdImage转换代码:

static BufferedImage Mat2BufferedImage(Mat matrix) throws Exception {
    MatOfByte mob = new MatOfByte();
    Imgcodecs.imencode(".jpg", matrix, mob);
    byte ba[] = mob.toArray();

    BufferedImage bi = ImageIO.read(new ByteArrayInputStream(ba));
    return bi;
}

使用此代码获得预期的输出。