图像在OpenCV中都是通过Mat类来存储的,Mat可以用来表示N维矩阵,当然用的最多的还是二维矩阵。

      Mat类有两部分组成:第一部分是头信息,这些信息主要用来描述矩阵,比如矩阵维数ndims,rows,cols(这两个成员变量主要用于二维矩阵,用来表示行数和列数),size,sizes, type,step等等;第二部分是data信息,这是一个指针,指向Mat中存储的数据。

通过下面的代码,我们创建一个二维矩阵,并打印出矩阵:

//创建一个5*5的2维矩阵,数据类型为8bit的无符号数,数据为3个通道,初始值都为(0,0,255)

cv::Mat M(5,5, CV_8UC3, cv::Scalar(0,0,255));

cout << "M = " << endl << " " << M << endl << endl;

 

      这个矩阵的头信息和数据如下图所示:

      step表示每一行占据的字节数目,包括padding数据,其中每行中的padding数据有点吓到我了,我们只有15个uchar而已,没想到step竟然这么大,而且每次运行程序还是变化的,真正的数据大小是 M.cols*M.elemSize() = 15,我们可以通过函数M.isContinuous()知道当前矩阵是否有padding数据。

     没有padding数据时候,我们可以把矩阵的data当一维数据处理,数据长度就是rows*cols*elemSize()。

下面我看看如何访问矩阵中的元素,并进行操作:

1. 直接访问data,简单快速。

for(i=0; i< M.rows; i++)

{

    for(j=0; j<M.cols*M.elemSize(); j++)

   {

       printf ("%d ", M.data[i*M.cols*M.elemSize() + j]);

   }

   printf("\n");

}

或者用下面的代码:

uchar* p;

for( i = 0; i < M.rows; ++i)

{

    //得到第i行的指针,等价于 p = M.data + i*M.step

    p = M.ptr<uchar>(i);

    for ( j = 0; j < M.cols; ++j)

    {

      printf (" %d %d %d",p[j*3], p[j*3+1],p[j*3+2]);

     }

    printf("\n");

    或者我们也可以用at的方式得到数组元素,M.at<cv::Vec3b>(i,j)[2]得到元素中的第2个分量,如果M.at<uchar>(i,j),则只能取到元素的第一个分量。

//用at的方式访问矩阵元素
for(i=0; i< M.rows; i++)
    {
    for(j=0; j<M.cols; j++)
        {
        printf ("%d %d %d ", M.at<cv::Vec3b>(i,j)[0],M.at<cv::Vec3b>(i,j)[1], M.at<cv::Vec3b>(i,j)[2]);
        }
    printf("\n");
    }

}

2. 用c++迭代器的方式访问。

cv::MatIterator_<cv::Vec3b> it, end;

for( it = M.begin<cv::Vec3b>(), end = M.end<cv::Vec3b>(); it != end; ++it)

{

    printf("%d %d %d\n",(*it)[0], (*it)[1], (*it)[2]);

}

程序源码:工程FirstOpenCV2。

 

