OPenCV4Android中Mat对象的内存若干测试(2)

继续做测试,这次要测试的是OpenCV for Android API 中的submat方法,该方法可以看做是Android中ROI的一种实现,因其返回的mat对象比较特殊,因此也对其常见操作进行了简单的测试。为方便叙述,原图对象称为原图mat,submat提取的mat对象称为子图mat。

测试代码如下:(关于屏幕输出用的是System.out.println而不是Log.i,这只是我个人抽抽而已)

private void Test_SubMatrix()
	{
		//构建位图原图
		Mat mat=Highgui.imread(mImagePath);
		//创建子区域(左上角坐标与原图一致)
		Mat subMat=mat.submat(0, 20, 0, 20);
		
		//打印两个mat的详细信息
		System.out.println("mat info: "+mat.toString());
		System.out.println("submat info: "+subMat.toString());
		
		//访问原图像素值
		double[] matpixel=mat.get(1, 1);
		System.out.print("mat pixel in (1,1)");
		for (double d : matpixel)
		{
			System.out.print("("+d+" )");
		}
		System.out.println();
		
		//访问子区域图像素值
		double[] submatpixel=subMat.get(1, 1);
		System.out.println("submat pixel in (1,1)");
		for (double d : submatpixel)
		{
			System.out.print("("+d+" )");
		}
		System.out.println();
		
		//修改子区域像素值
		double[] updataPixe=new double[]{12,33,55};
		subMat.put(1, 1, updataPixe);
		
		//访问原图像素值
		matpixel=mat.get(1, 1);
		System.out.println("mat pixel in (1,1)");
		for (double d : matpixel)
		{
			System.out.print("("+d+" )");
		}
		System.out.println();
		
		//访问子区域图像素值
		submatpixel=subMat.get(1, 1);
		System.out.println("submat pixel in (1,1)");
		for (double d : submatpixel)
		{
			System.out.print("("+d+" )");
		}
		System.out.println();
		
		//释放子区域
		subMat.release();
		
		//打印两个mat的详细信息
		System.out.println("submat is empty is "+(subMat.empty()));
		System.out.println("mat is empty is "+(mat.empty()));
		
		//访问原图详细
		System.out.println("mat pixel in (1,1)");
		for (double d : matpixel)
		{
			System.out.print("("+d+" )");
		}
		System.out.println();
		
	}

测试结果:


分析

1.由第一次原图mat与子图mat的打印结果可以看出来。两者虽然有着不同的本地地址(nativeref)但两者的数据地址(dataAdd)是一直的。按照OpenCV的观点来说就是submat创建的子图mat只有“头结构”,(或者元数据metadata).而子图mat的图像数据和原图mat的图像数据共享一片内存。因此,在第一次对两个mat的(1,1)元素进行访问时,实际是对同一个内存访问了两次。

2.共享内存,就导致了子图mat与原图mat之间的修改会相互影响。测试中,我们对子图mat中(1,1)位置的元素修改了像素值,结果表明原图mat也进行了相应修改。因此,当后期我们操作子图mat时,也要注意避免数据修改对原图的影像。

3.修改中最特殊的应当算是释放内存操作,而由Mat对象的打印信息来看,OpenCV专门为Mat对象添加了IsSubmat标示符,用于防止因release()方法的调用者是子图mat而导致的对原图mat的内存释放修改。不过,用于子图mat只有“头结构”因此,也不会出现因没有调用release()而出现的内存泄露问题。


当然,听说在OpenCV android API 也提供了locateROI的方法,只是目前还没有测试与应用。还望各位看官包含。


  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值