10秒后opencv android崩溃

时间:2014-05-18 05:38:25

标签: android opencv

我一直在使用使用opencv的教程脚本将灰度滤镜应用于相机图像。该脚本工作正常(连续运行),但是当我修改脚本以过滤掉蓝色/绿色并仅显示红色时,10秒后活动将关闭并显示以下警告/错误消息

05-18 15:24:36.765: W/ContextImpl(6067): Implicit intents with startService are not safe: Intent { act=org.opencv.engine.BIND } android.content.ContextWrapper.bindService:517 org.opencv.android.AsyncServiceHelper.initOpenCV:24 org.opencv.android.OpenCVLoader.initAsync:79 
05-18 15:24:37.983: W/Adreno-EGL(6067): <qeglDrvAPI_eglCreateContext:2349>: EGL_BAD_CONFIG
05-18 15:24:37.983: E/OpenCV_for_Tegra(6067): Cannot create OpenGL context

我不确定这些消息是什么意思。而且我不确定在运行一段时间之后会导致程序崩溃的原因。这可能是一个记忆问题吗?

这是我一直在修改的代码部分

    public Mat onCameraFrame(CvCameraViewFrame inputFrame) {
mRgba = inputFrame.rgba();

//Original code
//Imgproc.cvtColor(mRgba, mGray, Imgproc.COLOR_BGRA2GRAY);

Core.split(mRgba, channels);
// m = Core.mean(channels.get(0));
channels.set(1, Mat.zeros((channels.get(1)).rows(), (channels.get(1)).cols(), (channels.get(1)).type() ));
channels.set(2, Mat.zeros((channels.get(2)).rows(), (channels.get(2)).cols(), (channels.get(2)).type() ));

Core.merge(channels,mRgba);
//return mGray;
 return mRgba;
}

这是完整的代码。

package com.example.camera1;


import java.util.ArrayList;
import java.util.List;

import org.opencv.android.BaseLoaderCallback;
import org.opencv.android.CameraBridgeViewBase;
import org.opencv.android.CameraBridgeViewBase.CvCameraViewFrame;
import org.opencv.android.CameraBridgeViewBase.CvCameraViewListener2;
import org.opencv.android.LoaderCallbackInterface;
import org.opencv.android.OpenCVLoader;
import org.opencv.core.*;

//import org.opencv.highgui.Highgui;
import org.opencv.imgproc.Imgproc;

import android.os.Bundle;
import android.app.Activity;
import android.util.Log;
import android.view.MotionEvent;
import android.view.SurfaceView;
import android.view.View;
import android.view.View.OnTouchListener;
import android.view.WindowManager;


public class MainActivity extends Activity implements CvCameraViewListener2, OnTouchListener {
private static final String TAG = "OCVSample::Activity";
private Mat mRgba;
private Mat mGray;
private List<Mat> channels=new ArrayList<Mat>();
Scalar m;
private CameraBridgeViewBase mOpenCvCameraView;
private int rowsize;
private int colsize;
private int ktype;

private BaseLoaderCallback mLoaderCallback = new BaseLoaderCallback(this) {
@Override
public void onManagerConnected(int status) {
switch (status) {
case LoaderCallbackInterface.SUCCESS:
{
Log.i(TAG, "OpenCV loaded successfully");
mOpenCvCameraView.enableView();
mOpenCvCameraView.setOnTouchListener(MainActivity.this);
} break;
default:
{
super.onManagerConnected(status);
} break;
}
}
};
public MainActivity() {
Log.i(TAG, "Instantiated new " + this.getClass());
}

@Override
protected void onCreate(Bundle savedInstanceState) {
Log.i(TAG, "called onCreate");
super.onCreate(savedInstanceState);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);

setContentView(R.layout.activity_main);
mOpenCvCameraView = (CameraBridgeViewBase) findViewById(R.id.tutorial1_activity_java_surface_view);

mOpenCvCameraView.setVisibility(SurfaceView.VISIBLE);

mOpenCvCameraView.setCvCameraViewListener(this);
}

@Override
public void onPause()
{
super.onPause();
if (mOpenCvCameraView != null)
mOpenCvCameraView.disableView();
}

@Override
public void onResume()
{
super.onResume();
OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_2_4_3, this, mLoaderCallback);
}

public void onDestroy() {
super.onDestroy();
if (mOpenCvCameraView != null)
mOpenCvCameraView.disableView();
}


public void onCameraViewStarted(int width, int height) {
mGray = new Mat();
mRgba = new Mat();
channels=new ArrayList<Mat>();

}

public void onCameraViewStopped() {
}

public Mat onCameraFrame(CvCameraViewFrame inputFrame) {
mRgba = inputFrame.rgba();

//Original code
//Imgproc.cvtColor(mRgba, mGray, Imgproc.COLOR_BGRA2GRAY);

Core.split(mRgba, channels);
// m = Core.mean(channels.get(0));
channels.set(1, Mat.zeros((channels.get(1)).rows(), (channels.get(1)).cols(), (channels.get(1)).type() ));
channels.set(2, Mat.zeros((channels.get(2)).rows(), (channels.get(2)).cols(), (channels.get(2)).type() ));

Core.merge(channels,mRgba);
//return mGray;
 return mRgba;
}

@Override
public boolean onTouch(View arg0, MotionEvent arg1) {
    // TODO Auto-generated method stub
    return false;
}
}

2 个答案:

答案 0 :(得分:4)

onCameraFrame方法中明确调用垃圾收集器可能会解决问题:

    System.gc();

正如@xMKx已经注意到的那样,问题很可能与内存管理有关。应用程序刚刚用完堆然后终止。

问题在于,由于某些原因,垃圾收集器有时会忽略没有引用它们的Mats。因此,当使用Mat对象的release()方法不会产生任何结果时(不幸的是)就是这种情况。

答案 1 :(得分:1)

尝试使用它完成后释放ArrayList中的所有Mats。我有类似的问题,但这一切都归结为内存管理。(不确定是否是相同的错误消息)