【问题标题】:How to pause barcode scanning in android ML-kit when using ByteBuffer from SurfaceView使用 SurfaceView 中的 ByteBuffer 时如何在 android ML-kit 中暂停条码扫描
【发布时间】:2018-07-04 17:10:23
【问题描述】:

上下文

我正在使用 Android firebase-ml-vision 使用带有连续 ByteBuffer 相框的 SurfaceView 扫描条形码。我以ML kit quickstart project 为起点,效果很好。

我的项目的目标是识别与条形码相关的产品并将其添加到扫描项目列表中。

问题

一旦相机对焦,条码处理器会多次检测到同一个条码,因此您将在一秒钟内扫描 20 个而不是 1 个条码。

这是来自CamereSource.FrameProcessingRunnable.run的javadoc

 * As long as the processing thread is active, this executes detection on frames continuously.
 * The next pending frame is either immediately available or hasn't been received yet. Once it
 * is available, we transfer the frame info to local variables and run detection on that frame.
 * It immediately loops back for the next frame without pausing.

我尝试在 FrameProcessingRunnable 中添加“暂停”检查,但我仍然得到至少两次识别相同的条形码,因为下一帧/帧已经被输入以进行检测:

private class FrameProcessingRunnable implements Runnable {
private volatile boolean paused = false;
.
.
.
public void pause() {
  synchronized (lock) {
    this.paused = true;
    lock.notifyAll();
  }
}

public void resume() {
  synchronized (lock) {
    this.paused = false;
    lock.notifyAll();
  }
}

public void run() {
.
.
.
synchronized (processorLock) {
        if (!paused) {
          Log.d(TAG, "Process an image");
          frameProcessor.process(...

使用停止和启动的解决方案

由于无法暂停,我选择在从缓冲区检测到条形码时停止并开始:

private CameraSourcePreview preview;
public void pauseImageProcessing() {
  preview.stop();
  try {
      preview.start(cameraSource, graphicOverlay);
  } catch (IOException e) {
  }
}

这可行,但在再次启动之前大约有 1 秒的延迟,相机开始对焦并且可以检测到下一个条形码。毫无疑问,这种方法也会消耗不必要的资源。你可能会说这很好,但在this video you'll see the difference between the camera scanner with Stop&Start and a Bluetooth scanner

更好的方法

我正在寻找一种解决方案,该解决方案可以在成功检测的帧之后立即丢弃任何帧并重新开始,但到目前为止我失败了。我每秒使用 20 帧。

VissionProcessorBase 确实有节流代码

// Whether we should ignore process(). This is usually caused by feeding input data faster than
// the model can handle.
private final AtomicBoolean shouldThrottle = new AtomicBoolean(false);

但是对于我的需要还远远不够:(

【问题讨论】:

    标签: android firebase surfaceview barcode-scanner firebase-mlkit


    【解决方案1】:

    相机对焦后,条码处理器会多次检测到同一个条码,因此您将扫描 20 个条码而不是 1 个条码 一秒钟。

    VisionProcessorBase.java

    private void detectInVisionImage(
            FirebaseVisionImage image,
            final FrameMetadata metadata) {
    
        detectInImage(image)
                .addOnSuccessListener(
                        new OnSuccessListener<T>() {
                            @Override
                            public void onSuccess(final T results) {
                                new Handler().postDelayed(new Runnable() {
                                    @Override
                                    public void run() {
                                        shouldThrottle.set(false);
                                    }
                                },1000);
    
    
                                VisionProcessorBase.this.onSuccess(results, metadata);
    
                            }
                        })
                .addOnFailureListener(
                        new OnFailureListener() {
                            @Override
                            public void onFailure(@NonNull Exception e) {
                                new Handler().postDelayed(new Runnable() {
                                    @Override
                                    public void run() {
                                        shouldThrottle.set(false);
                                    }
                                },1000);
                                VisionProcessorBase.this.onFailure(e);
                            }
                        });
        // Begin throttling until this frame of input has been processed, either in onSuccess or
        // onFailure.
        shouldThrottle.set(true);
    
    
    
    }
    

    【讨论】:

      【解决方案2】:

      速度减半。

      类变量:

      private var isLocked = true
      

      扫描:

      scanner.process(barcodeImage)
              .addOnSuccessListener { barcodes ->
                      isLocked = !isLocked
                      if (isLocked) return@addOnSuccessListener //<--return here
      
                  barcodes.forEach { barcode ->
                      if (barcode.valueType == Barcode.TYPE_TEXT) {
                          barcode.rawValue?.let { value -> mutableValue.postValue(value) } 
                      }
                  }
              }
              .addOnCompleteListener {
                  image.close()
              }
      

      【讨论】:

        猜你喜欢
        • 2021-12-19
        • 2021-12-31
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-06-24
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多