前面博客中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. postgresql开篇

    postgresql 作为官方号称的最先进的开源数据库,从今天(2020-1-19)起开始系统的学习一下,记录自己学习的点点滴滴.

  2. PostgreSQL内核学习笔记四(SQL引擎)

    PostgreSQL实现了SQL Standard2011的大部分内容,SQL处理是数据库中非常复杂的一部分内容. 本文简要介绍了SQL处理的相关内容. 简要介绍 SQL文的处理分为以下几个部分: P ...

  3. 令人抓狂的redis和rediscluster Python驱动包的安装

    本文环境:centos 7,Python3编译安装成功,包括pip3,然后需要安装redis相关的Python3驱动包,本的redis指redis包而非redis数据库,rediscluster类似. ...

  4. wordpress<=4.6版本任意命令执行漏洞

    漏洞简述 当WordPress 使用 PHPMailer 组件向用户发送邮件.攻击者在找回密码时会使用PHPmailer发送重置密码的邮件,利用substr(字符串截取函数).$run(系统调用函数) ...

  5. vulnhub靶机之DC6实战(wordpress+nmap提权)

    0x00环境 dc6靶机下载地址:https://download.vulnhub.com/dc/DC-6.zip dc6以nat模式在vmware上打开 kali2019以nat模式启动,ip地址为 ...

  6. C# Socket的方式发送中文,接收方收到乱码

    场景: 使用 Socket的方式向下位机发送中文信息,下位机收到的中文是乱码 原因: 了解到的原因是上位机与下位机的发送与接收的编码与解码方式不一致 比如上位机采用 Encoding.UTF8.Get ...

  7. jQuery - lable 取值、赋值

    取值 var val = $("#breakfastMonday").html(); 赋值 $("#breakfastMonday").html("v ...

  8. JN_0011:改变PPT的页面尺寸,并导出图片

    1,改变尺寸 设计 --  幻灯片大小 --  自定义大小 2,导出图片 另存为 JPG 图片

  9. Codeforces Round #612 (Div. 2) (A-D)

    直 接看所有A后面连续P的个数最大值 #include<cstring> #include<cstdio> #include<set> #include<io ...

  10. 安装Elasticsearch到Linux(源码)

    运行环境 系统版本:CentOS Linux release 7.3.1611 (Core) 软件版本:Elasticsearch-7.1.0 硬件要求:最低2核4GB 安装过程 1.源码安装JDK ...