簡體   English   中英

zzrb.zza 導致每個其他 cameraX analyzer.analyze 幀除以零算術異常

[英]zzrb.zza resulting in a divide by zero arithmetic exception for every other cameraX analyzer.analyze frame

所以我要重新開始一個我幾個月沒有碰過的項目。 幾天前我在搞砸它,沒有任何問題(至少在我之前的最新帖子之后)。 不管出於什么原因,今天我去運行它,我已經為這個問題苦苦掙扎了幾個小時......

問題:

我正在創建一個 FIrebaseVisionImage object 用於各種 ml 視覺任務。

FirebaseVisionImage image = FirebaseVisionImage.fromMediaImage(mediaImage, rotation);

在此之前非常標准的設置(類似於他們在使用帶有 ImageAnalysis.Analyzer 的 CameraX 的示例中的設置。無論出於何種原因,我現在遇到了這個我以前沒有遇到的錯誤。

java.lang.ArithmeticException: divide by zero
    at com.google.android.gms.internal.firebase_ml.zzrb.zza(com.google.firebase:firebase-ml-vision@@24.0.0:55)
    at com.google.android.gms.internal.firebase_ml.zzrb.zza(com.google.firebase:firebase-ml-vision@@24.0.0:48)
    at com.google.firebase.ml.vision.common.FirebaseVisionImage.fromMediaImage(com.google.firebase:firebase-ml-vision@@24.0.0:20)
    at com.divertinc.visiondispositiontesting.MainActivity$4.analyze(MainActivity.java:248)

到目前為止我所做的:

好吧,沒問題,讓我只是堆棧跟蹤。 我看到這一行:

int var9 = var2 / var8;

是問題。 好的,很酷,讓我們找出這些值。

讓我們向后工作:

  1. 當我調用 fromMediaImage FirebaseVisionImage 它應該返回這個(基於我的圖像):

     return new FirebaseVisionImage(zzrb.zza(var2, var0.getWidth(), var0.getHeight()), (new Builder()).setFormat(17).setWidth(var0.getWidth()).setHeight(var0.getHeight()).setRotation(var1).build())
  2. K 酷,所以我們知道這里有問題的方法是: zza(Plane[] var0, int var1, int var2)

  3. K 那么接下來的行(就錯誤而言)是: zza(var0[0], var1, var2, var4, 0, 1);
  4. 然后調用: zza(Plane var0, int var1, int var2, byte[] var3, int var4, int var5)
  5. 最后調用: int var9 = var2 / var8

現在,我是 Android Studio 新手,所以我不知道如何在跟蹤時獲取 class 文件中的值,所以我回到了創建 FirebaseVisionImage 的位置,就在此之前我這樣做了:

Image.Plane var0 = mediaImage.getPlanes()[0];
ByteBuffer var6 = var0.getBuffer();
int var2 = mediaImage.getHeight();
int var8 = (var6.remaining() + var0.getRowStride() - 1) / var0.getRowStride();

Log.d("divide debug: ", String.valueOf(var2));
Log.d("divide debug: ", String.valueOf(var8));
Log.d("divide debug: ", String.valueOf(var6.remaining()));
Log.d("divide debug: ", String.valueOf(var0.getRowStride()));
Log.d("divide debug: ", String.valueOf((var6.remaining() + var0.getRowStride() - 1)));

這導致:

480

0

0

640

639

K 井 639/640 是 0.9.... 現在,如果我記得 Java 是如何工作的,int 除法會向下舍入 - 除非我假設明確覆蓋? 反正。 KI 猜想那是完全有道理的。 好吧,如果我沒記錯的話,從現在到它工作時我唯一改變的是依賴升級,我實際上降級了,看看這是否會影響它,在查看發行說明后它不應該有。

編輯:所以我發現實際上當我記錄我之前所做的事情時,我注意到之前正在分析 4 幀,結果如下:

日志 1:

480

480

307200

640

307839

日志 2:

480

0

0

640

639

日志 3:

480

480

307200

640

307839

崩潰信息

日志 4:

480

0

0

640

639

我被困在哪里:(

錯誤發生在第三個日志之后不到 100 毫秒,之后近 300 毫秒,第四個日志被命中。

所以我的假設是緩沖每隔一幀有問題,因為.remaining() 方法導致每隔一幀為0,這是不應該發生的。 不幸的是,我對此知之甚少,所以我想看看是否有人能指出我正確的方向 D:從好的方面來說,我在發布這篇文章的整個過程中學到了很多東西(我在這篇文章上工作了大約45分鍾)

下面是我的整個相機功能,我認為它和 D 一樣存在很多問題:

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 */
            .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){

                    while (weCanAnalyzeFrame) {

                        if (!isMachineLearning) {
                            Log.d("analyze", "just analyzing");
                            if (imageProxy == null || imageProxy.getImage() == null) {
                                Log.d("imageProxy: ", "is null");
                                return;
                            }
                            Image mediaImage = imageProxy.getImage();
                            int rotation = degreesToFirebaseRotation(degrees);
                            Log.d("degrees: ", String.valueOf(degrees));
                            Log.d("rotation: ", String.valueOf(rotation));

                            Image.Plane var0 = mediaImage.getPlanes()[0];
                            ByteBuffer var6 = var0.getBuffer();
                            int var2 = mediaImage.getHeight();
                            int var8 = (var6.remaining() + var0.getRowStride() - 1) / var0.getRowStride();
//                            int var9 = var2 / var8;

                            Log.d("divide debug: ", String.valueOf(var2));
                            Log.d("divide debug: ", String.valueOf(var8));
                            Log.d("divide debug: ", String.valueOf(var6.remaining()));
                            Log.d("divide debug: ", String.valueOf(var0.getRowStride()));
                            Log.d("divide debug: ", String.valueOf((var6.remaining() + var0.getRowStride() - 1)));
                            Log.d("divide debug: ", " ");

                            FirebaseVisionImage image = FirebaseVisionImage.fromMediaImage(mediaImage, rotation);

                            Log.d("analyze", "isMachineLearning is about to be true");
                            isMachineLearning = true;
                            extractBarcode(image, image.getBitmap());
                        }
                    }
                }
            });

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

它看起來像 var6.remaining():yPlane 緩沖區的當前 position() 到 limit() 從崩潰的 mediaImage 為 0。

mediaImage 來自 MLKit 在那里控制的相機。 但是,mlkit 絕對應該在除法操作之前檢查該值以避免崩潰。 我們將對其進行修復。

剛剛從cameraX團隊得到確認,這是camerax core beta02中引入的一個錯誤,修復將在beta04中。

現在,您可以在為 MLKit 創建 InputImage 之前在緩沖區上調用 rewind() 作為解決方法。

謝謝!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM