我正在尝试使用Camera2在android上进行条形码扫描。已经有其他人做过类似的事情,我正在努力让他们为我工作(说实话,这不太好)。
我首先将条形码扫描样本(谷歌视觉)用于常规相机源,然后尝试将其与Ezequiel Adrian Minniti制造的东西(他使它可以同时用于相机和camera2)结合使用。 Ezequil使面部检测器正常工作,我正在尝试将其扩展到与条形码检测器一起使用。我建立起来几乎完全一样,但是没有用。
通过在createCameraSource方法结尾处构建Camera2Source时,只需注释掉我不想使用的条形码,就可以在使用条形码条形码和PreviewFaceDetector之间进行切换。当我使用PreviewFaceDetector时,一切正常。 GraphicFaceTracker中每个新项目的Log.d都会按原样打印。使用条形码检测器时,检测器无响应。摄像头预览正常运行,但没有图形覆盖,没有在BarcodeGraphicTracker中打印新项目,也没有任何迹象表明已找到任何东西。也没有与此相关的错误...
我正在扫描的条形码已在Google视觉示例中进行了尝试(仅使用相机,而不使用camera2),所以我认为那里应该没有问题。 有人可以在这里帮助您找到问题吗?为什么人脸跟踪有效,但条形码跟踪无效?
private void createCameraSource(){
// A barcode detector is created to track barcodes. An associated multi-processor instance
// is set to receive the barcode detection results, track the barcodes, and maintain
// graphics for each barcode on screen. The factory is used by the multi-processor to
// create a separate tracker instance for each barcode.
BarcodeDetector barcodeDetector = new BarcodeDetector.Builder(context).build();
BarcodeTrackerFactory barcodeFactory = new BarcodeTrackerFactory();
if (!barcodeDetector.isOperational()) {
// Note: The first time that an app using the barcode or face API is installed on a
// device, GMS will download a native libraries to the device in order to do detection.
// Usually this completes before the app is run for the first time. But if that
// download has not yet completed, then the above call will not detect any barcodes
// and/or faces.
//
// isOperational() can be used to check if the required native libraries are currently
// available. The detectors will automatically become operational once the library
// downloads complete on device.
Log.w(TAG, "Detector dependencies are not yet available.");
// Check for low storage. If there is low storage, the native library will not be
// downloaded, so detection will not become operational.
IntentFilter lowstorageFilter = new IntentFilter(Intent.ACTION_DEVICE_STORAGE_LOW);
boolean hasLowStorage = registerReceiver(null, lowstorageFilter) != null;
if (hasLowStorage) {
Toast.makeText(context, R.string.low_storage_error, Toast.LENGTH_LONG).show();
Log.w(TAG, getString(R.string.low_storage_error));
}
} else {
barcodeDetector.setProcessor(new MultiProcessor.Builder<>(barcodeFactory).build());
}
FaceDetector previewFaceDetector = new FaceDetector.Builder(context)
.setClassificationType(FaceDetector.ALL_CLASSIFICATIONS)
.setLandmarkType(FaceDetector.ALL_LANDMARKS)
.setMode(FaceDetector.FAST_MODE)
.setProminentFaceOnly(true)
.setTrackingEnabled(true)
.build();
if(previewFaceDetector.isOperational()) {
previewFaceDetector.setProcessor(new MultiProcessor.Builder<>(new GraphicFaceTrackerFactory()).build());
} else {
Toast.makeText(context, "FACE DETECTION NOT AVAILABLE", Toast.LENGTH_SHORT).show();
}
mCameraSource = new Camera2Source.Builder(context, previewFaceDetector)
// mCameraSource = new Camera2Source.Builder(context, barcodeDetector)
.setFocusMode(Camera2Source.CAMERA_AF_CONTINUOUS_PICTURE)
.setFlashMode(Camera2Source.CAMERA_FLASH_ON)
.setFacing(Camera2Source.CAMERA_FACING_BACK)
.build();
startCameraSource();
}
private class GraphicFaceTrackerFactory implements MultiProcessor.Factory<Face> {
@Override
public Tracker<Face> create(Face face) {
return new GraphicFaceTracker(mGraphicOverlay);
}
}
private class BarcodeTrackerFactory implements MultiProcessor.Factory<Barcode> {
@Override
public Tracker<Barcode> create(Barcode barcode) {
return new BarcodeGraphicTracker(mGraphicOverlay);
}
}
private class GraphicFaceTracker extends Tracker<Face> {
private GraphicOverlay mOverlay;
GraphicFaceTracker(GraphicOverlay overlay) {
mOverlay = overlay;
mFaceGraphic = new FaceGraphic(overlay, context);
}
/**
* Start tracking the detected face instance within the face overlay.
*/
@Override
public void onNewItem(int faceId, Face item) {
mFaceGraphic.setId(faceId);
Log.d(TAG, "GraphicFaceTracker new item");
}
/**
* Update the position/characteristics of the face within the overlay.
*/
@Override
public void onUpdate(FaceDetector.Detections<Face> detectionResults, Face face) {
mOverlay.add(mFaceGraphic);
mFaceGraphic.updateFace(face);
}
/**
* Hide the graphic when the corresponding face was not detected. This can happen for
* intermediate frames temporarily (e.g., if the face was momentarily blocked from
* view).
*/
@Override
public void onMissing(FaceDetector.Detections<Face> detectionResults) {
mFaceGraphic.goneFace();
mOverlay.remove(mFaceGraphic);
}
/**
* Called when the face is assumed to be gone for good. Remove the graphic annotation from
* the overlay.
*/
@Override
public void onDone() {
mFaceGraphic.goneFace();
mOverlay.remove(mFaceGraphic);
}
}
private class BarcodeGraphicTracker extends Tracker<Barcode> {
private GraphicOverlay mOverlay;
private BarcodeGraphic mGraphic;
BarcodeGraphicTracker(GraphicOverlay overlay) {
mOverlay = overlay;
mGraphic = new BarcodeGraphic(overlay);
}
/**
* Start tracking the detected item instance within the item overlay.
*/
@Override
public void onNewItem(int id, Barcode item) {
mGraphic.setId(id);
Log.d(TAG, "BarcodeGraphicTracker new item");
}
/**
* Update the position/characteristics of the item within the overlay.
*/
@Override
public void onUpdate(Detector.Detections<Barcode> detectionResults, Barcode item) {
mOverlay.add(mGraphic);
mGraphic.updateItem(item);
}
/**
* Hide the graphic when the corresponding object was not detected. This can happen for
* intermediate frames temporarily, for example if the object was momentarily blocked from
* view.
*/
@Override
public void onMissing(Detector.Detections<Barcode> detectionResults) {
mOverlay.remove(mGraphic);
}
/**
* Called when the item is assumed to be gone for good. Remove the graphic annotation from
* the overlay.
*/
@Override
public void onDone() {
mOverlay.remove(mGraphic);
}
}