【问题标题】:AndroidX Camera Core ImageAnalysis.Analyser results in distorted imageAndroidX Camera Core ImageAnalysis.Analyser 导致图像失真
【发布时间】:2020-04-21 02:18:29
【问题描述】:

我正在使用 ImageAnalysis 库来提取实时预览,然后进行条形码扫描和 OCR。

我在条码扫描方面完全没有任何问题,但 OCR 会导致一些较弱的结果。我相信这可能有几个原因。我目前对解决方案的尝试是在我对帧运行 OCR(或条形码)之前将帧发送到 GCP - Storage,以便批量查看它们。它们看起来都非常相似:

我最好的猜测是我处理帧的方式可能会导致像素在缓冲区中的组织不正确(我对 Android 不熟悉 - 抱歉)。意思而不是组织 0,0 然后 0,1 .....它随机获取像素并将它们放在随机区域中。我不知道这是在哪里发生的。一旦我可以查看图像质量,我就可以分析 OCR 的问题,但不幸的是,这是我目前的拦截器。

额外说明:我在运行 OCR 之前将图像上传到 GCP - 存储,因此为了查看这一点,我们可以忽略我所做的 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);

感谢大家的热心帮助(:

【问题讨论】:

    标签: google-cloud-storage android-camera androidx


    【解决方案1】:

    我的问题是我试图在条形码扫描后转换为位图。转换没有正确编写,但我找到了一种方法,而不必编写自己的位图转换函数(尽管我计划回到它,因为我认为自己需要它,真正的好奇心想让我弄清楚)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-07-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-11-07
      • 2015-07-13
      相关资源
      最近更新 更多