Как прочитать матрицу данных, встроенную в документ? - PullRequest
0 голосов
/ 05 апреля 2020

Я пытаюсь прочитать матрицу данных, которая встроена в документ. Это для проекта с открытым исходным кодом, который помогает создавать и читать стандарт 2DCODE.

Я пытаюсь использовать этот код:

import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import java.util.Hashtable;

import javax.imageio.ImageIO;

import org.junit.Test;

import com.google.zxing.BarcodeFormat;
import com.google.zxing.BinaryBitmap;
import com.google.zxing.DecodeHintType;
import com.google.zxing.LuminanceSource;
import com.google.zxing.MultiFormatReader;
import com.google.zxing.Result;
import com.google.zxing.client.j2se.BufferedImageLuminanceSource;
import com.google.zxing.common.HybridBinarizer;

public class ZxingTest {

    @Test
    public void test() {

        readQRCode("sfr-facture-1048469311-1.jpg");
        readQRCode("sfr-facture-1048469311-1.png");

    }

    public static void readQRCode(String fileName) {

        System.out.println("Try reading " + fileName);

        File file = new File(fileName);
        BufferedImage image = null;

        try {
            image = ImageIO.read(file);
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        if (image == null)
            return;

        Hashtable<DecodeHintType, Object> hints = new Hashtable<DecodeHintType, Object>();
        // hints.put(DecodeHintType.CHARACTER_SET, "UTF-8");
        hints.put(DecodeHintType.TRY_HARDER, Boolean.TRUE);
        hints.put(DecodeHintType.POSSIBLE_FORMATS, Arrays.asList(BarcodeFormat.DATA_MATRIX));

        decode(image, hints);

    }

    public static void decode(BufferedImage tmpBfrImage, Hashtable<DecodeHintType, Object> hintsMap) {
        if (tmpBfrImage == null)
            throw new IllegalArgumentException("Could not decode image.");
        LuminanceSource tmpSource = new BufferedImageLuminanceSource(tmpBfrImage);
        BinaryBitmap tmpBitmap = new BinaryBitmap(new HybridBinarizer(tmpSource));
        MultiFormatReader tmpBarcodeReader = new MultiFormatReader();

        Result tmpResult;
        String tmpFinalResult;
        try {

            if (hintsMap != null && !hintsMap.isEmpty())
                tmpResult = tmpBarcodeReader.decode(tmpBitmap, hintsMap);
            else
                tmpResult = tmpBarcodeReader.decode(tmpBitmap);

            // setting results.
            tmpFinalResult = String.valueOf(tmpResult.getText());
            System.out.println("tmpFinalResult=" + tmpFinalResult);
        } catch (Exception tmpExcpt) {
            tmpExcpt.printStackTrace();
        }
    }

}

и изображения, найденные на net:

sfr-facture-1048469311-1.jpg sfr-facture-1048469311-1.png

Но я получаю это исключение независимо от формата изображения: com .google.zxing.NotFoundException

Можете ли вы посоветовать мне библиотеку, которая будет анализировать страницу и определять координаты матрицы данных для предварительной обработки перед обработкой?

Или лучше пример кода, который читает datamatrix?

Спасибо,

FJ.

1 Ответ

0 голосов
/ 08 апреля 2020

У меня есть решение моей проблемы. Я использую opencv, чтобы найти любой штрих-код, затем, после извлечения в соответствии с возвращенными координатами, я читаю их с помощью zxing.

Я основал свое решение на работе http://karthikj1.github.io/BarcodeLocalizer/

этот код, который я использую:

import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.EnumMap;
import java.util.List;
import java.util.Map;

import com.google.zxing.BinaryBitmap;
import com.google.zxing.DecodeHintType;
import com.google.zxing.LuminanceSource;
import com.google.zxing.MultiFormatReader;
import com.google.zxing.Reader;
import com.google.zxing.ReaderException;
import com.google.zxing.Result;
import com.google.zxing.client.j2se.BufferedImageLuminanceSource;
import com.google.zxing.common.HybridBinarizer;

import barcodelocalizer.Barcode;
import barcodelocalizer.CandidateResult;
import barcodelocalizer.ImageDisplay;
import barcodelocalizer.MatrixBarcode;
import barcodelocalizer.TryHarderFlags;

public class OpencvUtils {

