本系列文章由 @YhL_Leo 出品,转载请注明出处。

文章链接: http://blog.csdn.net/yhl_leo/article/details/47683127


本文主要介绍Opencv常用的三种Mat类型:MatMat_Matx

1. Mat

1.1 创建与初始化
  1. int rows = 3, cols = 1;
  2. cv::Size size(cols, rows);
  3. /* first method */
  4. cv::Mat myMat( rows, cols, CV_8UC1, cv::Scalar(0) );
  5. cv::Mat myMat = cv::Mat( rows, cols, CV_8UC1, cv::Scalar(0) );
  6. cv::Mat myMat( size, CV_8UC1, cv::Scalar(0) );
  7. cv::Mat myMat( cv::Size(cols, rows), CV_8UC1, cv::Scalar(0) );
  8. /* second method */
  9. cv::Mat myMat2;
  10. myMat = cv::Mat( rows, cols, CV_8UC1 );
  11. // initial with other mat or data
  12. myMat.copyTo(myMat2); // initial with mat
  13. cv::Point3i pts( 1, 2, 3 );
  14. myMat2 = cv::Mat(pts, true); // initial with other data

注意:

  1. 使用Mat::Mat(int rows, int cols, int type, const Scalar& s)Mat::Mat(Size size, int type, const Scalar& s)函数进行Mat初始化的时候,一定要注意Size行列存放顺序是(col, row)或者是(width, height)

  2. Mattype种类非常多,可以创建普通的CV_8UC1, ... , CV_64FC41-4通道的矩阵,也可以创建更高通道的矩阵CV_8UC(n), ... , CV_64FC(n),其中最大可以达到CV_CN_MAX通道,Opencv 2.4.11版本中#define CV_CN_MAX 512

  3. 创建多通道Mat时,例如CV_8UC3,使用cv::Scalar(0, 0,0)myMat.setTo(cv::Scalar(0)),其中后者通用于任意通道;

  4. 使用其他Mat拷贝初始化的时候,void Mat::copyTo(OutputArray m) const函数会首先调用m.create(this->size(), this->type())所以会对输入的m进行重新创建(包括sizetype),然后进行数据拷贝。m.copyTo(m)也是允许的,没有任何问题。

1.2 数据访问

这里只列举出常用三种方法:

1.指针数组的方式

  1. cv::Mat image = cv::imread( "E:\\test.JPG", CV_LOAD_IMAGE_GRAYSCALE );
  2. const int rows = image.rows;
  3. const int cols = image.cols;
  4. uchar* data = (uchar*)image.data;
  5. for ( int i=0; i<rows; i++ )
  6. {
  7. for ( int j=0; j<cols; j++ )
  8. {
  9. int index = i*cols + j;
  10. data[index] = 0;
  11. /*
  12. if color one:
  13. data[index * 3 + 0] = 0;
  14. data[index * 3 + 1] = 0;
  15. data[index * 3 + 2] = 0;
  16. */
  17. }
  18. }
  19. /*
  20. // also can be used as follow:
  21. for ( int i=0; i<rows; i++ )
  22. {
  23. uchar* data = (uchar*)image.data + i*cols;
  24. for ( int j=0; j<cols; j++ )
  25. {
  26. *data++ = 0;
  27. }
  28. }
  29. }
  30. */
  31. // cv::imwrite( "E:\\test2.JPG", image );

2..ptr的方式

  1. /* .ptr with [] */
  2. for ( int i=0; i<rows; i++ )
  3. {
  4. uchar *data = image.ptr<uchar>( i );
  5. for ( int j=0; j<cols; j++ )
  6. {
  7. data[j] = 0;
  8. /*
  9. if color one:
  10. data[j*3 + 0] = 0;
  11. data[j*3 + 1] = 0;
  12. data[j*3 + 2] = 0;
  13. */
  14. }
  15. }
  16. /* .ptr with pointer */
  17. for ( int i=0; i<rows; i++ )
  18. {
  19. uchar *data = image.ptr<uchar>( i );
  20. for ( int j=0; j<cols*image; j++ )
  21. {
  22. *data++ = 0;
  23. }
  24. }

