Сбой OpenCV Native Android cvtColor

Мне нужно преобразовать изображение в оттенки серого, а затем обратно в RGBA, чтобы иметь возможность рисовать на нем.

В настоящее время я делаю это с двумя разными вызовами cvtColor, которые отлично работают, хотя производительность в Android не очень хорошая (RGBA -> GRAY -> RGBA).

Получение серого изображения напрямую с камеры происходит быстрее, и только один вызов cvtColor имеет огромное значение (GRAY -> RGBA).

Проблема в том, что второй метод закрывает приложение через несколько секунд. Logcat в Android Studio не показывает сбой приложения, но показывает некоторые ошибки с выбранным параметром «Без фильтров». Вот журнал https://pastebin.com/jA7jFSvu. Кажется, это указывает на проблему с камерой OpenCV.

Ниже приведены два разных фрагмента кода.

public Mat onCameraFrame(CameraBridgeViewBase.CvCameraViewFrame inputFrame) {

    // Method 1 - works
    cameraImage = inputFrame.rgba();
    native.exampleProcessImage1(cameraImage.getNativeObjAddr(), cameraImage.getNativeObjAddr());

    return cameraImage;

    // Method 2 - app closes after a few seconds
    cameraImage = inputFrame.gray();
    Mat result = new Mat();
    native.exampleProcessImage2(cameraImage.getNativeObjAddr(), result.getNativeObjAddr());

    return result;
}

И это мой код на С++:

void Java_com_example_native_exampleProcessImage1(JNIEnv *env, jobject instance, jlong sourceImage, jlong destImage) {
    // works!
    Mat &src = * ((Mat *) sourceImage);
    Mat &dest = * ((Mat *) destImage);
    Mat pivot;

    // src is RGBA
    cvtColor(src, pivot, COLOR_RGBA2GRAY);
    cvtColor(pivot, dest, COLOR_GRAY2RGBA);
    // dest is RGBA

    // process
}

void Java_com_example_native_exampleProcessImage2(JNIEnv *env, jobject instance, jlong sourceImage, jlong destImage) {
    // does not work
    Mat &src = * ((Mat *) sourceImage);
    Mat &dest = * ((Mat *) destImage);

    // src is GRAY
    cvtColor(src, dest, COLOR_GRAY2RGBA);
    // dest is RGBA

    // process
}

Это работает, как и ожидалось, в Linux и OpenCV.

Вы знаете, что я делаю неправильно? Есть ли другой способ добиться того же? Производительность является ключевым фактором, особенно для устройств Android.

Заранее спасибо.


person Colmike    schedule 25.07.2018    source источник


Ответы (1)


Во втором случае у вас есть утечка памяти, и это приводит к утечке
~ 3 sec * fps * frame_resolution * 4 bytes

Я думаю, что сбой происходит после заполнения памяти.

Вам нужно звонить result.release(); где-то после каждого exampleProcessImage2 звонка

person tenta4    schedule 25.07.2018
comment
Спасибо, ваше предложение направило меня в правильном направлении. Я не знал, что мне нужно освободить память, и сообщение об ошибке было не очень ясным. - person Colmike; 26.07.2018