google tango/opencv android приложение камеры дает сбой/зависает

Я разрабатываю прототип приложения, используя камеру глубины танго для сопоставления шаблонов. До сих пор мне удавалось решать все проблемы с помощью уже отвеченных вопросов, документации и т. д.

Однако сейчас я, кажется, остановился. Последнее крупное изменение, которое я сделал, заключалось в том, чтобы нарисовать контур на изображении предварительного просмотра камеры перед его отображением. Что бы я ни делал сейчас, приложение какое-то время работает, прежде чем вылетит.

Я просмотрел дампы кучи и отслеживание распределения в Android Studio. Единственная, возможно, странная вещь заключается в том, что в объектах FinalizerReference в дампе кучи может быть много памяти...

Я также попытался перенести обработку в AsyncTask и просто пропустить каждый цветной кадр, пока задача не будет выполнена (чтобы одновременно выполнялась только одна задача) и отображался обработанный кадр, но проблема осталась.

Я использую Google Tango для получения данных камеры цвета и глубины и opencv в java для анализа данных и сопоставления шаблонов.

Кто-нибудь знает, что означают эти сообщения logcat?

Ошибки логката:

Код для отображения предварительного просмотра камеры:

Здесь потенциально могут произойти две вещи:

mTango.experimentalConnectOnFrameListener(TangoCameraIntrinsics.TANGO_CAMERA_COLOR, new Tango.OnFrameAvailableListener() {
    byte[] imageByteArray = new byte[colorCameraIntrinsics.height * colorCameraIntrinsics.width * 3 / 2];  
    Mat yuvMat = new Mat( colorCameraIntrinsics.height + colorCameraIntrinsics.height/2, colorCameraIntrinsics.width, CvType.CV_8UC1 );
    Bitmap bitmapDisplay = Bitmap.createBitmap( colorCameraIntrinsics.width, colorCameraIntrinsics.height, Bitmap.Config.ARGB_8888 );
    Mat colorMatDisplay;

    @Override
    public void onFrameAvailable(TangoImageBuffer imageBuffer, int cameraId) {
        Log.d(TAG, "onFrameAvailable: color frame available");
        if (colorFrameCounter < 3) { //only use every 3rd frame
            Log.d(TAG, "onFrameAvailable: skipping frame " + colorFrameCounter);
            colorFrameCounter++;
        } else {
            colorFrameCounter = 0;
            if (!stopCameraView.get()) { // Only view frame if camera view is not stopped

                // convert image buffer data to byte array
                imageBuffer.data.get(imageByteArray);

                // byte array to Mat object with YUV coding (NV21)
                yuvMat.put(0, 0, imageByteArray);

                // locking access to lastColorFrameMat
                synchronized (lockVar) {
                    Log.d(TAG, "onFrameAvailable: converting to bitmap");
                    // convert from YUV (NV21) Mat to RGBA Mat and place in lastColorFrameMat (global)
                    Imgproc.cvtColor(yuvMat, lastColorFrameMat, Imgproc.COLOR_YUV2RGBA_NV21, 4);
                    colorMatDisplay = lastColorFrameMat.clone();
                }

                if (templateContours != null) {
                    Imgproc.drawContours(colorMatDisplay, templateContours, templateContourMaxIdx, new Scalar(0, 255, 0, 255), 5);
                }

                // convert colorMatDisplay to bitmap, for display in imageview
                Utils.matToBitmap(colorMatDisplay, bitmapDisplay);

                Log.d(TAG, "onFrameAvailable: view lastColorFrameMat on phone display");

                // View colorImage in imageViewer on UI thread
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        imageViewer.setImageBitmap(bitmapDisplay);
                    }
                });
            }
        }

    }
});

person Nille    schedule 22.05.2017    source источник


Ответы (1)


С текущим SDK Tango вызываемый onFrameAvailable обратный вызов имеет контроль только над imageBuffer в рамках обратного вызова. Это означает, что если вы ссылаетесь на imageBuffer в AsynTask, вы потенциально можете получить нулевой буфер и привести к сбою. Способ решения Tango заключается в том, чтобы всегда глубоко копировать данные из обратного вызова и обрабатывать их в другом потоке.

  1. процесс слишком долго блокирует поток Tango.

