1

以下のデータ マトリックスは、バーコード スキャナー、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();
        }
    }

}

サンプルバーコード

4

2 に答える 2

4

複数のレベルで問題がありました。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. 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);
      }
    
    }
    

これらの変更を行った後、データ マトリックス検出は、これらと同じかそれよりも悪い画像に対して機能していました。

于 2016-07-20T09:48:51.670 に答える