【OpenCV学习笔记】之三:Mat初始创建方法----要求数据连续存储

来源:互联网 发布:天龙八部配乐知乎 编辑:程序博客网 时间:2024/05/17 08:29

      关于Mat的初始创建方法有很多,下面列举一些我喜欢使用的方法,以及使用过程中的一些注意事项。

     使用Mat的一个基本常识是:它可区分为“数据头+数据体”两大部分,并且二者在内存中是可分离的,其产生过程也不需要并发/次序完成全部,因此,一个Mat变量的存在模式有:空头、头+体。另外,数据体部分可与其它Mat变量共享。对于共享的数据区块,只有大家都不使用时才会得以销毁和释放。 膜拜OpenCV的大神们吧,竟能将Mat这一新秀设计得如此漂亮能干! 呵呵 

      在OpenCV中,表征一个区间时,一般默认为“左闭右开”的形式,所以抽取图像时需要稍加注意其边界。

1,单值填充

    Mat A(rows, cols, CV_8UC4, Scalar(1,2,3,4)); // A的四个通道依次被全部填充为 1 2 3 4    Mat B(Mat::eye(rows, cols, CV_32S));  //以 min(rows, cols)为边长构成正方形,从(0,0)开始用1填充对角线


2,多值填充

Mat sobelH =(Mat_<char>(3,3) << -1, -2, -1, 0, 0, 0, 1, 2, 1);  //填充指定值Mat A(getGaussianKernel(7, 2));   //



3,引用填充

     既然是引用,多数时候就不存在数据拷贝啦,当然有时候(基于vector和指针)也可以指定拷贝。

3.1 来自Mat  

抽取部分作为ROI

Mat B(A, Rect(10, 10, 100, 100));    //using a rectangle  [10, 100) 之间的矩形区间将被抽取Mat C(A(Rect(10, 10, 100, 100)));    // B 与 C 等价Mat D(A(Range:all(), Range(1, 3))); //using row and column boundaries 抽取[1,3) 列



3.2 来自vector

     OpenCV支持STL下的vector,并对此进行了扩展。

     按如下方式创建Mat时,只能得到一列数据,只是通道数量和数据类型有些差别,并且,诡异的是,有些函数不支持此类Mat,比如亲测发现 inRang()函数就不支持 Mat C(采用下面3.3的指针方法得到一行Mat, inRang()函数就不再报错---尺寸不匹配),所以还是少用为上。

   //A~E 都是60*1的一列,差别在于通道数量和 数据类型Mat A(vector<int>(60));         //单通道,32SMat B(vector<Vec<int, 8>>(60)); //8 通道,32SMat C(vector<Vec4i>(60));       //4 通道,32SMat D(vector<Point>(60));       //2 通道,32SMat E(vector<Point2f>(60));     //2 通道,32F//虽然编译不报错, 但 F 是无效的,不可使用,因为如此二维动态申请的内存不连续Mat F(vector<vector<int>>(60, vector<int>(4)));      




3.3 来自指针

int rows=15;   //int cols=40;int size=rows*cols;vector<int>Va(size);         vector<Vec<int, 8>>Vb(size); vector<Vec4i>Vc(size);      vector<Point>Vd(size);      vector<Point2f>Ve(size);    vector<vector<int>>Vf(size, vector<int>(4));Mat A(rows, cols, CV_32SC1, &Va[0]);         //单通道,32SMat B(rows, cols, CV_32SC(8), &Vb[0][0]);    //8 通道,32SMat C(rows, cols, CV_32SC4, &Vc[0][0]);      //4 通道,32S, 有效,但数据不大正常,估计是里面使用了 Matx类Mat D(rows, cols, CV_32SC2, &Vd[0].x);       //2 通道,32SMat E(rows, cols, CV_32FC2, &Ve[0].x);       //2 通道,32FMat F(rows, cols, CV_32SC4, &Vf[0][0]);  //无效,尽管也占据了些内存空间