Использование OpenCV Mat для чтения текста с использованием tesseract (Java) - PullRequest
0 голосов
/ 20 декабря 2018

Мне нужно прочитать текст, используя 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 возвращает массивпикселя, который зависит от канала.Так что просто использование 0-го значения должно быть неправильным.Логика кажется правильной, но что я делаю не так в этом методе?

Метод 4

Непосредственное использование Mat до setImage в Tesseract

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 голосов
/ 30 мая 2019

Я использовал приведенный ниже код для преобразования Mat в BufferImage.

Код Тессеракта:

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

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

Использование этого кодаполучение ожидаемого результата.

...