【问题标题】:Reading DataMatrix/QR code zxing java读取DataMatrix/QR码zxing java
【发布时间】:2016-07-18 12:57:00
【问题描述】:

使用条形码扫描仪,zxing 移动应用程序可以很好地读取以下数据矩阵。但是,zxing java库没有读取相同的内容。

我注释了一些图像转换代码。即使转换图像、旋转或缩放也无济于事。

理想情况下,我希望以编程方式执行所有可能的图像预处理,直到解码为止。

移动应用程序使用的逻辑是什么,因为我正在从计算机屏幕扫描相同的图像并且它正在工作。

请在下面找到,用于解码的代码。

public class BarcodeReader {

    private static Map<DecodeHintType,Object> hintsMap;

    public static void main(String...args){

         BufferedImage before = null;
         hintsMap = new EnumMap<DecodeHintType, Object>(DecodeHintType.class);
         hintsMap.put(DecodeHintType.TRY_HARDER, Boolean.TRUE);
         hintsMap.put(DecodeHintType.POSSIBLE_FORMATS, EnumSet.allOf(BarcodeFormat.class));
         //hintsMap.put(DecodeHintType.PURE_BARCODE, Boolean.FALSE);
         try 
         {
             before = ImageIO.read(new File("C:/ocr.jpg"));
             decode(before);
            /* for(int i=1; i < 1000;i++){
                 AffineTransform transform = new AffineTransform();
                 double rad = (double)i/100;
                 double scale = (double)i/100;
                 System.out.println("rad "+scale);
                 //transform.rotate(rad, before.getWidth()/2, before.getHeight()/2);
                 transform.scale(scale, scale);
                 BufferedImage after = new BufferedImage(before.getWidth(), before.getHeight(), BufferedImage.TYPE_INT_ARGB);
                 AffineTransformOp op = new AffineTransformOp(transform, AffineTransformOp.TYPE_BILINEAR);
                 after = op.filter(before, after);
                 decode(after);
             }*/


             //tmpBfrImage = tmpBfrImage.getSubimage(200, 100, 800, 800);
         } 
         catch (IOException tmpIoe) 
         {
             tmpIoe.printStackTrace();
         }


    }

    public static void decode(BufferedImage tmpBfrImage){
        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);
            System.exit(0);;
        } 
        catch (Exception tmpExcpt) 
        {
         tmpExcpt.printStackTrace();
        }
    }

}

【问题讨论】:

    标签: java barcode zxing datamatrix


    【解决方案1】:

    我在多个层面都遇到了问题。我从github下载了zxing源码,调试了一下。

    1. 第一个问题是添加以下行,因为提示会破坏识别hintsMap.put(DecodeHintType.PURE_BARCODE, Boolean.FALSE);

      查看他们的 DataMatrixReader 的源代码,有一行这样做

      if (hints != null &amp;&amp; hints.containsKey(DecodeHintType.PURE_BARCODE))

      因此,无论 PURE_BARCODE 设置为真还是假,它都将其视为真。理想情况下,提示不应包含密钥。

    2. 第二个问题是 DataMatrix 检测器的工作方式。

      检测器通过查看每个顶点的黑白过渡数量来识别“L”。理想情况下,从左上角到左下角和左下角到右下角的过渡应该有 0 过渡。

      但是,由于线条更靠近框的外边缘,因此过渡不会变成0。我进行了更改,使其更靠近左黑线和下黑线的中心。这意味着将垂直红线向右移动,底部红线向上移动一点。我添加了一个新方法 Correct Points,它可以进行必要的更正。这种更正对我有用,理想情况下应该使更正更聪明一点。

      ResultPoint pointA = correctPoints(cornerPoints[0], Vertices.TOPLEFT);
      ResultPoint pointB = correctPoints(cornerPoints[1], Vertices.BOTTOMLEFT);
      ResultPoint pointC = correctPoints(cornerPoints[2], Vertices.TOPRIGHT);
      ResultPoint pointD = correctPoints(cornerPoints[3], Vertices.BOTTOMRIGHT);
      
      ---
      ---
      
      private ResultPoint correctPoints(ResultPoint point, Vertices vertice){
        if(vertice.equals(Vertices.TOPLEFT))
            return new ResultPoint(point.getX()+10, point.getY()+5);
        else if(vertice.equals(Vertices.BOTTOMLEFT)){
            return new ResultPoint(point.getX()+10, point.getY()-5);
        }else if(vertice.equals(Vertices.TOPRIGHT)){
            return new ResultPoint(point.getX(), point.getY()+10);
        }else{
            return new ResultPoint(point.getX()-10, point.getY()-5);
        }
      
      }
      

    进行这些更改后,数据矩阵检测对与这些相同甚至更差的图像起作用。

    【讨论】:

    • 感谢分享。你的解码测试有多糟糕?在与带有 ZXing 的 libdmtx 进行比较时(加上您的更改),您是否注意到解码速率和速度的差异?
    【解决方案2】:

    我在使用 ZXing 解码 DataMatrix 条形码时遇到了类似的问题。从我看到的情况来看,ZXing 并没有遍历你发送的整个图像,而是从中间开始向外扩展,直到找到一个条形码。因此,如果 DataMatrix 条码不在图像的中心,ZXing 将无法可靠地找到它。我通过创建图像的不同裁剪版本实现了(一个相当慢的)解决方法来解决这个问题:

    我的核心解码方法与原帖类似。我的图片遍历逻辑如下:

        // Read the original image
        final BufferedImage image = ImageIO.read(...);
        
        final int width = image.getWidth();
        final int height = image.getHeight();
        
        // Try detect codes using different sections of the image.
        //
        // +------+------+
        // |    ##|##    |
        // |    ##|##    |
        // |    ##|##    |
        // +------+------+
        // |      |      |
        // |      |      |
        // |      |      |
        // +------+------+
        // 
        // We create 9 cropped versions of the image, with each cropped
        // version being 1/4 of the original image. We traverse the
        // original image from left-to-right, top-to-bottom, and create
        // 9 sub-images that we try to decode in turn.
        for (int i=0; i<3; i++) {
            for (int j=0; j<3; j++) {
                final int x = i * width / 4;
                final int y = j * height / 4;
                final BufferedImage crop = image.getSubimage(x, y, width / 2, height / 2);
    
                decoded(crop);
            }
        }
    

    【讨论】:

      猜你喜欢
      • 2016-02-22
      • 2017-12-07
      • 2014-04-18
      • 1970-01-01
      • 2022-07-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多