从 JAVA 图像中读取条码

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/19874557/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-12 20:58:21  来源:igfitidea点击:

Read barcode from an image in JAVA

javaimage

提问by chaitanya89

I have a java application which requires to read bar-code from an image to java program. I was very impressed with zxinglibrary which is able to retrieve bar-codes, But not for all the images(I mean if the image quality is slightly poor.).

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

My question is, What is the most preferable image format to read bar-codes? JPEG or PNG? I'm currently trying JPEG images.

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

And another question, What is the most reliable java API/SDK to retrieve bar-codes from images. I already tried, Accusoft, DataSymbol, AtalaSoft, j4lwhich are paid versions. And have gone through few open sources like Ron Cemer JavaBar. But still I'm looking for a JAVA API/SDK which gives accurate results in bar-code reading.

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

Your information regarding Barcode Reader JAVA APIs/SDKs would be really helpful for me.

您关于条码阅读器 JAVA API/SDK 的信息对我真的很有帮助。

回答by constantlearner

JavaBar is one more thing you can consider it is open source and has good reviews

JavaBar 是另外一件事,您可以认为它是开源的并且有很好的评价

回答by chaitanya89

Recently, I found this software zbarwhich gave promising results in reading bar-codes. It has an option of decoding the bar-code from command prompt. Since, it's not an SDK or API. So, I did a trick to read barcodes from an image by java program.

最近,我发现了这个软件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");

}
}

Hope, this might be helpful for anyone who's trying to read barcode from an image in JAVA.

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

Note: it also works for Linux. I tested it. For linux environment, all you need to do is, run this command.

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

sudo apt-get install zbar-tools

sudo apt-get install zbar-tools

and in Java program, change your code like this,

在 Java 程序中,像这样更改代码,

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

And it works very fine.

它工作得很好。

If you guys come across any other barcode reading SDKs or APIs or Softwares which can run on command line, Please leave an answer.

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

回答by Tom Setzer

JPEG is a lossy compression and, depending on the level of compression, the resolution of the image and the quality of the image (lighting, contrast, etc) the artifacts introduced by JPEG compression couldinterfere with the reading of the barcode.

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

PNG is lossless. It will result in a larger file, but won't add additional challenges (artifacts) for the barcode engine to read.

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

For accuracy of the barcode engines, this varies widely. Certain engines perform better on certain types of barcodes (e.g. Code 128 vs QR code) and on the image quality issues (low resolution vs poor contrast). If you have a wide variety of image quality problems because you can't control the source of the images, you will likely need to go with a commercial engine in order to achieve highest results.
One option for improving results is some image processing prior to sending into the engine. Try to scale the image up prior to going from Gray/Color to Black and White. A better binarization (gray to b&w) than what is provided in the engine can also help.

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

Full disclosure, I work for Accusoft, a barcode SDK provider.

完全公开,我在 Accusoft 工作,这是一家条形码 SDK 提供商。

回答by kevto

@Tom Setzer's solution is great if you don't mind paying a little extra for your project. However, if you don't have the budget to get such software, I'd still recommend to listen to Tom's answer.

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

One option for improving results is some image processing prior to sending into the engine. Try to scale the image up prior to going from Gray/Color to Black and White. A better binarization (gray to b&w) than what is provided in the engine can also help.

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

He's right but I'm still using ZXing. It works great only ifyou do some image processing before you attempt to read the barcode.

他是对的,但我仍在使用 ZXing。只有在您尝试读取条形码之前进行一些图像处理时,它才能很好地工作。

I'm using OpenCV for image processing. A great native library that works both for Linux and Windows and probably some other platforms as well (haven't looked into that).

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

This is the way I do it.

这就是我这样做的方式。

  1. Convert to the image to grayscale.
  2. Resize barcode up to 4 times in height and 8 times in width.
  3. Apply gaussian blur with the size of 17x17 pixels.
  4. Apply binary threshold with the threshold value of 225 and maximum value of 255.
  1. 将图像转换为灰度。
  2. 将条码的高度调整为 4 倍,宽度调整为 8 倍。
  3. 应用大小为 17x17 像素的高斯模糊。
  4. 应用阈值为 225,最大值为 255 的二进制阈值。

After following these steps, you'd be getting better results.

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



Resources:

资源:

回答by kinjelom

Java Apache Camel Barcodebased on the zxing libraryworks great:

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

Dependency

依赖

<!-- 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>

Some example (with rotating if needed)

一些示例(如果需要,可以旋转)

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

回答by lo?c

I recently had the same problem: using the ZXing library in a Java application I was decoding QR codes but we often had to process scans of prints with low quality and the rate of recognition of the QR codes needed to be improved. I am adding my findings here in the hope it will help somebody who faces the same problem.

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

I used the ImageJ image processing library. It is quite extensive and actually a complete program with a GUI and many plugins. I only used the api:

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

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

The documentationis not so useful, these tutorialswere more interesting.

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

I had to hunt for the javadocs of the API, you can find them here

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

So I tried a bunch of image optimization and enhancing, but nothing really seemed to have a positive effect. Cutting out a subimage where the QR code was placed on the scan sped up the process a lot though.

所以我尝试了一系列图像优化和增强,但似乎没有任何真正的积极效果。不过,在扫描件上切下二维码的子图像可以大大加快这个过程。

Then I tried the suggestions of user @kevto in another comment here (thanks!)

然后我在这里的另一条评论中尝试了用户@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.
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.

The image was already grayscale so that did not effect the recognition rate of the QR codes. The last suggestion did not seem to do much either. The second one is a bit strange : resizing with different parameters for width and height stretched out the image and resulted in unrecognizable QR codes. The third suggestion was what I was searching for : adding gaussian blur dramatically increased the recognition rate of QR codes when working with lower quality scans. Adding blur to QR codes of high quality scans lowered the recognition rate, so take care.

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

Resulted in this code:

导致此代码:

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

I tried a lot of values for the sigma of the blur function. Values between 1.5 and 2.5 gave the best results.

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

So I perform two passes at recognizing the QR code : once like I did before (gets the high quality images) and then once with the extra processing (for the lower quality images)

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