使用的命名空间
#pragma once
#include
#include
using namespace std;
using namespace cv;
为Mat对象开辟一段的新的存储空间
与Mat对象初始化一样,可以使用四种方式,均要指定对象的size和类型。
使用size()测试create():
Mat m2;
//m2 300行 ,200列
m2.create(Size(200, 300), CV_8UC3);
cout << "m2 rows:" << m2.rows << endl;
cout << "m2 cols:" << m2.cols << endl;
cout << "m2 size:" << m2.size() << endl;
可在不修改Mat对象数据的前提下,改变对象的通道数与行数。
改变前后满足 channels * cols * rows的值不变。
cn: 改变后的通道数
rows: 改变后的行数
他还有两个重载分别可指定维数和行列。
//reshape test
Mat m3{ 1,2,3, 4,5,6, 7,8,9 };
cout << "m3 size:" << m3.size() << endl;
Mat m4;
m4 = m3.reshape(1,3);
//m4与m3指向同一个存储空间,修改其一,另一也修改
m4 = Scalar(230);
cout << "m4 size after reshape:" << m4.size() << endl;
cout << m3.at<int>(4) << endl;
SZ :新的行数;
S :当需要添加新元素可以指定其值。
src:输入矩阵
dst:输出矩阵
dsize:输出的目标大小(列,行)
fx:输出矩阵列数的权重
fy:输出矩阵行数的权重
interpolation:新值填充方式,默认线性插值
dsize,fx,fy可以互相推导,不能同时为0;
dsize为0,dst.cols= fy * src.cols ;
dst.rows=fx * src.rows;
fx,fy为0,dst.size = dsize;
//cv::resize test
Mat m5(Size(200, 300), CV_8UC3);
Mat m6;
resize(m5, m6, Size(400, 500), 0, 0, INTER_LINEAR);
cout << "m6 size" << m6.size() << endl;
value:Scalar()对象
mask:掩码,通道大于等于1,类型必须是CV_8U,将掩码中非零位置对应在Mat对象上赋值为value。
将原Mat的对象的指定区域拷贝给新对象,他们共用同一存储区域,修改新对象,就对象也会发生改变。
多用于对图像的某一区域进行动态修改、重新赋值。
可将矩形指定区域或者指定行列的矩阵地址返回。
copyTo()与clone()都是深拷贝,即拷贝前后的Mat对象不会共用相同的存储空间,修改赋值也互不影响。
他们的区别在于 clone()会直接开辟新的存储空间,将旧对象复制并返回新对象。
而copyTo()会判断拷贝与待拷贝对象的矩阵大小是否相同,若相同则不开辟新的空间,否则开辟新的空间在复制数据。
Mat对象的拷贝构造()与赋值构造(=)均是浅拷贝,即拷贝前后对象共用相同的存储空间,改变其中一个的值,另一个也随之改变。
矩阵赋值是一个O(1)运算。这意味着不复制数据,但共享数据,并且增加引用计数器(如果有)。在分配新数据之前,通过Mat::release取消引用旧数据。
Mat对象的ptr与at用法类似,区别是ptr返回对应位置的指针,而at返回对应位置的引用。
使用ptr与at均要指定返回类型,常用的type与返回类型如下:
Mat type | 返回类型 |
---|---|
CV_8UC1 | uchar |
CV_8UC3 | Vec3b |
Vec3b = Vector
,大小为3的vector,存放数据类型为uchar,对应图像的三个通道。相应的有 Vec3f,Vec4b等类型。
Mat m7(Size(200, 300), CV_8UC3);
//使用uchar类型读取(100,200),赋值
//使用uchar指针指向三通道图像,可将uchar看做数组地址,直接用下标访问
uchar* mPtr1 = m7.ptr<uchar>(100,200);
mPtr1[0] = 60;
mPtr1[1] = 160;
mPtr1[2] = 230;
//使用Vec3b类型读取(100,100),赋值
Vec3b* mPtr2 = m7.ptr<Vec3b>(100, 100);
//mPtr2本身是一个指向Vec3b的指针,需要解引用获取Vec3b数组本身,在对每个通道赋值
(* mPtr2)[0] = 55;
(* mPtr2)[1] = 155;
(* mPtr2)[2] = 255;
//结果需要转为int
Vec3b mAt = m7.at<Vec3b>(100, 100);
cout << (int)mAt[0] << endl;
cout << (int)mAt[1] << endl;
cout << (int)mAt[2] << endl;
文章内容有误或可改正地方,可私信,会即使修改。