【问题标题】:Read barcode from an image in JAVA从 JAVA 中的图像中读取条形码
【发布时间】:2013-11-21 09:04:09
【问题描述】:

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

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

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

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

【问题讨论】:

  • 这是 OCR 的东西,很难做到,通常最有效的库是付费版本。如果你正在寻找最好的性能,也许你应该看看 ABBYY FineReader,它可以读取条码并且有很好的声誉,但它是 C 库 + JNI。

标签: java image


【解决方案1】:

JavaBar 是另一件你可以认为它是开源且好评如潮的东西

【讨论】:

    【解决方案2】:

    最近,我发现了这个软件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 或软件,请留下答案。

    【讨论】:

      【解决方案3】:

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

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

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

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

      【讨论】:

        【解决方案4】:

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

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

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

        我正在使用 OpenCV 进行图像处理。一个很棒的原生库,适用于 Linux 和 Windows,可能也适用于其他一些平台(尚未研究)。

        我就是这样做的。

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

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


        资源:

        【讨论】:

          【解决方案5】:

          基于zxing library 的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);
                  }
              }
          }
          

          【讨论】:

          【解决方案6】:

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

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

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

          documentation 没那么有用,these tutorials 更有趣。

          我不得不寻找 API 的 javadocs,你可以找到它们here

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

          然后我在这里的另一条评论中尝试了用户@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 之间的值给出了最好的结果。

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

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2015-10-05
            • 2013-07-20
            • 2023-04-08
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2010-09-11
            相关资源
            最近更新 更多