Opencv是由C语言实现的,实际上它使用的结构体也是遵循面向对象思想设计的,IplImage由CvMat派生
而CvMat由CvArr派生。Mat 是一个类,由两个数据部分组成:矩阵头(包含矩阵尺寸,存储方法,存储地址等
信息)和一个指向存储所有像素值的矩阵(根据所选存储方法的不同矩阵可以是不同的维数)的指针。
Mat矩阵头:包括
typedef struct CvMat { int type; int step; /* for internal use only */ int* refcount; int hdr_refcount; union { uchar* ptr; short* s; int* i; float* fl; double* db; } data; #ifdef __cplusplus union { int rows; int height; }; union { int cols; int width; }; #else int rows; int cols; #endif } CvMat;
每个 Mat 对象有自己的信息头,但共享同一个矩阵。这通过让矩阵指针指向同一地址而实现。而拷贝构造
函数则 只拷贝信息头和矩阵指针 ,而不拷贝矩阵。
Mat 不但是一个很赞的图像容器类,它同时也是一个通用的矩阵类,所以可以用来创建和操作多维矩阵
直接从图片读入;使用拷贝构造函数;使用赋值运算符;
Mat A, C; // 只创建信息头部分 A = imread(argv[1], CV_LOAD_IMAGE_COLOR); // imread读取图像(第一个参数为图像路径需传入,第二个是图像颜色类型
Mat B(A); // 使用拷贝构造函数 C = A; // 赋值运算符
Mat D (A, Rect(10, 10, 100, 100) ); //对A创建一个RIO感兴趣区域 Mat E = A(Range:all(), Range(1,3)); // 使用range函数利用A的行列赋值给
以上代码中的所有Mat对象最终都指向同一个也是唯一一个数据矩阵,最后一个使用Mat的对象会负责清理。
如果想拷贝矩阵本身(不只是信息头和矩阵指针),这时可以使用函数 clone() 或者 copyTo()。
Mat F = A.clone(); Mat G; A.copyTo(G);
使用Mat矩阵图像容器类的构造函数创建Mat类对象
//【1】载入原始图像1.jpg
Mat srcImg=imread("1.jpg",1);
//【2】创建一个和原始图像srcImg高和宽一致的8位无符号单通道的灰度图片容器,并且初始化图片为白色255
Mat grayImg(srcImg.rows,srcImg.cols,CV_8UC1,Scalar(255));
为已经存在的IplImage指针创建信息头
//【1】声明IplImg指针
IplImg* imgTopDown;
//【2】将图片加载到内存中
imgTopDown=cvLoadImage("1.jpg", CV_LOAD_IMAGE_GRAYSCALE);
//【3】为已经存在的imgTopDown指针创建信息头
//【4】转换IplImage*--->Mat
Mat mtx(imgTopDown);
利用Create()函数创建Mat矩阵图像容器类的对象
//【1】载入原始图像1.jpg
Mat srcImg=imread("1.jpg",1);
//【2】创建一个和原始图像srcImg高和宽一致的8位无符号单通道的灰度图片容器,并且初始化图片为白色255
Mat dstImg.create(srcImg.rows,srcImg.cols,CV_8UC1);
- Matlab风格的函数创建Mat矩阵图形容器类的对象
//! Matlab-style matrix initialization
static MatExpr zeros(int rows, int cols, int type);
static MatExpr zeros(Size size, int type);
static MatExpr zeros(int ndims, const int* sz, int type);
static MatExpr ones(int rows, int cols, int type);
static MatExpr ones(Size size, int type);
static MatExpr ones(int ndims, const int* sz, int type);
static MatExpr eye(int rows, int cols, int type);
static MatExpr eye(Size size, int type);
//【1】载入原始图像1.jpg
Mat srcImg=imread("1.jpg",1);
//【2】创建一个和原始图像srcImg高和宽一致的8位无符号单通道的灰度图片容器,并且初始化图片为白色255
Mat dstImg=Mat::zeros(srcImg.rows,srcImg.cols,CV_8UC3);
Mat dstImg=Mat::ones(srcImg.rows,srcImg.cols,CV_8UC3);
Mat dstImg=Mat::eye(srcImg.rows,srcImg.cols,CV_8UC3);
type--所创建图像/矩阵的类型
这里的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
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通道图像
--通过上面的讲解,现在,我们解读一下OpenCv的源代码:
//【1】CV_8UC1---则可以创建----8位无符号的单通道---灰度图片------grayImg
#define CV_8UC1 CV_MAKETYPE(CV_8U,1)
#define CV_8UC2 CV_MAKETYPE(CV_8U,2)
//【2】CV_8UC3---则可以创建----8位无符号的三通道---RGB彩色图像---colorImg
#define CV_8UC3 CV_MAKETYPE(CV_8U,3)
//【3】CV_8UC4--则可以创建-----8位无符号的四通道---带透明色的RGB图像
#define CV_8UC4 CV_MAKETYPE(CV_8U,4)
原博客:http://blog.csdn.net/maweifei/article/details/51221259