12

我有一个 java 应用程序,它需要从图像读取条形码到 java 程序。能够检索条形码的zxing库给我留下了深刻的印象,但不是针对所有图像(我的意思是如果图像质量稍差。)。

我的问题是,读取条形码最可取的图像格式是什么?JPEG还是PNG?我目前正在尝试JPEG图像。

还有一个问题,从图像中检索条形码的最可靠的 java API/SDK 是什么。我已经尝试过AccusoftDataSymbolAtalaSoftj4l ,它们是付费版本。并且已经通过了一些像Ron Cemer JavaBar这样的开源。但我仍然在寻找一个 JAVA API/SDK,它可以在条形码读取中给出准确的结果。

您有关 Barcode Reader JAVA API/SDK 的信息对我非常有帮助。

4

6 回答 6

6

如果您不介意为您的项目支付一点额外费用,@Tom Setzer 的解决方案非常棒。但是,如果您没有购买此类软件的预算,我仍然建议您听听 Tom 的回答。

改进结果的一种选择是在发送到引擎之前进行一些图像处理。在从灰色/彩色变为黑白之前尝试放大图像。比引擎中提供的更好的二值化(灰色到黑白)也可以提供帮助。

他是对的,但我仍在使用 ZXing。仅当您在尝试读取条形码之前进行一些图像处理时,它才有效。

我正在使用 OpenCV 进行图像处理。一个伟大的本地库,适用于 Linux 和 Windows,也可能适用于其他一些平台(还没有研究过)。

我就是这样做的。

  1. 将图像转换为灰度。
  2. 将条形码大小调整为高度的 4 倍和宽度的 8 倍。
  3. 应用大小为 17x17 像素的高斯模糊。
  4. 应用阈值为 225 和最大值为 255 的二进制阈值。

遵循这些步骤后,您将获得更好的结果。


资源:

于 2016-09-29T08:56:52.830 回答
4

最近,我发现了这个软件zbar,它在读取条形码方面取得了可喜的成果。它具有从命令提示符解码条形码的选项。因为,它不是 SDK 或 API。所以,我做了一个技巧,通过 java 程序从图像中读取条形码。

import java.io.*;

public class BarCodeReader {
public static void main(String args[]) 
{ 
    try 
    { 
        Process p=Runtime.getRuntime().exec("C:/Program Files/ZBar/bin/zbarimg  D:/jpeg/006.jpg"); 
        p.waitFor(); 
        BufferedReader reader=new BufferedReader(
            new InputStreamReader(p.getInputStream())
        ); 
        String line=reader.readLine(); 
        while(line!=null) 
        { 
            System.out.println(line); 
            line=reader.readLine(); 
        } 

    }
    catch(IOException e1) {} 
    catch(InterruptedException e2) {} 

    System.out.println("Done");

}
}

希望,这可能对任何试图从 JAVA 图像中读取条形码的人有所帮助。

注意:它也适用于 Linux。我测试了它。对于 linux 环境,您需要做的就是运行此命令。

sudo apt-get install zbar-tools

在Java程序中,像这样改变你的代码,

Process p=Runtime.getRuntime().exec("zbarimg /opt/images/006.jpg");// your file path.

它工作得很好。

如果你们遇到任何其他可以在命令行上运行的条形码读取 SDK 或 API 或软件,请留下答案。

于 2014-01-30T05:46:43.750 回答
4

基于zxing 库的Java Apache Camel Barcode效果很好:

依赖

<!-- https://mvnrepository.com/artifact/org.apache.camel/camel-barcode -->
<dependency>
    <groupId>org.apache.camel</groupId>
    <artifactId>camel-barcode</artifactId>
    <version>2.21.1</version>
</dependency>

一些例子(如果需要旋转)

import com.google.zxing.BinaryBitmap;
import com.google.zxing.MultiFormatReader;
import com.google.zxing.Reader;
import com.google.zxing.Result;
import com.google.zxing.client.j2se.BufferedImageLuminanceSource;
import com.google.zxing.common.HybridBinarizer;
import lombok.Getter;

import javax.imageio.ImageIO;
import java.io.IOException;
import java.io.InputStream;

public class BarcodeImageDecoder {

