读取DataMatrix/QR码 zxing java

And*_*ews 2 java barcode zxing datamatrix

使用条码扫描仪、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();
        }
    }

}
Run Code Online (Sandbox Code Playgroud)

条形码样本

And*_*ews 5

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

  1. 第一个问题是添加以下行作为提示搞砸了识别hintsMap.put(DecodeHintType.PURE_BARCODE, Boolean.FALSE);

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

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

    因此,无论将 PURE_BARCODE 设置为 true 或 false,它都会将其视为 true。理想情况下,提示不应包含密钥。

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

    检测器通过查看每个顶点的黑白过渡数量来识别“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);
      }
    
    }
    
    Run Code Online (Sandbox Code Playgroud)

进行这些更改后,数据矩阵检测适用于与这些图像一样糟糕甚至更差的图像。