1、mat类的介绍
什么是mat类,以及mat类能存储什么数据?
opencv里用于存储矩阵数据的类型,与c++中的int double等数据类型一样,例如:
133 141 147 153 171
128 152 133 132 154
152 187 136 127 145
也就是说opencv存储时是以一个矩阵类型的数据将图像的每个像素存储的!
自己理解:其实mat类就是一个保存图像像素值的一个数据类型,他有自己的数据的结构。你包括抠图等等其实也就是截取这个mat内部对应的像素点的信息,然后构成一个新的mat对象,也就是一个新的图像了。
mat类由矩阵头和数据两部分组成:
矩阵头:中包含了尺寸(640*480)、行数、列数(与尺寸是对应的)、数据类型、(这个mat类里存的是int 还是 double类型的数据)、通道数(2x3x4的图像)、引用次数等信息等(例如mat a mat b 两个数据对象公用的是一个mat数据图像 img,那么当删除img时他们两个引用的就是空的。还可以避免我在删除 a的img时 由于b还在引用,却给删了。)
数据部分:就是数据了。
2、mat能存储什么样的数据类型呢?
cv::mat_<_tp> //自定义的类型
cv::mat_<_double> //
cv::mat_<_float> //
cv::mat_<_uchar> //
cv::mat_<_unsigned char> //
3、mat类如何创建:三种常见的创建方式
第一种:
cv::mat::mat(int rows,/*构造矩阵的行数*/
int cols,/*矩阵的列数*/
int type /*矩阵中存储的数据类型此处除了cv_8uci cv_64fc4等从1到4通道外,还 提供了更多通道的参数,通过cv_8uc(n)中的n来构建多通道矩阵,其中 最大可以取到512)
第二种:使用size结构
cv::mat::mat(size size,/*通过size(cols,rows)进行赋值*/
type:与前面一致)
第三种:利用已有的mat类创建新的mat类。
cv::mat::mat(const mat& m, /*已经构建完成的mat类矩阵数据*/
const range & rowrange,/*在已有的矩阵中需要截取的行数范围,是一个range变量,例如
从第2行到第5行可以标识为range(2,5)*/
const range & colrange=range::all() /*在已有的矩阵中需要截取的列数范围,是一个
range变量,例如 从第2列到第5列可以标识为range(2,5)
其中截取的mat类的数据是不包括5的 其实以0为起始基数算 的话只截取了3列和第4列。*/)
4、mat类如何赋值
第一种创建时赋值:可以在创建时直接在后边加上一个参数
cv::mat::mat(int rows,
int cols,
int type,
const scalar& s /*这个参数是给矩阵中每个像素赋值的参数变量,
mat f(3,3,cv_8u,scalar(1))
例如比如你的mat是一个三通道的就可以在这个参数中给3个数 scalar (0,0,255),四通道的 就给4个数 scalar(1,1,1,1) scalar可以给任意几个数
如果你是三通道的,scalar给出了4个数,那最后的那个就被舍弃不用)
还有一种可以使用mat类中的类方法进行赋值:
eye:单位矩阵
diag:对角矩阵
ones:元素全为1的矩阵
zeros:元素全为0的矩阵
使用方法:a=mat::eye(行,列,type类型);
第三种赋值方式就是枚举法赋值:
cv::mat a=( cv::mat_<int>(3,3) << 1,2,3,4,5,6,7,8,9 );
声明一个mat类,并表明里边的数据类型和它是几行几列的,然后后边把具体的数据存入这
个3乘3的mat里面
cv::mat b=( cv::mat_<double>(2,3) << 1.0,2.1,3.2,4.0,5.1,6.2 );
这里注意尖括号中给出的是int 或者 double 这是数据类型。而不是给cv_8u。
因为给成int 或double 是跟你计算机中的数据对应的。
5、创建与赋值的代码实际讲解:
#include<iostream>
#include<opencv2/opencv.hpp>//使用这个大的头文件可以将所有的opencv的头文件全都包含进去
using namespace std;
using namespace cv;
int main()
{
system("color f0");//将c++黑色的界面调节成白色
//mat ooo(,);//创建一个mat值时,vs会给出提示,有9种创建方式。
mat a(3,3,cv_8uc1);//mat创建方式的第一种行、列、数据类型。定义了一个单通道的mat
mat b(size(4,4),cv_8uc1);//mat第二种创建方式,使用size创建一个mat变量。
mat c0(5,5,cv_8uc1,scalar(4,5,6));//创建一个1通道的mat值,赋值时却是赋值3个通道
mat c1(5,5,cv_8uc2,scalar(4,5,6));//创建一个2通道的mat值,赋值时却是赋值3个通道
mat c2(5, 5, cv_8uc3, scalar(4,5,6));//创建一个3通道的mat值,赋值时却是赋值3个通道
mat d = (cv::mat_<int>(1, 5) << 1, 2, 3, 4, 5);//创建一个1乘5这样的一个mat,存储的是
//int 类型。并进行枚举法赋值
mat e = mat::diag(d);//使用一个已知的mat矩阵,创建一个角点矩阵.
//创建角点矩阵它需要你输入的原有矩阵必须是
//一个1乘以n的矩阵原型。然后它把已有矩阵变成一个对角矩阵
mat f = mat(e, range(2, 4)/*抠第二行和第三行下的*/, range(3, 5)/*抠上述行中的第3列和
第四列*/);//抠图形式,在已有的mat类中抠出一个mat类
cout << c0 << endl;
cout << c1 << endl;
cout << c2 << endl;
cout << d << endl;
cout << e << endl;
cout << f << endl;
return 0;
}
运行结果:
[ 4, 4, 4, 4, 4;
4, 4, 4, 4, 4;
4, 4, 4, 4, 4;
4, 4, 4, 4, 4;
4, 4, 4, 4, 4]
[ 4, 5, 4, 5, 4, 5, 4, 5, 4, 5;
4, 5, 4, 5, 4, 5, 4, 5, 4, 5;
4, 5, 4, 5, 4, 5, 4, 5, 4, 5;
4, 5, 4, 5, 4, 5, 4, 5, 4, 5;
4, 5, 4, 5, 4, 5, 4, 5, 4, 5]
[ 4, 5, 6, 4, 5, 6, 4, 5, 6, 4, 5, 6, 4, 5, 6;
4, 5, 6, 4, 5, 6, 4, 5, 6, 4, 5, 6, 4, 5, 6;
4, 5, 6, 4, 5, 6, 4, 5, 6, 4, 5, 6, 4, 5, 6;
4, 5, 6, 4, 5, 6, 4, 5, 6, 4, 5, 6, 4, 5, 6;
4, 5, 6, 4, 5, 6, 4, 5, 6, 4, 5, 6, 4, 5, 6]
[1, 2, 3, 4, 5]
[1, 0, 0, 0, 0;
0, 2, 0, 0, 0;
0, 0, 3, 0, 0;
0, 0, 0, 4, 0;
0, 0, 0, 0, 5]
[0, 0;
4, 0]
发表评论