常用的构造函数有:
这些构造函数中,很多都涉及到类型 type。type 可以是 CV_8UC1,CV_16SC1,...,CV_64FC4 等。里面的 8U 表示 8 位无符号整数,16S 表示 16 位有符号整数,64F表示 64 位浮点数(即 double 类型);C 后面的数表示通道数,例如 C1 表示一个通道的图像,C4 表示 4 个通道的图像,以此类推。
如果你需要更多的通道数,需要用宏 CV_8UC(n),例如:
Mat M(3,2, CV_8UC(5));//创建行数为3,列数为2,通道数为5的图像
有些 type 参数如 CV_32F未注明通道数目,这种情况下它表示单通道。
常用方法
void copyTo(); //拷贝
Mat clone(); //拷贝
int channels(); //通道,矩阵中的每一个矩阵元素拥有的值的个数
int depth(); //深度,即每一个像素的位数(bits)
bool empty() const; //判断是否为空
uchar* ptr(int i0=0); //指针取第0行数据
void convertTo(oclMat& m, int rtype, double alpha=1, double beta=0);
//m:转为目标数据类型的矩阵;
//rtype: 指定目标数据类型,或者是depth(通道数),如果rtype:是负值,那么目标矩阵的数据类型和源矩形的数据类型是一致的;
//alpha:基于尺度的变化值;
//beta:在尺度上的加和;
四个要点:
除了在构造函数中可以创建图像,也可以使用 Mat 类的 create()函数创建图像。如果 create()函数指定的参数与图像之前的参数相同,则不进行实质的内存申请操作;如果参数不同,则减少原始数据内存的索引,并重新申请内存。使用方法如下面例程所示:
Mat M(2,2, CV_8UC3);//构造函数创建图像
M.create(3,2, CV_8UC2);//释放内存重新创建图像
需要注意的时,使用 create()函数无法设置图像像素的初始值。
/**/-----以下方法在opencv3及以下版本中可行,opencv4中没有IplImage结构------//
//IplImage—>Mat
//使用Mat的构造函数:
Mat::Mat(const IplImage* img, bool copyData=false);//默认情况下copyData为false
IplImage* srcImg = cvLoadImage("Lena.jpg");
//注意:以下三种效果一致,均为浅拷贝.
Mat M(srcImg);
Mat M(srcImg, false);
Mat M = srcImg;
//注意:当将参数copyData设为true后,则为深拷贝(复制整个图像数据).
Mat M(srcImg, true);
//converting IplImage to cv::Mat
Mat image=cvarrToMat(srcImg,true);
//Mat—>IplImage
//注意:浅拷贝 --- 同样只是创建图像头,而没有复制数据.
Mat M;
IplImage img = M;
IplImage img = IplImage(M);
//深拷贝
cv::Mat img2;
IplImage imgTmp = img2;
IplImage *input = cvCloneImage(&imgTmp);
//----------------------------------------------/*/
/*/-----以下方法在opencv3及以下版本中可行,opencv4中没有IplImage结构----//
//使用Mat的构造函数:
Mat::Mat(const IplImage* img, bool copyData=false); 默认情况下copyData为false
IplImage* srcImg = cvLoadImage("Lena.jpg");
//注意:以下三种效果一致,均为浅拷贝.
Mat M(srcImg);
Mat M(srcImg, false);
Mat M = srcImg;
//注意:当将参数copyData设为true后,则为深拷贝(复制整个图像数据).
Mat M(srcImg, true);
//converting IplImage to cv::Mat
Mat image=cvarrToMat(srcImg);
//注意:浅拷贝 --- 同样只是创建图像头,而没有复制数据.
Mat M;
IplImage img = M;
IplImage img = IplImage(M);
//深拷贝
cv::Mat img2;
IplImage imgTmp = img2;
IplImage *input = cvCloneImage(&imgTmp);
//-----------------------------------------------------------/*/
浅拷贝 - 不复制数据只创建矩阵头,数据共享(更改a, b, c的任意一个都会对另外2个产生同样的作用)
Mat a = imread("1.jpg");
Mat b = a; //a "copy" to b
Mat c(a); //a "copy" to c
a.col(10) = 0;//把a的第十列全置0,b和c也相应发生变化
clone 是完全的深拷贝,在内存中申请新的空间
Mat A = Mat::ones(4, 5, CV_32F);
Mat B = A.clone() //clone 是完全的深拷贝,在内存中申请新的空间,与A独立
copyTo 也是深拷贝,但是否申请新的内存空间,取决于dst矩阵头中的大小信息是否与src一至,若一致则只深拷贝并不申请新的空间,否则先申请空间后再进行拷贝.
Mat A = Mat::ones(4, 5, CV_32F);
Mat C;
A.copyTo(C) //此处的C矩阵大小与A大小不一致,则申请新的内存空间,并完成拷 贝,等同于clone()
Mat D = A.col(1);
A.col(0).copyTo(D) //此处D矩阵大小与A.col(0)大小一致,因此不会申请空间,而是直接进行拷贝,相当于把A的第1列赋值给第二列