3..at的方式

  1. for ( int i=0; i<rows; i++ )
  2. {
  3. for ( int j=0; j<cols; j++ )
  4. {
  5. image.at<uchar>(i, j)= 0; // also can be: image.at<uchar>( cv::Point(j, i) ) = 0;
  6. /*
  7. if color one:
  8. image.at<uchar>( i, j*3 + 0 ) = 0;
  9. image.at<uchar>( i, j*3 + 1 ) = 0;
  10. image.at<uchar>( i, j*3 + 2 ) = 0;
  11. */
  12. }
  13. }

三种方法速度上有一定差异,感兴趣的可以自己测试一下~

2. Mat_

Mat_继承于Mat,相比于Mat没有增加任何数据段,但增加了一些更加便捷的功能,表达上也更加精简。

2.1 创建与初始化
  1. /* first method */
  2. cv::Mat_<double> myMat_ = ( cv::Mat_<double>(3, 3) <<
  3. 1.0, 2.0, 3.0,
  4. 4.0, 5.0, 6.0,
  5. 7.0, 8.0, 9.0);
  6. cv::Mat_<double> myMat_ = cv::Mat_<double>::zeros(3, 3); // others: eyes, diag, ones
  7. /* second method */
  8. cv::Mat_<double> myMat_(3, 1, 0.0);
  9. // -> cv::Mat image(3, 1, CV_64FC1, cv::Scalar(0.0));
  10. // create a 100x100 color image and fill it with green(in RGB space)
  11. cv::Mat_<cv::Vec3b> image( 100, 100, cv::Vec3b(0, 255, 0) );
  12. /* third method */
  13. cv::Mat myMat( 100, 100, CV_64F1, cv::Scalar(0) );
  14. cv::Mat_<double>& myMat_ = (cv::Mat_<double>&)myMat;

注意:

  1. 使用( cv::Mat_<double>(row, col) << ...) )形式创建并初始化的时候,最外面的( )不能省略;

  2. 使用第二种通过Mat指针或者引用的方式创建与初始化Mat_时,两者的数据类型一定要一致,不然程序虽然编译没问题,但运行就会BUG~

2.2 数据访问
  1. /*
  2. Note that Mat::at<_Tp>(int y, int x) and
  3. Mat_<_Tp>::operator ()(int y, int x) do
  4. absolutely the same and run at the same speed
  5. */
  6. int rows = myMat_.rows;
  7. int cols = myMat_.cols;
  8. /* first method */
  9. for ( int i=0; i<rows; i++ )
  10. {
  11. for ( int j=0; j<cols; j++ )
  12. {
  13. std::cout << myMat_(i, j) << std::endl;
  14. }
  15. }
  16. // for multi-channel images/matrices:
  17. for ( int i = 0; i < rows; i++ )
  18. {
  19. for( int j = 0; j < cols; j++ )
  20. {
  21. // scramble the 2nd (red) channel of each pixel
  22. image(i, j)[2] ^= (uchar)(i ^ j); // ^: exclusive or operation
  23. }
  24. }
  25. /* second method */
  26. int matCount = rows * cols;
  27. for ( int idx=0; idx < matCount; idx++ )
  28. {
  29. std::cout << myMat_(idx) <<std::endl;
  30. }

3. Matx

Matx主要用于大小、数据类型(浮点型)已知的小矩阵(最大不超过6x6),包括:Matx12f, ... , Matx66fMatx12d, ... , Matx66d

创建与初始化都很简单,不做过多介绍:

  1. cv::Matx31d myMatx( 1.0, 2.0, 3.0 );
  2. cv::Matx33d myMatx2 = cv::Matx33d( 0.0, 0.0, 0.0 );

最后,关于Mat的运算(加,减,乘,求逆,转置,均值,标准差…)三种类型基本差异不大,在文档中也容易找到~

参考文档:http://www.docs.opencv.org/modules/core/doc/basic_structures.html?highlight=mat

