Anonymous
Рисование ограничивающих рамок на штрих-коде Сканер штрих-кода MLKit
Сообщение
Anonymous » 28 ноя 2024, 08:16
Я работаю над простым сканером штрих-кода, используя сканер штрих-кодов Google MLkit и API cameraX. Но ограничивающие рамки неправильно отображают штрих-коды. Я пробовал много вещей, таких как преобразование координат и т. д., но не помогло:
Изображения прилагаются.
[img]https: //i.sstatic.net/LhZvcaNd.jpg[/img]
Код:
BarcodeScannerActivity
Код: Выделить всё
public class BarcodeScannerActivity extends AppCompatActivity {
private static final int REQUEST_CAMERA_PERMISSION = 1001;
private ExecutorService cameraExecutor;
private static final String TAG = "BarcodeScannerActivity";
private int currentOrientation = 0; // 0: portrait, 1: landscape
private BarcodeOverlay barcodeOverlay;
private PreviewView previewView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_barcode_scanner);
previewView = findViewById(R.id.previewView);
barcodeOverlay = findViewById(R.id.barcodeOverlay);
if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA)
== PackageManager.PERMISSION_GRANTED) {
startCamera();
} else {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CAMERA}, REQUEST_CAMERA_PERMISSION);
}
cameraExecutor = Executors.newSingleThreadExecutor();
// Set up orientation listener
OrientationEventListener orientationEventListener = new OrientationEventListener(this) {
@Override
public void onOrientationChanged(int orientation) {
// Update orientation state based on the device's orientation
if ((orientation >= 0 && orientation < 45) || (orientation >= 315)) {
currentOrientation = 0; // Portrait
} else if (orientation >= 135 && orientation < 225) {
currentOrientation = 1; // Landscape
}
}
};
orientationEventListener.enable();
}
private void startCamera() {
ListenableFuture
cameraProviderFuture = ProcessCameraProvider.getInstance(this);
cameraProviderFuture.addListener(() -> {
try {
ProcessCameraProvider cameraProvider = cameraProviderFuture.get();
bindCameraUseCases(cameraProvider);
} catch (Exception e) {
Log.e(TAG, "Camera provider failed.", e);
}
}, ContextCompat.getMainExecutor(this));
}
private void bindCameraUseCases(@NonNull ProcessCameraProvider cameraProvider) {
// PreviewView previewView = findViewById(R.id.previewView);
// Camera selector for the back camera
CameraSelector cameraSelector = new CameraSelector.Builder()
.requireLensFacing(CameraSelector.LENS_FACING_BACK)
.build();
// Preview use case
Preview preview = new Preview.Builder().build();
preview.setSurfaceProvider(previewView.getSurfaceProvider());
// Image analysis use case
ImageAnalysis imageAnalysis = new ImageAnalysis.Builder()
.setBackpressureStrategy(ImageAnalysis.STRATEGY_KEEP_ONLY_LATEST)
.build();
BarcodeScannerOptions options = new BarcodeScannerOptions.Builder()
.setBarcodeFormats(Barcode.FORMAT_ALL_FORMATS)
.build();
BarcodeScanner scanner = BarcodeScanning.getClient(options);
imageAnalysis.setAnalyzer(cameraExecutor, image -> processImageProxy(scanner, image));
// Bind to lifecycle
cameraProvider.bindToLifecycle(
(LifecycleOwner) this,
cameraSelector,
preview,
imageAnalysis
);
}
private void processImageProxy(BarcodeScanner scanner, ImageProxy imageProxy) {
@SuppressWarnings("UnsafeOptInUsageError")
InputImage image = InputImage.fromMediaImage(imageProxy.getImage(), imageProxy.getImageInfo().getRotationDegrees());
scanner.process(image)
.addOnSuccessListener(barcodes -> {
if (!barcodes.isEmpty()) {
// Map all barcode bounding boxes to the view coordinates
List mappedBoundingBoxes = new ArrayList();
for (com.google.mlkit.vision.barcode.common.Barcode barcode : barcodes) {
Rect boundingBox = barcode.getBoundingBox();
if (boundingBox != null) {
Rect rect = mapBoundingBoxToView(boundingBox, imageProxy);
mappedBoundingBoxes.add(rect);
}
}
// Update the overlay with all mapped bounding boxes
barcodeOverlay.updateBarcodes(mappedBoundingBoxes);
}
})
.addOnFailureListener(e -> Log.e(TAG, "Barcode detection failed.", e))
.addOnCompleteListener(task -> imageProxy.close());
}
public Rect mapBoundingBoxToView(Rect boundingBox, ImageProxy imageProxy) {
int imageWidth = imageProxy.getWidth();
int imageHeight = imageProxy.getHeight();
int viewWidth = previewView.getWidth();
int viewHeight = previewView.getHeight();
float scaleX = (float) viewWidth / imageHeight;
float scaleY = (float) viewHeight / imageWidth;
float offsetX = (viewWidth - imageHeight * scaleX) / 2;
float offsetY = (viewHeight - imageWidth * scaleY) / 2;
int left = (int) (boundingBox.left * scaleX + offsetX);
int top = (int) (boundingBox.top * scaleY + offsetY);
int right = (int) (boundingBox.right * scaleX + offsetX);
int bottom = (int) (boundingBox.bottom * scaleY + offsetY);
return new Rect(left, top, right, bottom);
}
@Override
protected void onDestroy() {
super.onDestroy();
cameraExecutor.shutdown();
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == REQUEST_CAMERA_PERMISSION) {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
startCamera();
} else {
Toast.makeText(this, "Camera permission denied", Toast.LENGTH_SHORT).show();
}
}
}
}
Класс BarcodeOverlay
Код: Выделить всё
public class BarcodeOverlay extends View {
private final Paint paint = new Paint();
private List barcodeRects = new ArrayList();
public BarcodeOverlay(Context context, AttributeSet attrs) {
super(context, attrs);
paint.setColor(Color.RED);
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(5f);
}
public void updateBarcodes(List newBarcodeRects) {
barcodeRects = newBarcodeRects;
invalidate(); // Trigger a redraw
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
for (Rect rect : barcodeRects) {
canvas.drawRect(rect, paint);
}
}
}
Пожалуйста, помогите!
Я хочу отсканировать штрих-код и нарисовать ограничивающие рамки, но прямоугольники не отображаются на штрих-коде правильно.>
Подробнее здесь:
https://stackoverflow.com/questions/792 ... de-scanner
1732771016
Anonymous
Я работаю над простым сканером штрих-кода, используя сканер штрих-кодов Google MLkit и API cameraX. Но ограничивающие рамки неправильно отображают штрих-коды. Я пробовал много вещей, таких как преобразование координат и т. д., но не помогло: Изображения прилагаются. [img]https: //i.sstatic.net/LhZvcaNd.jpg[/img] Код: BarcodeScannerActivity [code]public class BarcodeScannerActivity extends AppCompatActivity { private static final int REQUEST_CAMERA_PERMISSION = 1001; private ExecutorService cameraExecutor; private static final String TAG = "BarcodeScannerActivity"; private int currentOrientation = 0; // 0: portrait, 1: landscape private BarcodeOverlay barcodeOverlay; private PreviewView previewView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_barcode_scanner); previewView = findViewById(R.id.previewView); barcodeOverlay = findViewById(R.id.barcodeOverlay); if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED) { startCamera(); } else { ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CAMERA}, REQUEST_CAMERA_PERMISSION); } cameraExecutor = Executors.newSingleThreadExecutor(); // Set up orientation listener OrientationEventListener orientationEventListener = new OrientationEventListener(this) { @Override public void onOrientationChanged(int orientation) { // Update orientation state based on the device's orientation if ((orientation >= 0 && orientation < 45) || (orientation >= 315)) { currentOrientation = 0; // Portrait } else if (orientation >= 135 && orientation < 225) { currentOrientation = 1; // Landscape } } }; orientationEventListener.enable(); } private void startCamera() { ListenableFuture cameraProviderFuture = ProcessCameraProvider.getInstance(this); cameraProviderFuture.addListener(() -> { try { ProcessCameraProvider cameraProvider = cameraProviderFuture.get(); bindCameraUseCases(cameraProvider); } catch (Exception e) { Log.e(TAG, "Camera provider failed.", e); } }, ContextCompat.getMainExecutor(this)); } private void bindCameraUseCases(@NonNull ProcessCameraProvider cameraProvider) { // PreviewView previewView = findViewById(R.id.previewView); // Camera selector for the back camera CameraSelector cameraSelector = new CameraSelector.Builder() .requireLensFacing(CameraSelector.LENS_FACING_BACK) .build(); // Preview use case Preview preview = new Preview.Builder().build(); preview.setSurfaceProvider(previewView.getSurfaceProvider()); // Image analysis use case ImageAnalysis imageAnalysis = new ImageAnalysis.Builder() .setBackpressureStrategy(ImageAnalysis.STRATEGY_KEEP_ONLY_LATEST) .build(); BarcodeScannerOptions options = new BarcodeScannerOptions.Builder() .setBarcodeFormats(Barcode.FORMAT_ALL_FORMATS) .build(); BarcodeScanner scanner = BarcodeScanning.getClient(options); imageAnalysis.setAnalyzer(cameraExecutor, image -> processImageProxy(scanner, image)); // Bind to lifecycle cameraProvider.bindToLifecycle( (LifecycleOwner) this, cameraSelector, preview, imageAnalysis ); } private void processImageProxy(BarcodeScanner scanner, ImageProxy imageProxy) { @SuppressWarnings("UnsafeOptInUsageError") InputImage image = InputImage.fromMediaImage(imageProxy.getImage(), imageProxy.getImageInfo().getRotationDegrees()); scanner.process(image) .addOnSuccessListener(barcodes -> { if (!barcodes.isEmpty()) { // Map all barcode bounding boxes to the view coordinates List mappedBoundingBoxes = new ArrayList(); for (com.google.mlkit.vision.barcode.common.Barcode barcode : barcodes) { Rect boundingBox = barcode.getBoundingBox(); if (boundingBox != null) { Rect rect = mapBoundingBoxToView(boundingBox, imageProxy); mappedBoundingBoxes.add(rect); } } // Update the overlay with all mapped bounding boxes barcodeOverlay.updateBarcodes(mappedBoundingBoxes); } }) .addOnFailureListener(e -> Log.e(TAG, "Barcode detection failed.", e)) .addOnCompleteListener(task -> imageProxy.close()); } public Rect mapBoundingBoxToView(Rect boundingBox, ImageProxy imageProxy) { int imageWidth = imageProxy.getWidth(); int imageHeight = imageProxy.getHeight(); int viewWidth = previewView.getWidth(); int viewHeight = previewView.getHeight(); float scaleX = (float) viewWidth / imageHeight; float scaleY = (float) viewHeight / imageWidth; float offsetX = (viewWidth - imageHeight * scaleX) / 2; float offsetY = (viewHeight - imageWidth * scaleY) / 2; int left = (int) (boundingBox.left * scaleX + offsetX); int top = (int) (boundingBox.top * scaleY + offsetY); int right = (int) (boundingBox.right * scaleX + offsetX); int bottom = (int) (boundingBox.bottom * scaleY + offsetY); return new Rect(left, top, right, bottom); } @Override protected void onDestroy() { super.onDestroy(); cameraExecutor.shutdown(); } @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); if (requestCode == REQUEST_CAMERA_PERMISSION) { if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { startCamera(); } else { Toast.makeText(this, "Camera permission denied", Toast.LENGTH_SHORT).show(); } } } } [/code] Класс BarcodeOverlay [code]public class BarcodeOverlay extends View { private final Paint paint = new Paint(); private List barcodeRects = new ArrayList(); public BarcodeOverlay(Context context, AttributeSet attrs) { super(context, attrs); paint.setColor(Color.RED); paint.setStyle(Paint.Style.STROKE); paint.setStrokeWidth(5f); } public void updateBarcodes(List newBarcodeRects) { barcodeRects = newBarcodeRects; invalidate(); // Trigger a redraw } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); for (Rect rect : barcodeRects) { canvas.drawRect(rect, paint); } } } [/code] [code] [/code] Пожалуйста, помогите! Я хочу отсканировать штрих-код и нарисовать ограничивающие рамки, но прямоугольники не отображаются на штрих-коде правильно.> Подробнее здесь: [url]https://stackoverflow.com/questions/79232660/drawing-bounding-boxes-on-barcode-mlkit-barcode-scanner[/url]