У меня есть решение моей проблемы. Я использую 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;
}