CV::MAT总结
来源:互联网 发布:中国工具书网络出版 编辑:程序博客网 时间:2024/06/07 05:32
CV::MAT
1 基础知识
MAT是opencv2.X里面新出现配合C++的n-dimensional dense array class。强烈推荐大家使用
我们先看一下结构:
class CV_EXPORTS Mat{public: // ... a lot of methods ... ... /*! includes several bit-fields: - the magic signature - continuity flag - depth //深度 - number of channels //通道数 彩图rgb 3通道 */ int flags; //! the array dimensionality, >= 2 int dims; //维度 //! the number of rows and columns or (-1, -1) when the array has more than 2 dimensions int rows, cols; //行,列 //! pointer to the data uchar* data; //数据指针 //! pointer to the reference counter; // when array points to user-allocated data, the pointer is NULL int* refcount; //引用次数 // other members ...};
数据类型属性:
type格式:
表示了矩阵中元素的类型以及矩阵的通道个数,它是一系列的预定义的常量,其命名规则为CV_(位数)+(数据类型)+(通道数)。具体的有以下值:
其中没有通道信息便是depth:
CV_8U - 8-bit unsigned integers ( 0..255 )
CV_8S - 8-bit signed integers ( -128..127 )
CV_16U - 16-bit unsigned integers ( 0..65535 )
CV_16S - 16-bit signed integers ( -32768..32767 )
CV_32S - 32-bit signed integers ( -2147483648..2147483647 )
CV_32F - 32-bit floating-point numbers ( -FLT_MAX..FLT_MAX, INF, NAN )
CV_64F - 64-bit floating-point numbers ( -DBL_MAX..DBL_MAX, INF, NAN )
U(unsigned integer)表示的是无符号整数,S(signed integer)是有符号整数,F(float)是浮点数。
step:内存地址
如需更详细信息请进
Mat这个类有两部分数据。一个是matrix header,这部分的大小是固定的,包含矩阵的大小,存储的方式,矩阵存储的地址等等。另一个部分是一个指向矩阵包含像素值的指针。对于Mat数据结构,在对图像进行处理时要
使用OpenCV的C++接口时不需要考虑内存释放问题。赋值运算符和拷贝构造函数( ctor )只拷贝信息头,这样构造出来的Mat共用一个矩阵空间,修改任意Mat的值将互相影响。使用函数 clone() 或者copyTo() 可以复制整个图像的矩阵数据。
创建MAT
构造函数用的比较多的:
C++: Mat::Mat(int rows, int cols, int type, const Scalar& s)
C++: Mat::Mat(const IplImage* img, bool copyData=false)
int main() { /*******************************Mat基本操作-创建矩阵*****************************************/ //二维三通道矩阵建立 Mat M(3,3, CV_8UC3, Scalar(0,0,255)); //使用构造函数创建矩阵 /* CV_8UC3 表示使用8位的 unsigned char 型,每个像素由三个元素组成三通道,初始化为(0,0,255) */ cout << "M = " << endl << " " << M << endl << endl; //格式化输出 //三维 int sz[3] = {3,3,3}; Mat L(3,sz, CV_8UC(1), Scalar::all(0)); /* 超过两维的矩阵:指定维数,然后传递一个指向一个数组的指针,这个数组包含每个维度的尺寸;其余的相同 */ /*****************************************Mat基本操作-图像*******************************/ Mat A, C; // 只创建信息头部分 A=imread("D:\\openCV\\openCVProject\\openCv1\\test.jpg", CV_LOAD_IMAGE_COLOR); // 这里为矩阵开辟内存 Mat B(A); // 使用拷贝构造函数 C = A; // 赋值运算符 /* 拷贝构造函数和赋值函数 只拷贝信息头和矩阵指针 */ Mat D (A, Rect(10, 10, 100, 100) ); //选取A中一个矩形区域,即只访问其矩形区域的信息头,只是创建信息头 Mat E = A(cv::Range::all(), Range(1,3)); // 创建访问边界的信息头。 /* 要创建一个感兴趣区域( ROI ),你只需要创建包含边界信息的信息头 */ Mat F = A.clone();//复制图像,包括数据 Mat G; A.copyTo(G); /* 拷贝矩阵本身(不只是信息头和矩阵指针), */ //测试 namedWindow( "a", CV_WINDOW_AUTOSIZE ); namedWindow( "c", CV_WINDOW_AUTOSIZE ); imshow( "a", D); imshow( "c", E ); /******************************图像的读取、处理和保存*********************************/ Mat image; image = imread( "D:\\openCV\\openCVProject\\openCv笔记\\openCv笔记\\test.jpg", CV_LOAD_IMAGE_COLOR);//导入图像 if( !image.data ) { cout<< " No image data \n " ; return -1; } Mat gray_image; cvtColor( image, gray_image, CV_BGR2GRAY );//转化为灰度图 imwrite( "../../images/Gray_Image.jpg", gray_image );//写入图像 namedWindow( "source", CV_WINDOW_AUTOSIZE ); namedWindow( "Gray image", CV_WINDOW_AUTOSIZE ); imshow( "source", image ); imshow( "Gray image", gray_image ); /*******************************************************************************************/ waitKey(0); return 0; }
2 用法简介
(1)遍历元素方法
遍历元素的方法很多,但是时间和速度上还是有很大的差别,迭代器是最安全的,指针是速度最快的方式。
#include<cv.h> #include<highgui.h> #include<time.h> #include<iostream> using namespace cv; using namespace std; int main() { //Mat img(10,10,CV_8UC3,Scalar(0,0,255)); Mat img,img_gray,img_gray2; img=imread("D:\\openCV\\openCVProject\\openCv1\\test.jpg", CV_LOAD_IMAGE_COLOR); cvtColor( img, img_gray, CV_BGR2GRAY );//转化为灰度图 img_gray.copyTo(img_gray2); //**方式一 .ptr and []或指针 ***推荐方式***速度最快,行列清晰利,不分通道 nr=img_gray.rows; nc=img_gray.cols*img_gray.channels(); for( int i=0;i<nr;i++) { uchar* data = img_gray.ptr<uchar>(i); for(int j=0;j<nc;j++) { data[j] = 255; //或*data++=255; } } //img.create(10,10,CV_8UC3,Scalar(0,0,255)); //cout << "img = " << endl << " " << img_gray << endl << endl; //格式化输出 //**方式二 W*H的一幅图像看成是一个1*(w*h)的一个一维数组 ***速度较快***不分行列通道 int nc; if(img_gray.isContinuous())//判断是否被所有的像素填满 { nc = img_gray.rows*img_gray.cols*img_gray.channels();//行 列 通道的乘积 } else { cout<<"像素未填满,不可用第二种方式"<<endl; return -1; } uchar* data_2 = img_gray.ptr<uchar>(0);//提取第一个像素点指针 for(int i=0;i<nc;i++)//遍历所有的元素 { data_2[i] = 255; } //方式三指针扫描 ***.at<uchar>(0,0)速度较慢***分通道赋值 uchar* data_3 = img.data;//单个元素 img.at<uchar>(0,0)=0; for(int i=0;i<img.rows;i++)//遍历所有的元素 { for(int j=0;j<img.cols;j++) { data_3 = img.data + i*img.step + j * img.elemSize(); //对各个通道赋值 data_3[0]=100; data_3[1]=100; data_3[2]=100; } } /*时间函数 double start = getTickCount(); finish = clock(); duration = (double)(finish - start) / CLOCKS_PER_SEC; */ //方式四 迭代器iterator扫描图像 Mat_<Vec3b>::iterator it = img.begin<Vec3b>(); Mat_<Vec3b>::iterator itend = img.end<Vec3b>(); for (; it!=itend; it++) { //对各个通道赋值 (*it)[0] = 200; (*it)[1] = 200; (*it)[2] = 200; } //测试,根据自己的选择查看结果 namedWindow("sorce",WINDOW_AUTOSIZE); namedWindow("result",WINDOW_AUTOSIZE); cv::imshow("sorce",img); cv::imshow("result",img_gray); waitKey(0); return 0; }
'using at'不推荐,速度慢,定位一个元素时可以使用Mat H(100, 100, CV_64F);for(int i = 0; i < H.rows; i++) for(int j = 0; j < H.cols; j++) H.at<double>(i,j)=1./(i+j+1);'using ptr' 行指针for(int i = 0; i < H.rows; i++)uchar* data = img_gray.ptr<uchar>(i); for(int j = 0; j < H.cols; j++)
(2)
3 注意事项
1。赋值问题,copyto两矩阵参数必须相同,否则将建立一个新的拷贝独立于共用矩阵。
2。
- CV::MAT总结
- cv...Mat...
- cv:Mat
- cv::mat
- cv:mat
- cv::Mat
- cv::Mat
- OpenCV 中cv::Mat 和 IplImage 的转换总结
- OpenCV中:CvArr、CvMat、IplImage、cv::Mat和cv::InputArray的相关总结
- cv::Mat学习
- 【转载】cv::Mat学习
- cv::Mat和IPlImage
- OpenCV笔记(cv::Mat)
- cv::Mat结构
- cv::Mat的介绍
- cv::Mat和 IplImage
- cv::mat to IplImage
- OpenCv cv::Mat用法
- 盒子阴影。转载自无极天宗的博客 http://blog.sina.com.cn/sun86yu。转载只为自用
- Could not calculate build plan Plugin org.apache.maven.pluginsmaven-resour
- 【转】Linux中常用操作命令
- Leetcode5 Rotate Image
- 养成良好编程习惯-写伪代码
- CV::MAT总结
- 1003. Emergency (25)
- sublime插件安装
- Mybatis动态更新
- 自定义控件(面试热门问题之一)
- 关于文本文件中的 "\n"
- C++中strcmp的头文件问题
- 清除svn密码
- 进程间同步