Opencv Mat的三种常用类型简介的更多相关文章

  1. opencv中Mat与IplImage,CVMat类型之间转换

    opencv中对图像的处理是最基本的操作,一般的图像类型为IplImage类型,但是当我们对图像进行处理的时候,多数都是对像素矩阵进行处理,所以这三个类型之间的转换会对我们的工作带来便利. Mat类型 ...

  2. C++ Opencv Mat类型使用的几个注意事项及自写函数实现Laplace图像锐化

    为了提升自己对Opencv中Mat数据类型的熟悉和掌握程度,自己尝试着写了一下Laplace图像锐化函数,一路坎坷,踩坑不断.现将代码分享如下: #include <opencv2/opencv ...

  3. OpenCv Mat操作总结

    Author:: Maddock Date: 2015-03-23 16:33:49 转载请注明出处:http://blog.csdn.net/adong76/article/details/4053 ...

  4. OpenCV——Mat,IplImage,CvMat类型转换

    Mat,cvMat和IplImage这三种类型都可以代表和显示图像,三者区别如下 Mat类型侧重于计算,数学性较高,openCV对Mat类型的计算也进行了优化. 而CvMat和IplImage类型更侧 ...

  5. OpenCV Mat数据类型及位数总结(转载)

    OpenCV Mat数据类型及位数总结(转载) 前言 opencv中很多数据结构为了达到內存使用的最优化,通常都会用它最小上限的空间来分配变量,有的数据结构也会因为图像文件格式的关系而给予适当的变量, ...

  6. Qt QImage与OpenCV Mat转换

    本系列文章由 @yhl_leo 出品,转载请注明出处. 文章链接: http://blog.csdn.net/yhl_leo/article/details/51029382 应一个朋友的要求,整理总 ...

  7. <学习opencv>图像和大型阵列类型

    OPenCV /*=========================================================================*/ // 图像和大型阵列类型 /* ...

  8. Matlab to OpenCV Mat

    convert Matlab matrix to OpenCV Mat. Support CV_32FC3 only currently. The Code int matlab2opencv(cv: ...

  9. python——动态类型简介

    动态类型简介 类型属于对象,而不是变量 每一个对象都有两个标准的头部信息:类型标志符和引用计数器. 对象的垃圾收集,就是通过引用计数器实现的.可以在脚本中任意使用对象而不需要考虑释放内存空间. 循环饮 ...

随机推荐

  1. 【原创】Apache和Tomcat实现动静分离

    集群中每个节点都启用了页面静态化功能,所以,为了防止单个节点刷新造成找不到页面问题,将每个节点刷新的页面都放入apache虚拟目录下,由apache统一来处理.静态页面由apache处理,动态页面仍然 ...

  2. UVa 12545 Bits Equalizer【贪心】

    题意:给出两个等长的字符串,0可以变成1,?可以变成0和1,可以任意交换s中任意两个字符的位置,问从s变成t至少需要多少次操作 先可以画个草图 发现需要考虑的就是 1---0 0---1 ?---0 ...

  3. php——get与post方法(转)

    file_get_contents版本: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 <?php /**  * 发送p ...

  4. webkit Safari的样式库

    1,webkit Box模型 CSS定义:-webkit-border-bottom-left-radius: radius; CSS定义:-webkit-border-top-left-radius ...

  5. 关于Python的装饰器

    false 7.8 磅 0 2 false false false EN-US ZH-CN X-NONE /* Style Definitions */ table.MsoNormalTable {m ...

  6. 微信小程序 刷新页面

    一 , 当前页面刷新 第一种方式: //pages 获取到当前页码数 然后执行当前页的onLoad const pages = getCurrentPages() ] perpage.onLoad() ...

  7. POJ-1113 Wall 计算几何 求凸包

    题目链接:https://cn.vjudge.net/problem/POJ-1113 题意 给一些点,求一个能够包围所有点且每个点到边界的距离不下于L的周长最小图形的周长 思路 求得凸包的周长,再加 ...

  8. jquery复制到剪贴板

    <!DOCTYPE html> <html> <head> <title>ZeroClipboard Test</title> <me ...

  9. window下搭建Python3.7+selenium3.1.1+pycharm环境

    1.安装Python3.7 1.1  下载 Python并安装 Python3.5 (勾选上 Add Python3.7 to PATH) 点击 Install Now,安装完成后将python路径加 ...

  10. WPF 一个空的 WPF 程序有多少个窗口

    原文:WPF 一个空的 WPF 程序有多少个窗口 好多小伙伴说 WPF 的程序有五个窗口,但是我尝试使用了 EnumThreadWindows 去获取的时候居然拿到了 10 多个窗口 在 WPF 内部 ...