    private static boolean SHOW_INTERMEDIATE_STEPS = false;
    private static boolean showImages = false;

    public static String process_bufferedImage(BufferedImage bufferedImage) {
        Barcode barcode;

        String barcodeText = null;

        // instantiate a class of type MatrixBarcode with the image filename
        try {
            barcode = new MatrixBarcode(bufferedImage, SHOW_INTERMEDIATE_STEPS, TryHarderFlags.VERY_SMALL_MATRIX);

            // locateBarcode() returns a List<CandidateResult> with all possible candidate
            // barcode regions from
            // within the image. These images then get passed to a decoder(we use ZXing here
            // but could be any decoder)
            List<CandidateResult> results = barcode.locateBarcode();
            System.out.println("Decoding buffered image " + results.size() + " candidate codes found");

            String barcodeName = barcode.getName();

            barcodeText = decodeBarcode(results, barcodeName, "Localizer");

        } catch (IOException ioe) {
            System.out.println("IO Exception when finding barcode " + ioe.getMessage());
        }

        return barcodeText;
    }

    public static String process_image(String imgFile) {
        Barcode barcode;

        String barcodeText = null;

        // instantiate a class of type MatrixBarcode with the image filename
        try {
            barcode = new MatrixBarcode(imgFile, SHOW_INTERMEDIATE_STEPS, TryHarderFlags.VERY_SMALL_MATRIX);

            // locateBarcode() returns a List<CandidateResult> with all possible candidate
            // barcode regions from
            // within the image. These images then get passed to a decoder(we use ZXing here
            // but could be any decoder)
            List<CandidateResult> results = barcode.locateBarcode();
            System.out.println("Decoding " + imgFile + " " + results.size() + " candidate codes found");

            String barcodeName = barcode.getName();

            barcodeText = decodeBarcode(results, barcodeName, "Localizer");

        } catch (IOException ioe) {
            System.out.println("IO Exception when finding barcode " + ioe.getMessage());
        }

        return barcodeText;
    }

    private static String decodeBarcode(List<CandidateResult> candidateCodes, String filename, String caption) {
        // decodes barcode using ZXing and either print the barcode text or says no
        // barcode found
        BufferedImage decodedBarcode = null;
        String title = null;
        Result result = null;

        String barcodeText = null;

        for (CandidateResult cr : candidateCodes) {
            BufferedImage candidate = cr.candidate;
            decodedBarcode = null;
            LuminanceSource source = new BufferedImageLuminanceSource(candidate);
            BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));
            Reader reader = new MultiFormatReader();

            Map<DecodeHintType, Object> hints = new EnumMap<>(DecodeHintType.class);
            hints.put(DecodeHintType.TRY_HARDER, Boolean.TRUE);

            try {
                result = reader.decode(bitmap, hints);
                decodedBarcode = candidate;
                title = filename + " " + caption + " - barcode text " + result.getText() + " " + cr.getROI_coords();
            } catch (ReaderException re) {
            }
            if (decodedBarcode == null) {
                title = filename + " - no barcode found - " + cr.getROI_coords();
                if (showImages)
                    ImageDisplay.showImageFrame(candidate, title);
            } else {
                if (showImages)
                    ImageDisplay.showImageFrame(decodedBarcode, title);

                System.out.println("Barcode text for " + filename + " is " + result.getText());
                barcodeText = result.getText();
            }
        }

        return barcodeText;

    }

}

я добавил метод process_bufferedImage, который обрабатывает java .awt.image.BufferedImage строкового имени файла.

И этот суб-метод для получить матрицу BufferedImage bi.

protected Mat loadBufferedImage(BufferedImage bi) throws IOException {
        // reads the BufferedImage passed in parameter
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        ImageIO.write(bi, "png", byteArrayOutputStream);
        byteArrayOutputStream.flush();

        Mat mat = Imgcodecs.imdecode(new MatOfByte(byteArrayOutputStream.toByteArray()), Imgcodecs.IMREAD_UNCHANGED);

        return mat;
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...