前面博客中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. 两分支部署Hexo

    最近把原本部署在GitHub上的hexo同时部署到码云上,速度快到飞起. 可做对比,我的GitHub Pages像乌龟一样慢吞吞,我的Gitee Pages像兔子一样敏捷. 使用hexo,如果换了电脑 ...

  2. 全网小说免费阅读下载APP

    先说主题:今天分享一个全网小说免费阅读下载APP.这篇文章是凌晨2点钟写的,原因呢可能有两点: 半夜无眠,一时兴起就想分享点有用的东西给大家,就问你感动不?其实吧,可能是晚上喝了点儿浓茶导致的无眠,所 ...

  3. VSCode(主进程)

    Overview(总览) SETUP(设定) Overview(总览) Linux(略) macOS(略) Windows 使用WSL,您可以在Windows上安装和运行Linux发行版.这使您能够在 ...

  4. Lucene使用IKAnalyzer分词

    1.分析器    所有分析器最终继承的类都是Analyzer        1.1 默认标准分析器:StandardAnalyzer            在我们创建索引的时候,我们使用到了Index ...

  5. Python 安装 virturalenv 虚拟环境

    返回目录 本篇索引 一.概述 二.Linux下安装Python虚拟环境 三.Windows下安装Python虚拟环境 一.概述 有时候会在一台主机上安装多个不同的Python版本,用以运行不同时期开发 ...

  6. Node.js_1.1

    Node.js简介 Node.js是一个能够在服务器端运行JavaScript的开源代码.跨平台JavaScript运行环境 Node采用Google开发的V8引擎运行js代码,使用事件驱动.非阻塞和 ...

  7. codechef Future of draughts

    难度 super-hard 题意 官方中文题意 做法 定义1:\(G\)为邻接矩阵,\(I\)为单位矩阵 定义2:\(H\)为转移矩阵,可以不动,即\(H=G+I\) 定义3:\(e_i(x_1,.. ...

  8. PAT (Advanced Level) Practice 1008 Elevator (20 分) (模拟)

    The highest building in our city has only one elevator. A request list is made up with N positive nu ...

  9. php 获取视频时长

    利用ffmpeg只能获取到本地视频的信息. function video_time($file) { ob_start(); passthru(sprintf(FFMPEG_PATH, $file)) ...

  10. BZOJ 3143 游走

    Description 一个无向连通图,顶点从1编号到N,边从1编号到M. 小Z在该图上进行随机游走,初始时小Z在1号顶点,每一步小Z以相等的概率随机选 择当前顶点的某条边,沿着这条边走到下一个顶点, ...