cv :: OutOfMemoryError, генерируемый Mat.clone () в методе onCameraFrame

0

Я новичок в Opencv4Android, и у меня появляется ошибка, которую я не могу решить. В основном моя программа основана на методе onCameraFrame, который я реализовал следующим образом:

public Mat onCameraFrame(CvCameraView inputFrame)
{
    Mat m = inputFrame.rgba().clone();
    //Do some stuff
    return m;
}

Программа работает нормально, но после обработки некоторых кадров она останавливается и возвращает эти ошибки:

E/AndroidRuntime(9841): at org.opencv.core.Mat.clone(Mat.java:834)
E/AndroidRuntime(9841): at it.unive.featuretracking.FeatureTrackingTestActivity.onCameraFrame(FeatureTrackingTestActivity.java:95)
E/AndroidRuntime(9841): at org.opencv.android.CameraBridgeViewBase.deliverAndDrawFrame(CameraBridgeViewBase.java:387)
E/AndroidRuntime(9841): at org.opencv.android.JavaCameraView$CameraWorker.run(JavaCameraView.java:328)
E/AndroidRuntime(9841): at java.lang.Thread.run(Thread.java:841)

Кроме того, я напечатал сообщение об исключительной Mat.clone() которое Mat.clone()

E/Error(16954): cv::Exception: /home/reports/ci/slave_desktop/50-SDK/opencv/modules/core/src/alloc.cpp:52: error: (-4) Failed to allocate 8294404 bytes in function void* cv::OutOfMemoryError(std::size_t)

Я думаю, что причиной является метод Mat.clone(). Если я правильно понял, буфер достигает предела, потому что он не освобождается во времени. Я прав? Как я могу исправить программу?

Edit: Ok Я не знаю, является ли это правильным решением, но кажется, что программа теперь работает с этим кодом:

Mat m = null;  //declared as a field

...

public onCameraFrame(CvCameraView inputFrame)
{
    if (m != null)
    {
        m.release();
    }
    m = inputFrame.rgba().clone();
    //Do some stuff
    return m;
}
  • 0
    если вы используете эмулятор, то увеличьте объем оперативной памяти и VMheap
  • 0
    Я работаю на планшете Samsung.
Теги:
opencv

2 ответа

1
Лучший ответ

Я думаю, проблема в том, что вы создаете новый экземпляр объекта Mat для каждого кадра, полученного от камеры. Каждый раз, когда вы вызываете Mat m = inputFrame.rgba().clone(); (onCameraFrame...) вы создаете новый объект (Mat...), который занимает некоторую память. Через некоторое время вы обязаны заполнить ОЗУ своего устройства.

Я предлагаю вам попытаться определить Mat m = new Mat(); только один раз в методе onCameraViewStarted (появляется в большинстве руководств opencv4android), а затем попробуйте m = inputFrame.rgba().clone(); в onCameraFrame.

  • 0
    Может быть, вы хотели определить 'm' как поле и инициализировать его в onCameraViewStarted? Я пробовал это, но я все еще получаю ошибку.
  • 0
    Да, это то, что я имел в виду ... Кажется, что ваша проблема связана с этой строкой - но из-за метода клонирования. Я копнул немного глубже, и кажется, что клон создает глубокую копию объекта Mat, что означает, что он выделяет память, которая должна быть освобождена позже - но так как вы возвращаете m (и используете его позже), вы должны освободить его в какой-то момент, вызвав - m.release (). Это зависит от того, как вы реализуете остальную часть вашей программы, и трудно сказать, подходит ли вам этот подход.
Показать ещё 3 комментария
0

Я добился успеха в решении этой проблемы, добавив Mat.release() к каждому объекту Matrix OpenCV в местах, где каждый объект больше не нужен. Я считаю, что это то же самое, что и Mat :: t() Android, после предоставления времени выдает ошибку памяти.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню