opencv Mat使用总结

一、Mat和IplImage

1、IplImage*,直接暴露内存,如果忘记释放内存,就会造成内存泄漏。
2、从OpenCV2开始,开始使用Mat类存储图像,具有以下优势:

(1)图像的内存分配和释放由Mat类自动管理
(2)Mat类由两部分数据组成:矩阵头(包含矩阵尺寸、存储方法、存储地址等)和一个指向存储所有像素值的矩阵(根据所选存储方法的不同,矩阵可以是不同的维数)的指针。Mat在进行赋值和拷贝时,只复制矩阵头,而不复制矩阵,提高效率。如果矩阵属于多个Mat对象,则通过引用计数来判断,当最后一个使用它的对象,则负责释放矩阵。

(3)可以使用clone和copyTo函数,不仅复制矩阵头还复制矩阵

二、Mat创建

rows 是 行数 相当于 height 对应 .y
cols 是 列数 相当于 width 对应 .x

Mat构造函数

 //! constructs 2D matrix of the specified size and type
 // (_type is CV_8UC1, CV_64FC3, CV_32SC(12) etc.)
    Mat(int rows, int cols, int type);

 //! constucts 2D matrix and fills it with the specified value _s.

    Mat(int rows, int cols, int type, const Scalar& s);

1、使用Mat构造函数
Mat test(2,2,CV_8UC3,Scalar(0,0,255));

2、使用Mat构造函数2
int sizes[3] = {2,2,2};
Mat test(3,sizes,CV_8UC3,Scalar::all(0));

3、为已存在的IplImage指针创建信息头
IplImage* img = cvLoadImage("1.jpg",1);
Mat test(img);

4、利用create函数
Mat test;
test.create(4,4,CV_8UC2);

5、采用Matlab形式的初始化方式
(1)Mat me = Mat::eye(4,4,CV_64F);
(2)Mat mo = Mat::ones(2,2,CV_32F);
(3)Mat mz = Mat::zeros(3,3,CV_8UC1);
注:元素类型,即CV_[位数][带符号与否][类型前缀]C[通道数]

三、访问矩阵元素

//1.at函数
M.at<double>(i,j) += 1.f;	//set (i,j)-th element
int a = M.at<int>(i,j);		//get (i,j)-th element
//2.矩阵元素指针(ptr)
for(int i = 0; i < M.rows; i++)
{
    const double* pData = M.ptr<double>(i);	//第i+1行的所有元素
    for(int j = 0; j < M.cols; j++)
		cout<<pData[j]<<endl;
}
1、Mat类型是自动内存管理,不需要显式释放(当然也可以手动调用release()方法强制Mat矩阵数据释放);而CvMat则需要调用cvReleaseMat(&cvmat)来释放,IplImage需要调用cvReleaseImage(&iplimage)来释放。
2、建立CvMat矩阵时,第一个参数为行数,第二个参数为列数:
CvMat* cvCreateMat( int rows, int cols, int type );
3、建立IplImage图像时,CvSize第一个参数为宽度,即列数;第二个参数为高度,即行数:
IplImage* cvCreateImage(CvSize size, int depth, int channels );
CvSize cvSize( int width, int height );

4、IplImage内部buffer每行是按4字节对齐的,CvMat没有这个限制。


参考:

1.https://www.cnblogs.com/justkong/p/7278579.html

2.https://blog.csdn.net/holybin/article/details/17751063

猜你喜欢

转载自blog.csdn.net/qq_42189368/article/details/80717718