Android视觉技术 - 缩小条形码跟踪窗口

12

我正在尝试将Google Vision扫描仪集成到一个应用程序中。默认情况下,它是全屏活动,并且条形码在整个屏幕上被跟踪。

然而,我需要一个全屏相机,但具有有限的扫描窗口。例如,相机的表面视图需要全屏显示,它有两个透明覆盖层设置为屏幕高度的35%,顶部和底部分别留下30%的视口。

我已更改了图形覆盖层,使其仅在中央视口中显示,但一直无法找出如何将条形码跟踪器限制在相同区域内。

有什么想法吗?


请问您能否分享一下您如何使用透明覆盖层的代码?您是否显示一个矩形或正方形?如果是,您是如何实现的呢?我正在苦苦思索这个问题,非常感谢您能帮助我。 - Vincy
2个回答

11

目前的API没有提供限制扫描区域的方法。然而,您可以过滤掉检测器输出的结果,或者裁剪传递给检测器的图像,从而实现限制扫描区域的效果。

过滤结果方法

使用此方法,条码检测器仍将扫描整个图像区域,但在目标区域之外检测到的条码将被忽略。一种方法是实现一个“聚焦处理器”,该处理器接收来自检测器的结果,并且最多只传递一个条码给您的相关跟踪器。例如:

public class CentralBarcodeFocusingProcessor extends FocusingProcessor<Barcode> {

  public CentralBarcodeFocusingProcessor(Detector<Barcode> detector, Tracker<Barcode> tracker) {
    super(detector, tracker);
  }

  @Override
  public int selectFocus(Detections<Barcode> detections) {
    SparseArray<Barcode> barcodes = detections.getDetectedItems();
    for (int i = 0; i < barcodes.size(); ++i) {
      int id = barcodes.keyAt(i);
      if (/* barcode in central region */) {
        return id;
      }
    }
    return -1;
  }
}
你可以将这个处理器与探测器关联起来,方法如下:
   BarcodeDetector barcodeDetector = new BarcodeDetector.Builder(context).build();
   barcodeDetector.setProcessor(
                new CentralBarcodeFocusingProcessor(myTracker));

裁剪图像的方法

在调用检测器之前,您需要先自行裁剪图像。这可以通过实现一个 Detector 子类来完成,该子类包装条形码检测器,对接收到的图像进行裁剪,并使用裁剪后的图像调用条形码扫描器。

例如,您可以创建一个检测器来拦截和裁剪图像,如下所示:

class MyDetector extends Detector<Barcode> {
  private Detector<Barcode> mDelegate;

  MyDetector(Detector<Barcode> delegate) {
    mDelegate = delegate;
  }

  public SparseArray<Barcode> detect(Frame frame) {
    // *** crop the frame here
    return mDelegate.detect(croppedFrame);
  }

  public boolean isOperational() {
    return mDelegate.isOperational();
  }

  public boolean setFocus(int id) {
    return mDelegate.setFocus(id);
  }
} 
你需要用这个包装条形码检测器,将其放置在相机源和条形码检测器之间:


BarcodeDetector barcodeDetector = new BarcodeDetector.Builder(context)
        .build();
MyDetector myDetector = new MyDetector(barcodeDetector);

myDetector.setProcessor(/* include your processor here */);

mCameraSource = new CameraSource.Builder(context, myDetector)
        .build();

最终我得出了相同的结论,但在将图像插入输出框架之前尝试裁剪图像。然后我遇到的问题是将YUV转换为位图。最终我时间不够了,发现dm77条形码扫描仪更适合定制。感谢您的输入^^ - devchimp
3
你如何确定在CentralFocusingProcessor内部条形码的位置? - JPM
2
@pm0733464 你有任何样本代码吗?我们缺少这个代码。如果(/* 在中央区域的条形码 */){ 返回id; } - Android Developer World
2
中央地区的条形码如何识别,有任何更新吗? - Snake
1
@pm0733464,您能否提供一个包含上述代码的示例应用程序?这将非常有帮助。谢谢。 - Nishant
显示剩余2条评论

7

根据@pm0733464的答案,提供了一个示例来获取最接近预览中心的条形码。

public class CentralBarcodeFocusingProcessor extends FocusingProcessor<Barcode> {

    public CentralBarcodeFocusingProcessor(Detector<Barcode> detector, Tracker<Barcode> tracker) {
        super(detector, tracker);
    }

    @Override
    public int selectFocus(Detector.Detections<Barcode> detections) {

        SparseArray<Barcode> barcodes = detections.getDetectedItems();
        Frame.Metadata meta = detections.getFrameMetadata();
        double nearestDistance = Double.MAX_VALUE;
        int id = -1;

        for (int i = 0; i < barcodes.size(); ++i) {
            int tempId = barcodes.keyAt(i);
            Barcode barcode = barcodes.get(tempId);
            float dx = Math.abs((meta.getWidth() / 2) - barcode.getBoundingBox().centerX());
            float dy = Math.abs((meta.getHeight() / 2) - barcode.getBoundingBox().centerY());

            double distanceFromCenter =  Math.sqrt((dx * dx) + (dy * dy));

            if (distanceFromCenter < nearestDistance) {
                id = tempId;
                nearestDistance = distanceFromCenter;
            }
        }
        return id;
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接