无法使用 Firebase ML Kit 读取更多 30 个字符的条码
Not able to read more 30 chars barcode using Firebase ML Kit
我正在尝试使用独立的 firebase ML 套件读取 barcode128 和 QR 码 API。我能够读取条形码和二维码。但是,如果我的条码长度超过 30-35 个字符,则条码扫描仪无法检测到条码。我可以检测二维码,但不能检测条形码。
这是我的代码:
// Use this dependency to use the dynamically downloaded model in Google Play Services
implementation 'com.google.android.gms:play-services-mlkit-barcode-scanning:16.1.2'
implementation 'com.google.mlkit:barcode-scanning:16.0.3'
扫描仪活动:
executor = Executors.newSingleThreadExecutor();
PreviewView previewView = findViewById(R.id.cameraPreviewView);
cameraProviderFuture = ProcessCameraProvider.getInstance(this);
cameraProviderFuture.addListener(() -> {
try {
ProcessCameraProvider cameraProvider = cameraProviderFuture.get();
Preview preview = new Preview.Builder().build();
CameraSelector cameraSelector = new CameraSelector.Builder()
.requireLensFacing(CameraSelector.LENS_FACING_BACK)
.build();
preview.setSurfaceProvider(
previewView.createSurfaceProvider());
ImageCapture imageCapture = new ImageCapture.Builder()
.setCaptureMode(ImageCapture.CAPTURE_MODE_MINIMIZE_LATENCY)
.build();
ImageAnalysis imageAnalysis =
new ImageAnalysis.Builder()
.build();
imageAnalysis.setAnalyzer(ContextCompat.getMainExecutor(this), new ImageAnalysis.Analyzer() {
private BarcodeScanner scanner = buildBarCodeScanner();
@Override
public void analyze(ImageProxy imageProxy) {
@SuppressLint("UnsafeExperimentalUsageError") Image mediaImage = imageProxy.getImage();
if (mediaImage != null) {
InputImage image =
InputImage.fromMediaImage(mediaImage, imageProxy.getImageInfo().getRotationDegrees());
Task<List<Barcode>> result = scanner.process(image);
result.addOnSuccessListener(new OnSuccessListener<List<Barcode>>() {
@Override
public void onSuccess(List<Barcode> barcodes) {
processBarCodes(barcodes);
}
}).addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
// Task failed with an exception
Log.i("CameraXApp3", "scanner task failed. Error:" + e);
}
}).addOnCompleteListener(new OnCompleteListener<List<Barcode>>() {
@Override
public void onComplete(@NonNull Task<List<Barcode>> task) {
mediaImage.close();
imageProxy.close();
}
});
}
}
private BarcodeScanner buildBarCodeScanner() {
BarcodeScannerOptions options =
new BarcodeScannerOptions.Builder()
.setBarcodeFormats(
Barcode.FORMAT_QR_CODE,
Barcode.FORMAT_CODE_128)
.build();
return BarcodeScanning.getClient(options);
}
private void processBarCodes(List<Barcode> barcodes) {
for (Barcode barcode : barcodes) {
confirmCounter++;
if (confirmCounter >= CONFIRM_VALUE) {
confirmCounter = 0;
final Rect boundingBox = barcode.getBoundingBox();
final Point[] cornerPoints = barcode.getCornerPoints();
String rawValue = barcode.getRawValue();
int valueType = barcode.getValueType();
if (valueType == Barcode.TYPE_TEXT) {
toast(MainActivity.this, "Received Message:" + rawValue);
}
}
}
}
public void toast(final Context context, final String text) {
Handler handler = new Handler(Looper.getMainLooper());
handler.post(() -> Toast.makeText(context, text, Toast.LENGTH_LONG).show());
}
});
Camera camera = cameraProvider.bindToLifecycle(
((LifecycleOwner) this),
cameraSelector,
preview,
imageCapture,
imageAnalysis);
} catch (InterruptedException | ExecutionException e) {
}
}, ContextCompat.getMainExecutor(this));
我也在尝试通过点击来增加焦点,但没有成功:
previewView.setOnTouchListener((v, event) -> {
v.performClick();
if (event.getAction() == MotionEvent.ACTION_UP) {
final MeteringPointFactory factory = previewView.getMeteringPointFactory();
final MeteringPoint point = factory.createPoint(event.getX(), event.getY());
final FocusMeteringAction action = new FocusMeteringAction.Builder(point).build();
camera.getCameraControl().startFocusAndMetering(action);
return false;
}
return true;
});
ML Kit 条形码要求最细条的宽度至少为 3 像素。 Code-128 每个字符是 11 条宽,所以就像素而言它是 33 像素宽,对于 35 个这样的字符,它需要 1155 像素的宽度。因此条形码在图像中至少需要 1155 像素宽。这个粗略的计算忽略了 + + 个字符。
您可能需要提高此格式的图像分辨率。
我正在尝试使用独立的 firebase ML 套件读取 barcode128 和 QR 码 API。我能够读取条形码和二维码。但是,如果我的条码长度超过 30-35 个字符,则条码扫描仪无法检测到条码。我可以检测二维码,但不能检测条形码。
这是我的代码:
// Use this dependency to use the dynamically downloaded model in Google Play Services
implementation 'com.google.android.gms:play-services-mlkit-barcode-scanning:16.1.2'
implementation 'com.google.mlkit:barcode-scanning:16.0.3'
扫描仪活动:
executor = Executors.newSingleThreadExecutor();
PreviewView previewView = findViewById(R.id.cameraPreviewView);
cameraProviderFuture = ProcessCameraProvider.getInstance(this);
cameraProviderFuture.addListener(() -> {
try {
ProcessCameraProvider cameraProvider = cameraProviderFuture.get();
Preview preview = new Preview.Builder().build();
CameraSelector cameraSelector = new CameraSelector.Builder()
.requireLensFacing(CameraSelector.LENS_FACING_BACK)
.build();
preview.setSurfaceProvider(
previewView.createSurfaceProvider());
ImageCapture imageCapture = new ImageCapture.Builder()
.setCaptureMode(ImageCapture.CAPTURE_MODE_MINIMIZE_LATENCY)
.build();
ImageAnalysis imageAnalysis =
new ImageAnalysis.Builder()
.build();
imageAnalysis.setAnalyzer(ContextCompat.getMainExecutor(this), new ImageAnalysis.Analyzer() {
private BarcodeScanner scanner = buildBarCodeScanner();
@Override
public void analyze(ImageProxy imageProxy) {
@SuppressLint("UnsafeExperimentalUsageError") Image mediaImage = imageProxy.getImage();
if (mediaImage != null) {
InputImage image =
InputImage.fromMediaImage(mediaImage, imageProxy.getImageInfo().getRotationDegrees());
Task<List<Barcode>> result = scanner.process(image);
result.addOnSuccessListener(new OnSuccessListener<List<Barcode>>() {
@Override
public void onSuccess(List<Barcode> barcodes) {
processBarCodes(barcodes);
}
}).addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
// Task failed with an exception
Log.i("CameraXApp3", "scanner task failed. Error:" + e);
}
}).addOnCompleteListener(new OnCompleteListener<List<Barcode>>() {
@Override
public void onComplete(@NonNull Task<List<Barcode>> task) {
mediaImage.close();
imageProxy.close();
}
});
}
}
private BarcodeScanner buildBarCodeScanner() {
BarcodeScannerOptions options =
new BarcodeScannerOptions.Builder()
.setBarcodeFormats(
Barcode.FORMAT_QR_CODE,
Barcode.FORMAT_CODE_128)
.build();
return BarcodeScanning.getClient(options);
}
private void processBarCodes(List<Barcode> barcodes) {
for (Barcode barcode : barcodes) {
confirmCounter++;
if (confirmCounter >= CONFIRM_VALUE) {
confirmCounter = 0;
final Rect boundingBox = barcode.getBoundingBox();
final Point[] cornerPoints = barcode.getCornerPoints();
String rawValue = barcode.getRawValue();
int valueType = barcode.getValueType();
if (valueType == Barcode.TYPE_TEXT) {
toast(MainActivity.this, "Received Message:" + rawValue);
}
}
}
}
public void toast(final Context context, final String text) {
Handler handler = new Handler(Looper.getMainLooper());
handler.post(() -> Toast.makeText(context, text, Toast.LENGTH_LONG).show());
}
});
Camera camera = cameraProvider.bindToLifecycle(
((LifecycleOwner) this),
cameraSelector,
preview,
imageCapture,
imageAnalysis);
} catch (InterruptedException | ExecutionException e) {
}
}, ContextCompat.getMainExecutor(this));
我也在尝试通过点击来增加焦点,但没有成功:
previewView.setOnTouchListener((v, event) -> {
v.performClick();
if (event.getAction() == MotionEvent.ACTION_UP) {
final MeteringPointFactory factory = previewView.getMeteringPointFactory();
final MeteringPoint point = factory.createPoint(event.getX(), event.getY());
final FocusMeteringAction action = new FocusMeteringAction.Builder(point).build();
camera.getCameraControl().startFocusAndMetering(action);
return false;
}
return true;
});
ML Kit 条形码要求最细条的宽度至少为 3 像素。 Code-128 每个字符是 11 条宽,所以就像素而言它是 33 像素宽,对于 35 个这样的字符,它需要 1155 像素的宽度。因此条形码在图像中至少需要 1155 像素宽。这个粗略的计算忽略了 + + 个字符。
您可能需要提高此格式的图像分辨率。