Без AsyncTask, вероятно, произошло то, что обработка слишком долго блокировала поток Tango, и известно, что это также плохо для Tango.

  1. E/lowmemorykiller: ошибка при открытии /proc/10173/oom_score_adj; errno=2
    E/mm-camera-isp2: abf40_trigger_update:587 aec_ratio.ratio = 0,039062
    W/ActivityManager: планирование перезапуска службы com.lenovo.lsf.device/com.lenovo.lsf.push. service.PushService через 68 068 мс
    W/ActivityManager: Планирование перезапуска службы com.qualcomm.qti.modemtestmode/.MbnSystemService через 88 020 мс
    E/InputDispatcher: канал '478a66c com.android.documentsui/com.android.documentsui .DocumentsActivity (server)' ~ Канал безвозвратно поврежден и будет удален!
    E/lowmemorykiller: Ошибка записи /proc/10113/oom_score_adj; errno=22
    E/JavaBinder: !!! НЕУДАЧНАЯ СДЕЛКА СВЯЗИВАТЕЛЯ !!! (размер посылки = 76)
    E/lowmemorykiller: Ошибка записи /proc/32408/oom_score_adj; errno=22
    E/InputDispatcher: канал '85c4188 com.android.launcher3/com.android.launcher3.Launcher (сервер)' ~ Канал безвозвратно поврежден и будет удален!
    E/mm-camera-isp2 : abf40_trigger_update:587 aec_ratio.ratio = 0.000000
    E/ConnectivityService: RemoteException поймано при попытке отправить сообщение обратного вызова для NetworkRequest [ id=332, legacyType=-1, [ Capabilities: INTERNET&NOT_RESTRICTED&TRUSTED] ]
    E/mm-camera : mct_util_timer_handler: Ошибка бэкэнда, зависшего во время команды HAL, поднимающей сигнал SIGABRT
    E/JavaBinder: !!! НЕУДАЧНАЯ СДЕЛКА СВЯЗИВАТЕЛЯ !!! (размер посылки = 76)
    E/lowmemorykiller: Ошибка записи /proc/32437/oom_score_adj; errno=22
    E/JavaBinder: !!! НЕУДАЧНАЯ СДЕЛКА СВЯЗИВАТЕЛЯ !!! (размер посылки = 308)
    E/JavaBinder: !!! НЕУДАЧНАЯ СДЕЛКА СВЯЗИВАТЕЛЯ !!! (размер посылки = 76)
    E/lowmemorykiller: Ошибка записи /proc/32437/oom_score_adj; errno=22
    E/JavaBinder: !!! НЕУДАЧНАЯ СДЕЛКА СВЯЗИВАТЕЛЯ !!! (размер посылки = 76)
    E/mm-camera: mct_util_timer_handler:Error Backend застрял во время вызова SIGABRT команды HAL буфер в SurfaceTexture, -32
    E/mm-camera: cpp_module_send_buf_divert_event:545] событие буфера получено без конфигурации перенаправления
    E/mm-camera: cpp_module_send_buf_divert_event:545] событие буфера получено без конфигурации перенаправления
    E /Camera3-OutputStream: getBufferLocked: Stream 0: Не удается удалить из очереди следующий выходной буфер: Неработающий канал (-32)
    E/Camera3-OutputStream: returnBufferCheckedLocked: Поток 0: Ошибка постановки буфера в очередь в исходное окно: Неработающий канал (-32) )
    E/Camera3-Device: RequestThread: Не удается получить выходной буфер, пропуская запрос: Неисправный канал (-32)
    E/Camera3-Device: Не удается вернуть буфер в свой поток: Неисправный канал (- 32)
    E/Camera3-OutputStream: getBufferLocked: Stream 0: невозможно удалить из очереди следующий выходной буфер: сломан канал (-32)
    E/Camera3-Dev ice: RequestThread: не удается получить выходной буфер, пропущен запрос: сломан канал (-32)

буфер для изображения с камеры вышел за рамки.

person xuguo    schedule 21.06.2017