zzrb.zza, в результате чего арифметическое c исключение делится на ноль для всех остальных CameraX analyzer.analyze frame - PullRequest
0 голосов
/ 30 апреля 2020

Так что я возвращаюсь к проекту, который я не затрагивал месяцами. Я возился с этим несколько дней go без проблем (по крайней мере, после моего последнего поста до этого). Сегодня, по какой-то причине, я решил его запустить и уже несколько часов бьюсь над этой проблемой ...

Проблема:

Я создаю объект FIrebaseVisionImage для использования в различных задачах ml vision.

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

Довольно стандартная настройка до этого (аналогично тому, что они имеют в их примере с использованием CameraX с ImageAnalysis.Analyzer. По любой причине Теперь я получаю эту ошибку, которую не получал раньше.

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 (плоскость var0, int var1, int var2, byte [] var3, int var4, int var5)
  5. Что в итоге вызывает: int var9 = var2 / var8

Теперь я Android Studio newb ie поэтому я не могу понять, как получить значения в файлах классов при трассировке, поэтому я просто вернулся к тому месту, где создавал 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 округляется вниз - разве я не предполагаю, что это явно переопределено? Тем не мение. Я думаю, тогда это имеет смысл. Итак, если я правильно помню, единственное, что я изменил между тем, когда он работал, было обновление зависимостей, которое я фактически понизил, чтобы посмотреть, повлияет ли это на него, чего не должно быть после просмотра заметок о выпуске.

РЕДАКТИРОВАТЬ: Таким образом, я обнаружил, что на самом деле, когда я регистрирую то, что сделал ранее, я замечаю, что 4 кадра анализируются ранее со следующими результатами:

Журнал 1:

480

480

307200

640

307839

Журнал 2:

480

0

0

640

639

Журнал 3:

480

480

307200

640

307839

CRA SH СООБЩЕНИЕ

Журнал 4:

480

0

0

640

639

Где я застрял: (

Ошибка происходит менее чем за сотую часть утра. через секунду после третьего журнала и почти через 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);
}

1 Ответ

0 голосов
/ 08 мая 2020

Похоже на var6.remaining (): текущее положение буфера yPlane () в limit () равно 0 от сбойного mediaImage.

mediaImage исходит от камеры, контроль над которой MLKit имеет там. Тем не менее, mlkit должен обязательно проверить значение перед операцией деления, чтобы избежать сбоев. Мы исправим это.

Только что было подтверждено командой cameraX, что это ошибка, которая была введена в ядре camerax beta02, исправление будет в beta04.

На данный момент вы можете вызвать rewind () для буфера перед созданием InputImage для MLKit в качестве обходного пути.

Спасибо!

...