OpenCV深入学习(2)-Mat构造初始化等
来源:互联网 发布:app推广网站源码 编辑:程序博客网 时间:2024/05/17 09:11
主要是手册中关于该部分的翻译;
有很多的创建Mat对象的方法,主要的有以下:
1、使用create(nrow,ncols,type)函数,或者相似的构造函数Mat(nrow,ncols,type[,fillValue]),将分配新的指定大小和格式的数组,
type的意义和cvCreateMat函数一样,例如CV_8UC1意思是创建8位单通道的数组,而CV_32FC2则是两通道的浮点数数组;例如:
//创建一个7*7的复数矩阵并且初始化为1+3j;cv::Mat M(7,7,CV_32FC2, Scalar(1,3));//然后将M转换为100*60的15通道的8位矩阵;M.create(100,60,CV_8UC(15));
正如开始时介绍的一样,create()函数只在当前数组大小或者类型与指定的不一样时才分配新的数组。
2、与1类似的,还可以创建一个多维数组:
//创建100*100*100的8位数组int sz[]={100,100,100};cv::Mat bigCube(3, sz, CV_8U, Scalar::all(0));
即使传递给构造函数的维数参数dimensions=1,创建的数组也会是2维数组,即参数dims=2,函数会将矩阵视为只有多行一列的矩阵,所以Mat::dims一直是大于等于2的(数组为空时是0);
3、使用复制构造函数或者复制操作符,如下所示;正如介绍的那样,赋值操作的计算复杂度是O(1)的,因为只是进行对象头的复制和引用计数的增加(并没有真的复制数据),当需要时可以使用函数Mat.clone()
来获得数组的完整拷贝。
4、为其他的Mat数组构造一个新的头,Mat数组可以是一行,一列,多行,多列,矩阵数组中的一块矩形区域或者对角线,这些操作的复杂度也是O(1),因为新的头指向相同的数据,
可以使用这种特点来改变数组的一部分,例如:
//将第5行的三倍加到第3行上M.row(3)=M.row(3)+M.row(5)*3;//将第7列复制到第1列,使用 M.col(1)=M.col(7) 将不会奏效,应该使用如下方法:Mat M1 = M.col(1);M.col(7).copyTo(M1);//创建一幅320×240的图像Mat img(Size(320,240), CV_8UC3);//选择一块ROIMat roi(img, Rect(10, 10, 100, 100));//将ROI的颜色填充为绿色,原始的img图像将会改变。roi=Scalar(0,255,0);
因为额外的成员:datastart和dataend的帮助,可以使用locateROI()函数计算子块在主数组中的相对位置;
Mat A=Mat::eye(10,10, CV_32S);//析取A的列[1,3),左闭右开区间;Mat B = A(Range::all(), Range::(1,3));//析取B的行[5,9),这样C就是A的5-8行,1-2列;Mat C = B(Range::(5,9),Range::all());Size size;Point ofs;C.locateROI(size, ofs);//size为(10,10),ofs(x=1,y=5)
如果需要,可以使用clone()函数来复制析取的子矩阵。
5、给用户外部数据分配对象头,这种方法在下面情况中有用:
(1)、使用OpenCV处理外部数据(如自己实现的DirectShow的过滤器或者gstreamer的处理模块等),例如
void process_video_frame(const unsigned char *pixels, int width, int height, int step){Mat img(height, width, CV_8UC3, pixels, step);//注意此处height和width的与cols和rows的对应关系;GaussianBlur(img, img, Size(7,7), 1.5,1.5);}
(2)、快速初始化小的矩阵并且\或者获得super-fast的元素获取速度;
double m[3][3] = {{a,b,c},{d,e,f},{g,h,i}};Mat M = Mat(3,3, CV_64F, m).inv();
不常用但是非常普遍的使用用户分配数据的情况就是从CvMat或者IplImage向Mat转换时【partial yet very common cases of this..case】,
为此有专门的以指向CvMat或IplImage的指针和可选的指出是否进行数据复制的标志flag为参数的Mat构造函数。
从Mat到CvMat或IplImage的反向转换由重载的操作符Mat::operator CvMat()和Mat::operator IplImage()完成,该操作不会复制数据!
IplImage *img = cvLoadImage("greatewave.jpg",1);Mat mtx(img); //IplImage*->MatCvMat oldmat = mtx; //Mat->CvMatCV_Assert(oldmat.cols==img->width && oldmat.rows==img->height && oldmat.data.ptr==(uchar *)img->imageData && oldmat.step==img->widthStep);
6、使用MATLAB样式的矩阵初始化函数,zeros(),ones(),eys(),例如:
//创建双精度的单位矩阵并将其加到M上;
M += Mat::eye(M.rows, M.cols, CV_64F);
7、使用逗号分隔初始化;
//创建3×3的双精度单位阵;
Mat M = (Mat_<double>(3,3) << 1,0,0,0,1,0,0,0,1);
使用该方法可以先调用一个给定了合适参数的Mat_类的构造函数,然后就可以使用<<操作符将用逗号分隔的值输入,这些值可以使常量,变量,表达式等;注意为避免编译错误则加上的额外的括号;
【到此基本上创建Mat矩阵的常用方法就比较全了,看了一下构造函数中还有几个实用模板实现的构造函数,参数是Vec,Matx以及vector的;
8、使用模板的构造函数;
const int dimss=40;vector<float> stl_vec;Vec<short, dimss> vecs;Matx<double, 30, 50> matxs;for (int i=0; i<dimss; ++i){vecs[i] = i*3;stl_vec.push_back(i*10.f);}Mat vecMat(vecs);Mat matxMat(matxs);Mat stlvecMat(stl_vec,true);
使用该方法主要是用于将向量表示转换为Mat的矩阵表示方便处理,关键是向量的构造,像使用findContour获得的轮廓,
可以将Point的vector转换为Mat处理;
】
--------------------------------------------------------------------------------
Mat的构造创建以及初始化常用的基本上就这几种。下一次将总结一下Mat元素的获取方法。
- OpenCV深入学习(2)-Mat构造初始化等
- OpenCV学习笔记(2):Mat矩阵的初始化
- OpenCV学习笔记(2):Mat矩阵的初始化
- OpenCV学习笔记(2):Mat矩阵的初始化
- Opencv 学习笔记(2):Mat矩阵的初始化
- OpenCV学习篇1:Mat类构造
- opencv Mat() 构造函数
- opencv深入学习(1)--Mat主要成员变量
- OpenCV深入学习(4)--Mat元素的获取方法
- OpenCV深入学习(7)--Mat的元素分布图示详解
- opencv深入学习(1)--Mat主要成员变量
- opencv深入学习(1)--Mat主要成员变量
- opencv深入学习(1)--Mat主要成员变量
- 【学习OpenCV】—— 深入了解 cv::Mat
- 【OpenCV学习笔记】二、深入了解 cv::Mat
- OpenCv:Mat矩阵的初始化
- openCV(1)-Mat初始化
- OpenCv矩阵(Mat)的构造
- Ubuntu下NS3安装步骤
- 计算几何 ural 1754. Explosion in a Pyramid
- 警世之言
- WinCE中触摸屏驱动开发详解(2440)
- Java基础之abstract class与interface,Override与Overload
- OpenCV深入学习(2)-Mat构造初始化等
- <转载>条件变量(互斥量)与pthread_cond_wait函数详解
- 合并烧写程序BIN文件的两种方法
- sendRedirect,include,forward的区别
- 访问webservice 时遇到的概念 HTTP-GET 和 HTTP-POST 的比较
- js与java互调(webkit开发)
- Ubuntu下安装ns-allinone-2.35.tar.gz
- 用cmd命令杀死进程
- LM3S系列芯片出厂ISP烧写程序