OpenCV学习(4) Mat的基本操作(1)的更多相关文章

  1. OpenCV学习(5) Mat的基本操作(2)

          本章我们学习一下Mat中的常用操作,因为在后面其它的教程中,我们经常要对图像进行各种处理,也要使用这些操作. 一. Mat的复制,就是从一个矩阵A,生成相关的另一个矩阵B. (1)使用赋值 ...

  2. OpenCV学习:Mat结构中的数据共享机制

    使用Mat类,内存管理变得简单,不再像使用IplImage那样需要自己申请和释放内存. Mat是一个类,由两个数据部分组成:矩阵头(包含矩阵尺寸,存储方法,存储地址等信息)和一个指向存储所有像素值的矩 ...

  3. OpenCV学习笔记——Mat类型数据存储

    CV_[The number of bits per item][Signed or Unsigned][Type Prefix]C[The channel number] 比如 CV_8UC3 表示 ...

  4. OpenCV学习(3)--Mat矩阵的操作

    CvMat的矩阵结构 typedef struct CvMat { //矩阵中元素的类型 int type; //行数据长度 int step; /* for internal use only */ ...

  5. opencv学习笔记(一)IplImage, CvMat, Mat 的关系

    opencv学习笔记(一)IplImage, CvMat, Mat 的关系 opencv中常见的与图像操作有关的数据容器有Mat,cvMat和IplImage,这三种类型都可以代表和显示图像,但是,M ...

  6. [OpenCV学习笔记2][Mat数据类型和操作]

    [Mat数据类型和基本操作] ®.运行环境:Linux(RedHat+OpenCV3.0) 1.Mat的作用: Mat类用于表示一个多维的单通道或者多通道的稠密数组.能够用来保存实数或复数的向量.矩阵 ...

  7. OpenCV学习C++接口 Mat像素遍历详解

    OpenCV学习C++接口 Mat像素遍历详解

  8. opencv学习笔记(六)直方图比较图片相似度

    opencv学习笔记(六)直方图比较图片相似度 opencv提供了API来比较图片的相似程度,使我们很简单的就能对2个图片进行比较,这就是直方图的比较,直方图英文是histogram, 原理就是就是将 ...

  9. opencv学习笔记(五)镜像对称

    opencv学习笔记(五)镜像对称 设图像的宽度为width,长度为height.(x,y)为变换后的坐标,(x0,y0)为原图像的坐标. 水平镜像变换: 代码实现: #include <ios ...

随机推荐

  1. 浅谈ES5和ES6继承和区别

    最近想在重新学下ES6,所以就把自己学到的,记录下加强下自己的理解 首先先简单的聊下ES5和ES6中的继承 1.在es5中的继承: function parent(a,b){ this a = a; ...

  2. MQTT协议以及库函数说明

    内容简介:之前我们写了一篇ESP8266AT指令的说明文档,在客户端连接上服务器之后,接下来便是网络通信.为此我们又写了这一片MQTT协议的说明文档,更加深层次的讲述了通信的原理.此文档只是我们在调试 ...

  3. jquery 美化弹出提示 漂亮的Dialog 对话框

    三个不同的效果,分别是普通的警告,确认/取消,带一个输入框 本例用了jquery.alertify.js,请到演示页面查看 css文件也请到演示页面查看 JavaScript Code <scr ...

  4. JS 数组求 最大值、最小值、平均值以及求和方法

    function arrMaxNum2(arr) { return Math.max.apply(null, arr); } function arrMinNum2(arr) { return Mat ...

  5. POJ3255 Roadblocks [Dijkstra,次短路]

    题目传送门 Roadblocks Description Bessie has moved to a small farm and sometimes enjoys returning to visi ...

  6. Docker运行oracle12c注意事项

    title: docker运行oracle12c注意事项 date: 2019-03-27 13:42:34 categories: 数据库 author: mrzhou tags: docker 数 ...

  7. hiho1393二分图多重匹配

    题目链接:[http://hihocoder.com/problemset/problem/1393] 题意:中文题意. 题解:二分图的多重匹配.主要是建图然后跑一个最带流,再判断一下就可以了. 建图 ...

  8. 「TJOI 2018」教科书般的亵渎

    「TJOI 2018」教科书般的亵渎 题目描述 小豆喜欢玩游戏,现在他在玩一个游戏遇到这样的场面,每个怪的血量为 \(a_i\) ,且每个怪物血量均不相同, 小豆手里有无限张"亵渎" ...

  9. 【随机化】【并查集】Gym - 100851J - Jump

    题意:交互题,有一个长度为n(偶数)的二进制串,你需要猜不超过n+500次猜到它.如果你猜的串与原串相同的位数为n,那么会返回n,如果为n/2,那么会返回n/2,否则都会返回零. 先random,直到 ...

  10. Java虚拟机类加载机制--概述

    一.虚拟机类概加载概述 虚拟机将描述类的Class文件加载到内存,并对数据进行校验,转换解析和初始化,最终形成可以直接被虚拟机使用的Java类型 Java语言支持动态加载和动态连接. 二.虚拟机加载类 ...