    public BarcodeInfo decodeImage(InputStream inputStream) throws BarcodeDecodingException {
        try {
            BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(
                    new BufferedImageLuminanceSource(ImageIO.read(inputStream))));
            if (bitmap.getWidth() < bitmap.getHeight()) {
                if (bitmap.isRotateSupported()) {
                    bitmap = bitmap.rotateCounterClockwise();
                }
            }
            return decode(bitmap);
        } catch (IOException e) {
            throw new BarcodeDecodingException(e);
        }
    }

    private BarcodeInfo decode(BinaryBitmap bitmap) throws BarcodeDecodingException {
        Reader reader = new MultiFormatReader();
        try {
            Result result = reader.decode(bitmap);
            return new BarcodeInfo(result.getText(), result.getBarcodeFormat().toString());
        } catch (Exception e) {
            throw new BarcodeDecodingException(e);
        }
    }

    public static class BarcodeInfo {
        @Getter
        private final String text;
        @Getter
        private final String format;

        BarcodeInfo(String text, String format) {
            this.text = text;
            this.format = format;
        }
    }

    public static class BarcodeDecodingException extends Exception {
        BarcodeDecodingException(Throwable cause) {
            super(cause);
        }
    }
}
于 2018-06-26T18:17:33.553 回答
1

JPEG 是一种有损压缩,根据压缩级别、图像分辨率和图像质量(照明、对比度等),JPEG 压缩引入的伪影可能会干扰条形码的读取。

PNG是无损的。这将导致文件更大,但不会增加条码引擎读取的额外挑战(工件)。

对于条形码引擎的准确性,这变化很大。某些引擎在某些类型的条形码(例如 Code 128 与 QR 码)和图像质量问题(低分辨率与低对比度)上表现更好。如果您因为无法控制图像来源而遇到各种各样的图像质量问题,则可能需要使用商业引擎才能获得最高结果。
改进结果的一种选择是在发送到引擎之前进行一些图像处理。在从灰色/彩色变为黑白之前尝试放大图像。比引擎中提供的更好的二值化(灰色到黑白)也可以提供帮助。

完全披露,我为条形码 SDK 提供商 Accusoft 工作。

于 2015-11-23T17:59:02.583 回答
0

JavaBar 是您可以考虑的另一件事,它是开源的并且有很好的评论

于 2013-11-09T10:10:14.230 回答
0

我最近遇到了同样的问题:在 Java 应用程序中使用 ZXing 库我正在解码 QR 码,但我们经常不得不处理低质量的打印扫描,并且需要提高 QR 码的识别率。我在这里添加我的发现,希望它能帮助面临同样问题的人。

我使用了 ImageJ 图像处理库。它非常广泛,实际上是一个带有 GUI 和许多插件的完整程序。我只使用了api:

    <dependency>
        <groupId>net.imagej</groupId>
        <artifactId>ij</artifactId>
        <version>1.52g</version>
    </dependency>

文档不是那么有用,这些教程更有趣。

我不得不寻找 API 的 javadocs,你可以在这里找到它们

所以我尝试了一堆图像优化和增强,但似乎没有任何积极的效果。剪掉一个扫描二维码的子图像可以大大加快这个过程。

然后我在这里的另一条评论中尝试了用户@kevto 的建议(谢谢!)

Convert to the image to grayscale.
Resize barcode up to 4 times in height and 8 times in width.
Apply gaussian blur with the size of 17x17 pixels.
Apply binary threshold with the threshold value of 225 and maximum value of 255.

图像已经是灰度的,因此不会影响二维码的识别率。最后一个建议似乎也没有多大作用。第二个有点奇怪:使用不同的宽度和高度参数调整大小会拉伸图像并导致无法识别的二维码。第三个建议是我一直在寻找的:添加高斯模糊可以显着提高 QR 码的识别率,因为扫描质量较低。为高质量扫描的二维码添加模糊会降低识别率,所以要小心。

导致此代码:

  public BufferedImage preProcessBufferedImage (BufferedImage bufferedImage)throws IOException{
    //get subimage that cuts out the QR code, speeds up the QR recognition process
    BufferedImage subImage = bufferedImage.getSubimage(x, y,width,height);
    //gaussian blur the result , leads to better QR code recognition
    ImagePlus imagePlus = new ImagePlus("process-qr-code", subImage);
    imagePlus.getProcessor().blurGaussian(2);
    return imagePlus.getBufferedImage();
}

我为模糊函数的 sigma 尝试了很多值。1.5 和 2.5 之间的值给出了最好的结果。

所以我在识别二维码时执行了两次:一次像我之前所做的那样(获得高质量的图像),然后一次进行额外的处理(用于低质量的图像)

于 2018-10-08T07:14:27.350 回答