首页 > 解决方案 > Barcode Google Vision API 检查检测到的条形码是否在区域内

问题描述

我无法检测条形码是否在指定区域内。出于测试目的,相机源预览和表面视图具有相同的大小1440x1080,以防止相机和视图之间缩放。即使我看到 QR 码不在代表图像的框中,我也会得到肯定的检查。怎么了?

误报检查

误报检查

扫描仪活动

public class ScannerActivity extends AppCompatActivity {
    private static final String TAG = "ScannerActivity";

    private SurfaceView mSurfaceView; // Its size is forced to 1440x1080 in XML
    private CameraSource mCameraSource;
    private ScannerOverlay mScannerOverlay; // Its size is forced to 1440x1080 in XML

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // .. create and init views
        // ...

        BarcodeDetector barcodeDetector = new BarcodeDetector.Builder(this)
                .setBarcodeFormats(Barcode.ALL_FORMATS)
                .build();

        mCameraSource = new CameraSource.Builder(this, barcodeDetector)
                .setRequestedPreviewSize(1440, 1080)
                .setRequestedFps(20.0f)
                .setFacing(CameraSource.CAMERA_FACING_BACK)
                .setAutoFocusEnabled(true)
                .build();

        barcodeDetector.setProcessor(new Detector.Processor<Barcode>() {
            @Override
            public void release() {
            }

            @Override
            public void receiveDetections(Detector.Detections<Barcode> detections) {
                parseDetections(detections.getDetectedItems());
            }
        });

    }

    private void parseDetections(SparseArray<Barcode> barcodes) {
        for (int i = 0; i < barcodes.size(); i++) {
            Barcode barcode = barcodes.valueAt(i);
            if (isInsideBox(barcode)) {
                runOnUiThread(() -> {
                    Toast.makeText(this, "GOT DETECTION: " + barcode.displayValue, Toast.LENGTH_SHORT).show();
                });
            }
        }
    }

    private boolean isInsideBox(Barcode barcode) {
        Rect barcodeBoundingBox = barcode.getBoundingBox();
        Rect scanBoundingBox = mScannerOverlay.getBox();

        boolean checkResult = barcodeBoundingBox.left >= scanBoundingBox.left &&
                barcodeBoundingBox.right <= scanBoundingBox.right &&
                barcodeBoundingBox.top >= scanBoundingBox.top &&
                barcodeBoundingBox.bottom <= scanBoundingBox.bottom;

        Log.d(TAG, "isInsideBox: "+(checkResult ? "YES" : "NO"));
        return checkResult;
    }
}

标签: javaandroidbarcode

解决方案


对您的问题的解释很简单,但解决方案并非易事。

UI 中框的坐标与每个预览帧上的假想框大多不同。您必须将坐标从 UI 框转换为 scanBoundingBox。

我开源了一个示例,该示例实现了您尝试完成的相同用例。在这个例子中,我采用了另一种方法,在将其输入到 Google Vision 之前,我先从每一帧中切出框,这也更有效,因为 Google Vision 不必分析整个图片并浪费大量 CPU...


推荐阅读