user2121 user2121 - 2 months ago 33
Android Question

OutOfMemoryError generated due to camera preview

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

Answer

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

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

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