在使用OpenCV时,程序总是在某个时间墨明棋妙地终止,打开CygWin ,输入 adb logcat ,查看打印的信息,发现是内存问题。经过反复的查找,发现使用OpenCV的java类库时,一定要慎重使用New Mat()。

内存溢出的原因: 在循环中使用Java层的OpenCV,本质都需要深入到Native层。在使用New Mat(),进行初始化时,默认使用了C++的new()函数,但并没有同时使用Delete(),并且也无法确定初始化对象的作用域,导致大量的New()没有Delete(),造成内存溢出。

经过修改后的处理帧的函数是这样的:

  @SuppressLint("SdCardPath")
public Mat onCameraFrame(CvCameraViewFrame inputFrame) { if(!inited)
return inputFrame.rgba();//初始化OpenCV mRgba = inputFrame.rgba();
mGray = inputFrame.gray(); if (mTrack6Dof.mNativeObjCvT != 0 && mTrack6Dof.mCamParam!=null){
if(mRgba.rows()>0 ){ //经过一次分辨率转换!
Imgproc.resize(mRgba, m_Mi, mRgba.size());
Imgproc.cvtColor( mRgba,m_Mi, Imgproc.COLOR_BGRA2RGB); //确认是否调用原始视频!
if(IsVideo == true){  //1.获得红色追踪面的重心
getSeqCentroid(m_Mi, mRgba); }
else{ if(G_Counter <1000 ){ String filename ="/sdcard/DevCv/CircleBall/";
filename +="Image" + G_Counter + ".png"; Mat M =Highgui.imread(filename); //2.测试序列追踪
//代码无修改,测试追踪没有响应代码,暂时不可行
if( M.rows()>0 ){ //3.测试球追踪
refineYSeq( M, mRgba); } G_Counter+=1;
}
else
{
IsVideo = false;
}
}
} } return mRgba;
}

所使用的函数:

	public int refineYSeq(Mat M, Mat mRgba)
{
Point3 Centroid = new Point3();
Centroid.x =0; Pattern.refineSeqJar(M,Centroid); if(Centroid.x !=0){
Rect RCen = new Rect();
RCen.height = 4;
RCen.width = 4;
RCen.x = (int) ( Centroid.x );
RCen.y = (int) ( Centroid.y ); Point Center = new Point();
Center.x = (int) ( Centroid.x );
Center.y = (int) ( Centroid.y );
RectMyMat(M, Center, (float)4.0, FACE_RECT_COLOR ,2);
} //Mat MT= new Mat( mRgba.rows(),mRgba.cols(),CvType.CV_8UC3);
Imgproc.resize( M, m_MT, mRgba.size() );
Imgproc.cvtColor(m_MT, mRgba, Imgproc.COLOR_RGB2BGRA); return 1;
}

所使用的全局变量:

	//初始化OpenCV载入状态和循环中使用的mat,把循环内的mat转化为全局,不在局部new mat型
boolean inited = false; Mat m_Mi = null;
Mat m_edges = null;
Mat m_MT = null;

初始化OpenCV和局部变量:

//初始化OpenCV的callback函数:

private BaseLoaderCallback  mLoaderCallback = new BaseLoaderCallback(this) {
@Override
public void onManagerConnected(int status) {
switch (status) {
case LoaderCallbackInterface.SUCCESS:
{
Log.i(TAG, "OpenCV loaded successfully");
//System.loadLibrary("feelJulyGpsMap");// Load native library after(!) OpenCV initialization
try { {
m_Mi = new Mat(540,960,CvType.CV_8UC3);
m_edges = new Mat(540,960,CvType.CV_8UC1);
m_MT = new Mat(540,960,CvType.CV_8UC3); Pattern = new CMovePattern();
PatternRf = new CMovePatternRf();
} } catch (IOException e) {
e.printStackTrace();
Log.e(TAG, "Failed to load cascade. Exception thrown: " + e);
} //尝试几种方法,暂时不改正摄像机角度问题了!
//camera.setDisplayOrientation(90);
//mOpenCvCameraView.setRotationX(15);//立体旋转,旋转90度就成一条线了!wishchin!
//mOpenCvCameraView.surfaceCreated(surfaceHolder Holder);
mOpenCvCameraView.enableView(); } break; default:
{
super.onManagerConnected(status);
} break;
}
}
};

总结:

避免使用OpenCV造成内存溢出的方法是:

把循环中需要初始化的变量移到全局,避免大量的New Mat() 出现;

1. 初始化为null;

2.初始化OpenCV后,再初始化Mat的大小;

3.在循环中使用全局Mat型,避免new 或者初始化!

