OpenCV-Mat结构详解

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

OpenCV-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;
上⾯博⽂参考:
写到这⾥,我也只了解了⾏,列,通道等概念,但是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;。

相关文档
最新文档