所以我要重新开始一个我几个月没有碰过的项目。几天前我在搞砸它,没有任何问题(至少在我之前的最新帖子之后)。不管出于什么原因,今天我去运行它,我已经为这个问题苦苦挣扎了几个小时......
问题:
我正在创建一个 FIrebaseVisionImage 对象以用于各种 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)
- K 那么接下来的行(就错误而言)是: zza(var0[0], var1, var2, var4, 0, 1);
- 然后调用: zza(Plane var0, int var1, int var2, byte[] var3, int var4, int var5)
- 最后调用: int var9 = var2 / var8
现在,我是一个 Android Studio 新手,所以我不知道如何在跟踪时获取类文件中的值,所以我回到了创建 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);
}