前面博客中Mat函数谈到一些理解,但是理解的比较浅显,下面谈谈通道,行列等意义;

Mat的常见属性

opencv中type类型·

CV_<bit_depth>(S|U|F)C<number_of_channels>
1--bit_depth---比特数---代表8bite,16bites,32bites,64bites---举个例子吧--比如说,
如果你现在创建了一个存储--灰度图片的Mat对象,这个图像的大小为宽100,高100,那么,现在这张
灰度图片中有10000个像素点,它每一个像素点在内存空间所占的空间大小是8bite,8位--所以它对应的就是CV_8

depth:深度,即每一个像素的位数(bits),在opencv的Mat.depth()中得到的是一个 0 – 6 的数字,分别代表不同的位数:enum { CV_8U=0, CV_8S=1, CV_16U=2, CV_16S=3, CV_32S=4, CV_32F=5, CV_64F=6 }; 可见 0和1都代表8位, 2和3都代表16位,4和5代表32位,6代表64位;

2--S|U|F--

S--代表---signed int---有符号整形
U--代表--unsigned int--无符号整形
F--代表--float---------单精度浮点型

3--C<number_of_channels>----代表---一张图片的通道数,比如:

1--灰度图片--grayImg---是--单通道图像
2--RGB彩色图像---------是--3通道图像
   3--带Alph通道的RGB图像--是--4通道图像

如:CV_8UC1---则可以创建----8位无符号的单通道---灰度图片------grayImg
       CV_8UC3---则可以创建----8位无符号的三通道---RGB彩色图像---colorImg

channels:通道,矩阵中的每一个矩阵元素拥有的值的个数,比如说 3 * 4 矩阵中一共 12 个元素,如果每个元素有三个值,那么就说这个矩阵是 3 通道的,即 channels = 3。常见的是一张彩色图片有红、绿、蓝三个通道。

上面是一个 3 X 4 的矩阵,假设其数据类型为 CV_8U,也就是单通道的 uchar 类型

CV_8U 得到 M.depth() == 0, M.channels() == 1
这是一个二维矩阵,那么维度为 2 (M.dims == 2);
M.rows == 3; M.cols == 4;

step:是一个数组,定义了矩阵的布局,具体见上面图片分析,另外注意 step1 (step / elemSize1),M.step[m-1] 总是等于 elemSize,M.step1(m-1)总是等于 channels;

因为是二维矩阵,那么 step 数组只有两个值, step[0] 和 step[1] 分别代表一行的数据大小和一个元素的数据大小,则 M.step[0] == 4, M.step[1] == 1;
M.step1(0) == M.cols = 4; M.step1(1) == 1;

elemSize : 矩阵中每一个元素的数据大小,如果Mat中的数据的数据类型是 CV_8U 那么 elemSize = 1,CV_8UC3 那么 elemSize = 3,

CV_16UC2那么 elemSize = 4;

记住另外有个 elemSize1 表示的是矩阵中数据类型的大小,即 elemSize / channels 的大小

sizeof(uchar) = 1,那么每一个数据元素大小为 1 (M.elemSize() == 1, M.elemSize1() == 1);
CV_8U 得到 M.depth() == 0, M.channels() == 1;

假设上面的矩阵数据类型是 CV_8UC3,也就是三通道
M.dims == 2; M.channels() == 3;M.depth() == 0;
M.elemSize() == 3 (每一个元素包含3个uchar值) M.elemSize1() == 1 (elemSize / channels)
M.step[0] == M.cols * M.elemSize() == 12, M.step[1] == M.channels() * M.elemSize1() == M.elemSize() == 3;
M.step(0) == M.cols * M.channels() == 12 ; M.step(1) == M.channels() == 3;

上面博文参考:opencv数据结构-MAT结构详解

写到这里,我也只了解了行,列,通道等概念,但是step,step(0),elemSize1,elemSize()我感到很困惑,看看下面的理解:

上图中: int matSize[] = {5,8,10};//每一维元素的个数:8:行,10:列

