问题描述
我正在使用Android firebase-ml-vision 使用带有连续ByteBuffer图片框架的SurfaceView扫描条形码.我以 ML工具包快速入门项目为起点,它的工作原理非常好
I'm using the Android firebase-ml-vision to scan barcodes using SurfaceView with continuous ByteBuffer of pictures frames. I used the ML kit quickstart project as a starting point and it works great.
我的项目的目的是识别与条形码关联的产品,并将其添加到扫描项目列表中.
The objective of my project is to recognise the product associated with the barcode and add it to the list of scanned items.
相机对焦后,条形码处理器会多次检测到相同的条形码,因此您每秒可以扫描20条而不是1条条形码.
Once the camera focuses, the barcode processor would detect the same barcode multiple times, so you would scan 20 rather than 1 barcode in a second.
这是来自 CamereSource.FrameProcessingRunnable.run
* 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中添加一个已暂停"的检查,但是我仍然获得了至少两次被识别的相同条形码,因为已经送入下一个或多个帧进行检测:
I have tried to add a "paused" check into the FrameProcessingRunnable, but I was still getting the same barcode recognised at least twice, as the next frame/frames were already being fed in for detection:
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(...
使用stop&解决方案开始
由于无法暂停,我选择了停止&从缓冲区中检测到条形码时开始:
Solution using stop & start
As I couldn't get it to pause, I opted for stop & start when a barcode is detected from the buffer:
private CameraSourcePreview preview;
public void pauseImageProcessing() {
preview.stop();
try {
preview.start(cameraSource, graphicOverlay);
} catch (IOException e) {
}
}
这可以工作,但是大约需要1秒钟的延迟才能再次启动,相机开始对焦并且可以检测到下一个条形码.毫无疑问,这种方法还会消耗不必要的资源.您可能会说这很好,但是在此视频中,您会看到区别在使用Stop& Start的相机扫描仪和蓝牙扫描仪之间:
This works, but there is about 1 second delay before it starts up again, camera starts focusing and the next barcode can be detected. No doubt this approach also consumes unnecessary resources. You may say this is fine, but in this video you'll see the difference between the camera scanner with Stop&Start and a Bluetooth scanner:
我正在寻找一种解决方案,该解决方案将在成功检测到帧之后立即丢弃所有帧并重新开始,但是到目前为止,我失败了.我每秒使用20帧.
I'm looking for a solution that would simply discard any frames immediately after the one with successful detection and start again, but so far I have failed. I'm using 20 frames per second.
VissionProcessorBase 确实有用于节流的代码
VissionProcessorBase does have code for throttling
// 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);
但是距离我所需要的还远远不够:(
But is doesn't go far enough for my need :(
推荐答案
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);
}
这篇关于从SurfaceView使用ByteBuffer时如何暂停android ML-kit中的条形码扫描的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!