解决JavaOpenCV的内存问题的更多相关文章

  1. Flex内存泄露解决方法和内存释放优化原则

    Flex内存泄露解决方法和内存释放优化原则 你对Flex内存泄露的概念是否了解,这里和大家分享一下Flex内存释放优化原则和Flex内存泄露解决方法,希望本文的介绍能让你有所收获. Flex内存释放优 ...

  2. 怎样解决SQL Server内存不断增加问题

    原文:怎样解决SQL Server内存不断增加问题 版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn. ...

  3. 如何解决audiodg占用内存高(停止与重启audiodg服务)

    window7电脑audiodg.exe进程占用内存很高 首先想到的办法是结束该进程,于是在任务管理器里结束进程后,内存是释放了,但是发现发现电脑没有声音 去到电脑的system32目录下双击audi ...

  4. 解决MyEclipse吃内存以及卡死的方法

    前言:MyEclipse5.5 大小 139M:MyEclipse6.5 大小 451M:MyEclipse7.0 大小 649M!下载服务器又是国外的...下载速度累人也就罢了,只要你工作性能一流. ...

  5. 解决Ubuntu下内存不足---作为Slave的虚拟机

    1)在虚拟机上安装了Ubuntu桌面版作为DataNode,由于物理机内存的限制只是分了1G的内存给虚拟机,使用bin/start-all.sh启动了hadoop之后,Slave的资源使用情况如下图所 ...

  6. Java中的OutOfMemoryError的各种情况及解决和JVM内存结构

    在JVM中内存一共有3种:Heap(堆内存),Non-Heap(非堆内存) [3]和Native(本地内存). [1] 堆内存是运行时分配所有类实例和数组的一块内存区域.非堆内存包含方法区和JVM内部 ...

  7. linux设置虚拟内存(swap)解决mysql因内存不足挂掉的故障

    mysql错误日志显示: InnoDB: mmap(137363456 bytes) failed; errno 122016-03-01 01:38:42 13064 [ERROR] InnoDB: ...

  8. android文件缓存,并SD卡创建目录未能解决和bitmap内存溢出解决

    1.相关代码: 加入权限: <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" ...

  9. 解决MyEclipse吃内存以及卡死的方法 (转)

    前言:MyEclipse5.5 大小 139M:MyEclipse6.5 大小 451M:MyEclipse7.0 大小 649M!下载服务器又是国外的...下载速度累人也就罢了,只要你工作性能一流. ...

随机推荐

  1. 8.2.3 操作MySQL数据库

    Python访问MySQL数据库可以使用MySQLDb模块,该模块主要方法如下: (1)commit():提交事务. (2)rollback():回滚事务. (3)callproc(self,proc ...

  2. OpenCV 基于超像素分割的图像区域选取方法及源码

    本系列文章由 @yhl_leo 出品,转载请注明出处. 文章链接: http://blog.csdn.net/yhl_leo/article/details/51386993 工程源码GitHub: ...

  3. [luoguP1197] [JSOI2008]星球大战(并查集)

    传送门 思维!重要的是思维! 题目让删边,然而并查集不好删边(并!查!集!啊) 我们离线处理,从后往前添边,这样并查集就可以用了. 用并查集维护连通块个数即可. ——代码 #include <c ...

  4. [TS-A1505] [清橙2013中国国家集训队第二次作业] 树 [可持久化线段树,求树上路径第k大]

    按Dfs序逐个插入点,建立可持久化线段树,每次查询即可,具体详见代码. 不知道为什么,代码慢的要死,, #include <iostream> #include <algorithm ...

  5. assign retain 和copy的区别

    assign 对基础数据类型 (NSInteger,CGFloat)和C数据类型(int, float, double, char)等 等. 此标记说明设置器直接进⾏行赋值,这也是默认值.在使⽤用垃圾 ...

  6. 开源GIS软件 3

    OpenWLANMap 与 OpenStreetMap 项目类似,OpenWLANMap 将变成一个开源的替代产品,提供 WLANs 的数据库.定位信息等. 开源排水管网GIS系统 udpnGIS 邢 ...

  7. Tween公式

    Tween公式 4个参数 t:current time(当前时间) b:beginning value(初始值) c: change in value(变化量) d:duration(持续时间) re ...

  8. CF #EDU R1 E

    最二的一次了~我开始以为是带有贪心的DP,谁知道想错了.后来才想明白,暴力二分+记忆化DP #include <iostream> #include <cstdio> #inc ...

  9. D. Multiplication Table 二分查找

    刚做这道题根本没想到二分,最关键是没想出来怎样统计在这个矩阵中比一个数小的有几个怎么算.造成自己想了好久最后看了别人的提示才做出来.哎.好久不做题太弱了 #include<iostream> ...

  10. 把握linux内核设计思想系列

    [版权声明:尊重原创,转载请保留出处:blog.csdn.net/shallnet,文章仅供学习交流,请勿用于商业用途] 本专栏分析linux内核的设计实现,包含系统调用.中断.下半部机制.时间管理. ...