Mat mat1(3,matSize, CV_16UC3, Scalar::all(0);

对于mat1,3通道,一个像素点在内存空间大小是16bit;每一个像素的位数(bits)是2(深度);

三维矩阵,一共有三维,我们分别类比为

面:每个二维矩阵,表示第1维的元素

线:矩阵的每一行,表示第2维的元素

点:矩阵中每行的每个元素,表示第3维的元素

那么这样子就可以解释清楚每一维元素的含义了。

以step[i]为例

step[0]:面的大小,第1维的元素的大小,也就是二维矩阵的大小,一个二维矩阵有8行,所以step[0]=step[1]*8=480

step[1]:线的大小,第2维的元素的大小,也就是二维矩阵每一行的大小,由于每个元素大小为6,每行有10个元素,所以step[1]=10*6=60

step[2]:点的大小,第3维的元素的大小,这里矩阵的每个元素类型为CV_16UC3,所以step[2]=2*3=6个字节

这里注意:

1.step的大小是字节

2.注意下标与维数的对应关系:下标2对应点,1对应线,0对应面

3.矩阵有几维,step[]数组就有几个元素,如3维,则有3个元素,step[0],step[1],step[2].分别对应面,线,点
只要记住,最后一个总是表示点,然后依次向前为线,面…

4.第2,3 点 ,对于size和step1()也一样。

step1(i):每一维元素的通道数

step[i]:每一维元素的大小,单位字节;(包含所有通道)

size[i]:每一维元素的个数

elemSize():每个元素大小,单位字节

elemSize1():每个通道大小,单位字节

elemSize  表示每个元素的大小(单位字节),每个元素可能有多个通道,示例中,每个元素有三个通道,而每个通道类型为CV_16U,算3个通道的总数, 2*3=6

elemSize1 每个通道的大小(单位字节),CV_16=2字节

step1[i] = step.p[i]/elemSize1();

step1[0] = step[0]/elemSize1 = 240 bytes

step1[1] = step[1]/elemSize1 = 30 bytes

step1[2] = step[2]/elemSize1 = 3 bytes

代码如下:

#include"sift.h"
#include<fstream>
#include<iostream>
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include <opencv2/core/core.hpp>
#include <stdio.h>
#include <stdlib.h> int main(int argc, char **argv)
{ //////////////////Demo1(3维矩阵)///////////////////////////////////////////
printf("//////////////////////Demo1(3维矩阵)////////////////////////\n");
//最后面的两个数:(行,列),确定了一个面
//是一个依次降维的过程
//8,10组成了面,5个面,组成了立方体
int matSize[] = { 5,8,10 };//每一维元素的个数:8:行,10:列
Mat mat1(3, matSize, CV_16UC3, Scalar::all(0)); //求step[i]的大小:每一维元素的大小(单位字节)
printf("\n///////step[i]的大小//////////\n");
printf("step[0]:%d\n", mat1.step[0]);//480=8*60:面的大小(第一维)
printf("step[1]:%d\n", mat1.step[1]);//60=6*10:线的大小(第二维)
printf("step[2]:%d\n", mat1.step[2]);//6=2*3:点的大小(第三维) //求size[i]:每一维元素的个数
printf("\n///////size[i]的大小///////\n");
printf("size[0]:%d\n", mat1.size[0]);//5:面
printf("size[1]:%d\n", mat1.size[1]);//8:线
printf("size[2]:%d\n", mat1.size[2]);//10:点 //求step1(i):每一维元素的通道数
printf("\n///////step1(i)的大小///////\n");
printf("step1(0):%d\n", mat1.step1(0));//240:面
printf("step1(1):%d\n", mat1.step1(1));//30:线
printf("step1(2):%d\n", mat1.step1(2));//3:点 //求elemSize:每个元素的大小(单位字节)
printf("\n///////elemSize的大小///////\n");
printf("elemSize:%d\n", mat1.elemSize());//6:每个元素的大小 //求elemSize1:每个通道的大小(单位字节)
printf("\n///////elemSize1的大小///////\n");
printf("elemSize1:%d\n", mat1.elemSize1());//2:每个通道的大小
system("pause");
return 0;
}

  

改成.jpg图片

/求step[i]的大小:每一维元素的大小(单位字节)
//step[i]
printf("\n///////step[i]的大小///////\n");
printf("step[0]:%d\n", mat2.step[0]);//1200=3*400:线
printf("step[1]:%d\n", mat2.step[1]);//3=1*3:点 //size[i]
printf("\n///////size[i]的大小///////\n");
printf("size[0]:%d\n", mat2.size[0]);//250:线
printf("size[1]:%d\n", mat2.size[1]);//400:点 //step1(i)
printf("\n///////step1(i)的大小///////\n");
printf("step1(0):%d\n", mat2.step1(0));//1200:第一维的通道数
printf("step1(1):%d\n", mat2.step1(1));//3:第二维的通道数 //elemSize
printf("\n///////elemSize的大小///////\n");
printf("elemSize:%d\n", mat2.elemSize());//3:每个元素的大小 //elemSize1
printf("\n///////elemSize1的大小///////\n");
printf("elemSize1:%d\n", mat2.elemSize1());//1:每个通道的大小,也就是单通道数据类型 system("pause");
return 0;

  

OpenCV-Mat结构详解的更多相关文章

  1. [OpenCV]Mat类详解

    http://blog.csdn.net/yang_xian521/article/details/7107786 Preface Mat:Matrix Mat类可以被看做是opencv中C++版本的 ...

  2. opencv数据结构-MAT结构详解

    1.定义 OpenCV中的C结构体有 CvMat 和 CvMatND,但后续的应用中指出 CvMat 和 CvMatND 弃用了,在C++封装中用 Mat 代替,另外旧版还有一个 IplImage,同 ...

  3. OpenCV参考手册之Mat类详解

    OpenCV参考手册之Mat类详解(一) OpenCV参考手册之Mat类详解(二) OpenCV参考手册之Mat类详解(三)

  4. Mat的详解

    [转]OpenCV中Mat的详解 每次碰到Mat都得反复查具体的用法,网上的基础讲解不多,难得看到一篇,赶快转来收藏~ 原文地址:http://www.opencvchina.com/thread-1 ...

  5. BS模式的模型结构详解

    编号:1004时间:2016年4月12日16:59:17功能:BS模式的模型结构详解 URL:http://blog.csdn.net/icerock2000/article/details/4000 ...

  6. Linux下的文件目录结构详解

    Linux下的文件目录结构详解 / Linux文件系统的上层根目录 /bin 存放用户可执行的程序 /boot 操作系统启动时所需要的文件 /dev 接口设备文件目录,例如:had表示硬盘 /etc ...

  7. PHP扩展代码结构详解

    PHP扩展代码结构详解: 这个是继:使用ext_skel和phpize构建php5扩展  内容 (拆分出来) Zend_API:深入_PHP_内核:http://cn2.php.net/manual/ ...

  8. Android系统目录结构详解

    Android系统基于linux内核.JAVA应用,算是一个小巧精致的系统.虽是开源,但不像Linux一般庞大,娇小可亲,于是国内厂商纷纷开发出自己基于Android的操作系统.在此呼吁各大厂商眼光放 ...

  9. Linux文件系统的目录结构详解

    Linux文件系统的目录结构详解   一.前 言 文章对Linux下所有目录一一说明,对比较重要的目录加以重点解说,以帮助初学者熟练掌握Linux的目录结构. 二.目 录 1.什么是文件系统 2.文件 ...

随机推荐

  1. Linux下VIM编译器的使用以及shell编程基础

    VIM编译器的安装与使用 vim编辑器安装 在CentOS中,执行:yum -y install vim 普通模式 h: 左移一个字符 j: 下移一行 k: 上移一行 l: 右移一个字符 PageDo ...

  2. asp.net mvc 使用AuthorizeAttribute做授权验证

    授权验证,比如登陆验证 1.自定义属性继承AuthorizeAttribute 2.重写OnAuthorization方法 3.通过AllowAnonymousAttribute特性处理无需授权的Ac ...

  3. ajax 携带参数传递 页面 查找

    不从新定义只能传过来数字  ,不能穿字符串 完整的ajax 获取参数跳转页面

  4. 洛谷 UVA11388 GCD LCM

    UVA11388 GCD LCM Description of the title PDF The GCD of two positive integers is the largest intege ...

  5. egg 提交数据 防csrf 攻击 配置

    await ctx.render('from',{csrf:this.ctx.csrf}); 或者 使用中间件 ctx.state.csrf = ctx.csrf;

  6. disabled属性对form表单提交的影响

    在form表单里,如果对input加入disabled="disabled"或disabled="true"等属性,form表单提交的时候,就不会传值到后台. ...

  7. 克里金插值 调用matlab工具箱

    克里金插值 克里金插值是依据协方差函数对随机过程或随机场进行空间建模和插值的回归算法. 克里金插值法的公式为: 式中为待插入的各点的重金属污染值,为已知点的重金属污染值,为每个点的权重值. 用BLUP ...

  8. 关于GET和POST请求的区别,最通俗全面的回答

    GET和POST是HTTP请求的两种基本方法,要说它们的区别,接触过WEB开发的人都能说出一二. 最直观的区别就是GET把参数包含在URL中,POST通过request body传递参数. 你可能自己 ...

  9. JS实现轮播图特效(带二级导航)

    按照国际惯例先放效果图 index.html <!DOCTYPE html> <html lang="en"> <head> <meta ...

  10. SQL Server 2012 下载和安装详细教程

    https://blog.csdn.net/qq_37591637/article/details/93102794 选择图片中的三个,然后点击下载 ,文件内存很大 下载以后,如图所示,双击.exe程 ...