首页 > 系统相关 >图像识别与处理之Opencv——Mat_类与Mat 类的内存管理

图像识别与处理之Opencv——Mat_类与Mat 类的内存管理

时间:2024-08-07 10:21:19浏览次数:9  
标签:图像识别 Mat int double 代码 矩阵 Opencv d1

Mat_类
Mat_类是对 Mat 类的一个包装,其定义如下

点击查看代码
template<typename _Tp> class Mat_ : public Mat
{
public:
//只定义了几个方法
//没有定义新的属性
};
这是一个非常轻量级的包装,既然已经有 Mat 类,为何还要定义一个 Mat_类? 下面我们看这段代码:
点击查看代码
Mat M(600, 800, CV_8UC1);
for( int i = 0; i < M.rows; ++i)
{
    uchar * p = M.ptr<uchar>(i);
    for( int j = 0; j < M.cols; ++j )
     {
        double d1 = (double) ((i+j)%255);
        M.at<uchar>(i,j) = d1;
        double d2 = M.at<double>(i,j);//此行有错
     }
}
在读取矩阵元素时,以及获取矩阵某行的地址时,需要指定数据类型。这样首先需要不停地写“”,让人感觉很繁琐,在繁琐和烦躁中容易犯错,如上面代码中的错误,用 at()获取矩阵元素时错误的使用了 double 类型。这种错误不是语法错误,因此在编译时编译器不会提醒。在程序运行时, at()函数获取到的不是期望的(i,j)位置处的元素,数据已经越界,但是运行时也未必会报错。这样 的错误使得你的程序忽而看上去正常,忽而弹出“段错误”,特别是在代码规模很大时,难以查错。 如果使用 Mat_类,那么就可以在变量声明时确定元素的类型, 访问元素时不再需要指定元素类型,即使得代码简洁,又减少了出错的可能性。上面代码可以用 Mat_实现,实现代码如下面例程里的第二个双重 for 循环。
点击查看代码
#include<iostream>
#include"opencv2/opencv.hpp"
#include<stdio.h>
using namespace std;
using namespace cv;

int main()
{
	Mat M(600, 800, CV_8UC1);
	for (int i = 0; i < M.rows; ++i)
	{
	//获取指针时需要指定类型
		uchar* p = M.ptr<uchar>(i);
		for (int j = 0; j < M.cols; ++j)
		{
			double d1 = (double)((i + j) % 255);
			//用at()读写像素时,需要指定类型
			M.at<uchar>(i, j) = d1;
			//下面代码错误,应该使用at<uchar>()
			//但编译时不会提醒错误
			//运行结果不正确,d2不等于d1
			double d2 = M.at<double>(i, j);
			cout << "d1=" << d1 << endl;
			cout << "d2=" << d2 << endl;
		}

	}

	
	system("pause");
	return 0;
}

换成Mat_
点击查看代码
#include<iostream>
#include"opencv2/opencv.hpp"
#include<stdio.h>
using namespace std;
using namespace cv;

int main()
{
	Mat M(600, 800, CV_8UC1);
	//在变量声明时指定矩阵元素类型
	Mat_<uchar>M1 = (Mat_<uchar>&)M;
	for (int i = 0; i < M1.rows; ++i)
	{
		//不需指定元素类型,语句简洁
		uchar* p = M1.ptr(i);
		for (int j = 0; j < M1.cols; ++j)
		{
			double d1 = (double)((i + j) % 255);
			//直接使用Matlab风格的矩阵元素读写,简洁
			M1(i, j) = d1;
			double d2 = M1(i, j);
			cout << "d1=" << d1 << endl;
			cout << "d2=" << d2 << endl;
		}


	}


	system("pause");
	return 0;
}
Mat类的内存管理 使用Mat类,内存管理变得简单,不再像使用IpIImage那样需要自己申请和释放内存。虽然不了解Mat的内存管理机制,也无碍于Mat类的使用, 但是如果清楚了解Mat的内存管理,会更清楚一些函数到底操作了哪些数据。

Mat是一个类,由两个数据部分组成:矩阵头(包含矩阵尺寸,存储方法,存储地址等信息)和一个指向存储所有像素值的指针,如下图所示。矩阵头
的尺寸是常数值,但矩阵本身的尺寸会依透骨香的不同而不同,通常比矩阵头的尺寸大数个数量级。复制矩阵数据往往花费较多时间,因此除非有
必要,不要复制大的矩阵。

为了解决矩阵数据的传递,OpenCV使用了引用计数机制,其思路是让每个Mat对象有自己的矩阵头信息,但多个Mat对象可以共享同一个矩阵数据。
让矩阵指针指向同一地址而实现这一目的。很多函数以及很多操作(如函数参数传值)只复制矩阵头信息,而不复制矩阵数据。

