由Mat.clone()在onCameraFrame方法中抛出的OutOfMemoryError错误

cv::OutOfMemoryError thrown by Mat.clone() in onCameraFrame method

本文关键字:错误 OutOfMemoryError 方法 onCameraFrame clone Mat      更新时间:2023-10-16

我是新的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()抛出的异常消息

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()方法。如果我理解正确的话,缓冲区达到极限是因为它没有及时释放。我说的对吗?我怎样才能修复这个程序?

编辑:

好吧,我不知道这是不是正确的解决方案,但似乎程序现在正在工作,这段代码:

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;
}

我认为问题在于您正在从相机接收的每一帧上创建Mat对象的新实例。每次你调用Mat m = inputFrame.rgba().clone(); (onCameraFrame…),你创建一个新的对象(Mat…),占用一些内存。过了一段时间,你一定会填满你的设备的RAM。

我建议您尝试在onCameraViewStarted方法中定义Mat m = new Mat();一次(出现在大多数opencv4android教程中),然后在onCameraFrame中尝试m = inputFrame.rgba().clone();

我成功地解决了这个问题,通过在每个不再需要的对象的位置将Mat.release()添加到每个OpenCV矩阵对象。我相信这是相同的Mat::t() Android,给时间后给出了内存错误。