AndroidX Camera Core ImageAnalysis.Analyser приводит к искаженному изображению - PullRequest
0 голосов
/ 21 апреля 2020

Я использую библиотеку ImageAnalysis для извлечения предварительного просмотра, а затем сканирования штрих-кода и распознавания.

У меня вообще нет проблем со сканированием штрих-кода, но OCR приводит к некоторым слабым результатам. Я уверен, что это может быть из нескольких причин. Моя текущая попытка поработать над решением - отправить фреймы в GCP-Storage до того, как я запустил OCR (или штрих-код) для фреймов, чтобы просмотреть их в большом количестве. Все они выглядят очень похоже:

enter image description here

Мое лучшее предположение состоит в том, что способ обработки кадров может привести к организации пикселей в буфер некорректно (я неопытен до Android - извините). То есть, вместо того, чтобы организовывать 0,0, а потом 0,1 ..... это случайное выделение пикселей и размещение их в случайных областях Я не могу понять, где это происходит, хотя. Как только я посмотрю на качество изображения, я смогу проанализировать, в чем проблема с OCR, но, к сожалению, это мой текущий блокировщик.

Дополнительное примечание: я загружаю изображение в GCP - Хранилище до даже для запуска OCR, поэтому ради этого можно проигнорировать сделанное мной заявление OCR - я просто хотел дать некоторую предысторию.

Ниже приведен код, в котором я запускаю камеру и анализатор, а затем наблюдаю кадры

private void startCamera() {
    //make sure there isn't another camera instance running before starting
    CameraX.unbindAll();

    /* start preview */
    int aspRatioW = txView.getWidth(); //get width of screen
    int aspRatioH = txView.getHeight(); //get height
    Rational asp = new Rational (aspRatioW, aspRatioH); //aspect ratio
    Size screen = new Size(aspRatioW, aspRatioH); //size of the screen

    //config obj for preview/viewfinder thingy.
    PreviewConfig pConfig = new PreviewConfig.Builder().setTargetResolution(screen).build();
    Preview preview = new Preview(pConfig); //lets build it

    preview.setOnPreviewOutputUpdateListener(
            new Preview.OnPreviewOutputUpdateListener() {
                //to update the surface texture we have to destroy it first, then re-add it
                @Override
                public void onUpdated(Preview.PreviewOutput output){
                    ViewGroup parent = (ViewGroup) txView.getParent();
                    parent.removeView(txView);
                    parent.addView(txView, 0);

                    txView.setSurfaceTexture(output.getSurfaceTexture());
                    updateTransform();
                }
            });

    /* image capture */

    //config obj, selected capture mode
    ImageCaptureConfig imgCapConfig = new ImageCaptureConfig.Builder().setCaptureMode(ImageCapture.CaptureMode.MAX_QUALITY)
            .setTargetRotation(getWindowManager().getDefaultDisplay().getRotation()).build();
    final ImageCapture imgCap = new ImageCapture(imgCapConfig);

    findViewById(R.id.imgCapture).setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Log.d("image taken", "image taken");
        }
    });

    /* image analyser */

    ImageAnalysisConfig imgAConfig = new ImageAnalysisConfig.Builder().setImageReaderMode(ImageAnalysis.ImageReaderMode.ACQUIRE_LATEST_IMAGE).build();
    ImageAnalysis analysis = new ImageAnalysis(imgAConfig);


    analysis.setAnalyzer(
            Executors.newSingleThreadExecutor(), new ImageAnalysis.Analyzer(){
                @Override
                public void analyze(ImageProxy imageProxy, int degrees){
                    Log.d("analyze", "just analyzing");
                    if (imageProxy == null || imageProxy.getImage() == null) {
                        return;
                    }
                    Image mediaImage = imageProxy.getImage();
                    int rotation = degreesToFirebaseRotation(degrees);
                    FirebaseVisionImage image = FirebaseVisionImage.fromBitmap(toBitmap(mediaImage));


                    if (!isMachineLearning){
                        Log.d("analyze", "isMachineLearning is about to be true");
                        isMachineLearning = true;
                        String haha = MediaStore.Images.Media.insertImage(getContentResolver(), toBitmap(mediaImage), "image" , "theImageDescription");
                        Log.d("uploadingimage: ", haha);
                        extractBarcode(image, toBitmap(mediaImage));
                    }
                }
            });

    //bind to lifecycle:
    CameraX.bindToLifecycle(this, analysis, imgCap, preview);
}

Ниже показано, как я структурирую свое обнаружение (довольно просто и просто):

FirebaseVisionBarcodeDetectorOptions options = new FirebaseVisionBarcodeDetectorOptions.Builder()
            .setBarcodeFormats(FirebaseVisionBarcode.FORMAT_ALL_FORMATS)
            .build();

FirebaseVisionBarcodeDetector detector = FirebaseVision.getInstance().getVisionBarcodeDetector(options);
detector.detectInImage(firebaseVisionImage)

Наконец, когда я загружаю изображение в GCP - Storage, это как это выглядит:

ByteArrayOutputStream baos = new ByteArrayOutputStream();
bmp.compress(Bitmap.CompressFormat.JPEG, 100, baos); //bmp being the image that I ran barcode scanning on - as well as OCR
byte[] data = baos.toByteArray();

UploadTask uploadTask = storageRef.putBytes(data);

Спасибо всем за помощь (:

1 Ответ

0 голосов
/ 22 апреля 2020

Моя проблема заключалась в том, что я пытался преобразовать в растровое ПОСЛЕ сканирования штрих-кода. Преобразование не было написано должным образом, но я нашел способ обойтись без написания собственной функции преобразования растровых изображений (хотя я планирую вернуться к ней, поскольку вижу, что мне это нужно, и искреннее любопытство хочет, чтобы я это выяснил)

...