前面文提到过,有很多种方法创建Mat类。如果Mat类自己申请数据空间,那么该类会多申请4个字节,多出的4个字节存储数据被引用的次数。
引用次数存储于数据空间的后面,refcount指向这个位置,如下图所示。当计数等于0时,则释放该空间。

标签:图像识别,Mat,int,double,代码,矩阵,Opencv,d1
From: https://www.cnblogs.com/SunshineWeather/p/18346457

相关文章

  • SciTech-Mathematics-Probability+Statistics-Comparison:Chance + Possibility + Lik
    https://www.geeksforgeeks.org/what-is-the-difference-between-likelihood-and-probability/1.Chance2.Possibility3.Likelihood4.ProbabilityWhatIstheDifferenceBetween“Likelihood”and“Probability”?LastUpdated:30Jul,2024https://www.geeksforg......
  • 使用 Python 中的 Matplotlib 和时间序列索引生成奇怪的图
    我正在尝试使用Python中的Matplotlib绘制一些时间序列数据,但生成的图看起来很奇怪,我不明白为什么。这是我正在使用的代码:filtered_df=df.loc[(df.index>'2010-01-01')&(df.index<='2010-01-08')]#Plottingthedatafig,axs=plt.subplots(1,1,figsize=(12,......
  • Xticks 标签贴在我的绘图 matplotlib 的右上角?
    我的顶部xticks标签卡在matplotlit图的右上角。如何将它们设置在时间序列的正确位置?底部的xtick标签很好。我只想将顶级的与他们匹配。我怎样才能做到这一点?请参阅下面的代码和图像。importmatplotlib.pyplotasplttime_zones=pd.to_datetime(["2022-07-312:00",......
  • 基于深度学习网络的USB摄像头实时视频采集与火焰检测matlab仿真
    1.算法运行效果图预览(完整程序运行后无水印) 将usb摄像头对准一个播放火焰的显示器,然后进行识别,识别结果如下:    本课题中,使用的USB摄像头为:   2.算法运行软件版本MATLAB2022a 3.部分核心程序(完整版代码包含详细中文注释和操作步骤视频) 程序中包......
  • SciTech-Mathematics-Probability+Statistics-Causation vs. Correlation: From Corre
    https://www.statology.org/from-correlation-to-causation-deep-dive-into-data-interpretation/FromCorrelationtoCausation:DeepDiveintoDataInterpretationCorrelationandCausationarekeyconceptsindataanalysis.However,correlationdoesn'tme......
  • 【Material-UI】按钮组件中的实验性API:Loading按钮详解
    文章目录一、LoadingButton组件概述1.组件介绍2.基本用法二、LoadingButton组件的高级用法1.自定义加载指示器2.图标与加载位置三、已知问题与解决方法1.Chrome翻译工具与LoadingButton的兼容性问题四、实用性与未来展望1.应用场景2.未来展望五、总结......
  • 【论文笔记】Cross-Domain WiFi Sensing with Channel State Information: A Survey
    Cross-DomainWiFiSensingwithChannelStateInformation:ASurveyIntroduction检测领域:检测领域里,大部分用的阈值检测或者简单的学习算法,例如SVM。fallsRT-Fall:Areal-timeandcontactlessfalldetectionsystemwithcommodityWiFidevicesWiFall:Device-fr......
  • QRGRU-基于分位数回归门控循环单元的时间序列/回归区间概率预测matlab代码
    本人整理了QRGRU基于分位数回归门控循环单元的时间序列/回归区间概率预测matlab代码,该代码质量优异,出图精美,有详细注释,适合新手学习使用。1.多变量回归或时序预测均可,不加价~适用于matlab2020及以上。可任意选择置信区间,评价指标包括R2、MAE、区间覆盖率picp、区间平均宽度百分......
  • Matlab第一章
    Matlab第一章1.命令行窗口里写的命令,当文件关闭时命令行窗口和工作区内容消失。2.想要保存代码,方法是:新建脚本->写代码->保存->运行3.脚本语言(1)clear;清空工作区clc;清空命令行窗口x=20;y=30;x+y(2)clear;clc;x=20;y=30;x+y;如果x+y有分号则命令行窗口不会输出......
  • 【学习笔记】Matlab和python双语言的学习(最大最小化规划)
    文章目录前言一、最大最小化规划二、选址问题三、代码实现----Matlab1.Matlab的`fminimax`函数2.Matlab代码四、代码实现----python总结前言通过模型算法,熟练对Matlab和python的应用。学习视频链接:https://www.bilibili.com/video/BV1EK41187QF?p=28&vd_sour......