OutOfMemoryError generated due to camera preview

限于喜欢 提交于 2021-02-04 20:47:30

问题


I managed to open the Android camera using opencv. but when i use the code that fixes the camera orientation -"see the code mentioned below in the onCameraFrame(..) method"- the App crashes after few seconds and the logcat generates the belwo posted messages in the "logcat section".

To solve this issue:

  1. i tried to use SystemClock.sleep to force the App to dely for a while but this was not a good solution because it delays the camera preview

  2. i tried to minimize the frame size as much as i can, so i set it to 320x240 using mOpenCvCameraView.setMaxFrameSize(320, 240) "mentioned belwo in the code section". But this solution managed to keep the camera preview longer for few minutes but in the end The App crashed also.

Please tell me what is the proper solution for such situation and how to avoid it?

Logcat:

10-07 14:42:43.445 30510-31656/com.example.bak.opencvcamera_00 E/cv::error(): OpenCV Error: Insufficient memory (Failed to allocate 307200 bytes) in void* cv::OutOfMemoryError(size_t), file /home/maksim/workspace/android-pack/opencv/modules/core/src/alloc.cpp, line 52
10-07 14:42:43.445 30510-31656/com.example.bak.opencvcamera_00 E/cv::error(): OpenCV Error: Assertion failed (u != 0) in void cv::Mat::create(int, const int*, int), file /home/maksim/workspace/android-pack/opencv/modules/core/src/matrix.cpp, line 411
10-07 14:42:43.450 30510-31656/com.example.bak.opencvcamera_00 E/org.opencv.core.Mat: Mat::n_1t() caught cv::Exception: /home/maksim/workspace/android-pack/opencv/modules/core/src/matrix.cpp:411: error: (-215) u != 0 in function void cv::Mat::create(int, const int*, int)
10-07 14:42:43.450 30510-31656/com.example.bak.opencvcamera_00 E/AndroidRuntime: FATAL EXCEPTION: Thread-9334
Process: com.example.bak.opencvcamera_00, PID: 30510
CvException [org.opencv.core.CvException: cv::Exception: /home/maksim/workspace/android-pack/opencv/modules/core/src/matrix.cpp:411: error: (-215) u != 0 in function void cv::Mat::create(int, const int*, int)
at org.opencv.core.Mat.n_t(Native Method)
at org.opencv.core.Mat.t(Mat.java:852)
at com.example.bak.opencvcamera_00.MainActivity.onCameraFrame(MainActivity.java:109)
at org.opencv.android.CameraBridgeViewBase.deliverAndDrawFrame(CameraBridgeViewBase.java:391)
at org.opencv.android.JavaCameraView$CameraWorker.run(JavaCameraView.java:350)

code:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);

    setContentView(R.layout.activity_main);
    mOpenCvCameraView = (JavaCameraView) findViewById(R.id.surfaceView);
    mOpenCvCameraView.setOnTouchListener(this);
    mOpenCvCameraView.setVisibility(SurfaceView.VISIBLE);
    mOpenCvCameraView.setCvCameraViewListener(this);
    mOpenCvCameraView.setMaxFrameSize(320, 240);
}
...
...
...
@Override
public Mat onCameraFrame(Mat inputFrame) {
    mRgbaT = inputFrame.t();
    Core.flip(inputFrame.t(), mRgbaT, 1);
    Imgproc.resize(mRgbaT, mRgbaT, inputFrame.size());
    return mRgbaT;
}

update:

I modified the below method in such a way that mRgbaT is declared as a field and i clear its contents after capturing a new frame...but still the problem persists

@Override
public Mat onCameraFrame(Mat inputFrame) {

    if (mRgbaT != null) {
        mRgbaT.release();
    }

    mRgbaT = inputFrame.t();
    Core.flip(inputFrame.t(), mRgbaT, 1);
    Imgproc.resize(mRgbaT, mRgbaT, inputFrame.size());
    return mRgbaT;
}

回答1:


From my experience OpenCV4Android is really, really bad at garbage collecting Matrixes, so I would keep each matrix in separate variable and clean them all manually.

@Override
public Mat onCameraFrame(Mat inputFrame) {

    Matrix mat1 = new Mat();
    Matrix mat2 = new Mat();

    Core.flip(inputFrame.t(), mat1, 1);
    Imgproc.resize(mat1, mat2, inputFrame.size());

    mat1.release();
    inputFrame.release();

    return mat2;
}

If you're using OpenCV4Android in source form, I would also suggest adding modified.release(); here




回答2:


I solved it by avoiding performing matrix transpose operation twice as shown below in the code:

@Override
public Mat onCameraFrame(Mat inputFrame) {
    if (mRgbaT != null) {
        mRgbaT.release();
    }

    mRgbaT = inputFrame.t();
    Core.flip(mRgbaT, mRgbaT, 1);
    Imgproc.resize(mRgbaT, mRgbaT, inputFrame.size());
    return mRgbaT;
}



回答3:


There should be a loop existing in your cpp file which is capturing images continuously on each call. When you are resizing image into a lower resolution, the app runs a little longer, but still causing a memory leak and crashes.

You can make an approach which will clear each image after processing and capture a new one so that you may not end up using all RAM spaces. Referring you to this link.



来源:https://stackoverflow.com/questions/39918063/outofmemoryerror-generated-due-to-camera-preview

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!