[英]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;
是問題。 好的,很酷,讓我們找出這些值。
讓我們向后工作:
當我調用 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())
K 酷,所以我們知道這里有問題的方法是: zza(Plane[] var0, int var1, int var2)
現在,我是 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.