Mat 和IplImage
Mat对象OpenCV2.0之后引进的图像数据结构、自动分配内存、不存在内存泄漏的问题,是面向对象的数据结构。分了两个部分,头部与数据部分
IplImage是从2001年OpenCV发布之后就一直存在,是C语言风格的数据结构,需要开发者自己分配与管理内存,对大的程序使用它容易导致内存泄漏问题。
Maat成员变量
enum { MAGIC_VAL = 0x42FF0000, AUTO_STEP = 0, CONTINUOUS_FLAG = CV_MAT_CONT_FLAG, SUBMATRIX_FLAG = CV_SUBMAT_FLAG };
enum { MAGIC_MASK = 0xFFFF0000, TYPE_MASK = 0x00000FFF, DEPTH_MASK = 7 };
/*! includes several bit-fields:
- the magic signature
- continuity flag
- depth
- number of channels
*/
int flags;
//! the matrix dimensionality, >= 2
int dims;
//! the number of rows and columns or (-1, -1) when the matrix has more than 2 dimensions
int rows, cols;
//! pointer to the data
uchar* data;
//! helper fields used in locateROI and adjustROI
const uchar* datastart;
const uchar* dataend;
const uchar* datalimit;
//! custom allocator
MatAllocator* allocator;
//! and the standard allocator
static MatAllocator* getStdAllocator();
static MatAllocator* getDefaultAllocator();
static void setDefaultAllocator(MatAllocator* allocator);
//! interaction with UMat
UMatData* u;
MatSize size;
MatStep step;
一般我们只需要关注几个常用成员变量:
//Mat的维度
int dims;
//Mat的行数、列数
int rows, cols;
//Mat的数据指针
uchar* data;
//Mat的形状
MatSize size;
Mat对象构造函数与常用方法
常用方法:
//把一张图复制到另一张图
void copyTo(Mat mat) const;/void copyTo( Mat m, Mat mask ) const;
//convertTo()函数负责转换数据类型不同的Mat,即可以将类似float型的Mat转换到imwrite()函数能够接受的类型。
void convertTo(Mat dst, int type)
//复制图像
Mat clone()
//通道数
int channels()
//图像深度
int depth()
//是否为空
bool empty();
//得到某行的指针(dst.ptr(0)
uchar* ptr(i=0)
//部分函数的使用示例
#include<opencv2/opencv.hpp>
#include<iostream>
#include<math.h>
using namespace cv;
using namespace std;
int main(int argc,char** argv) {
Mat src, dst;
src = imread("D:\\File\\G\\images\\shiyuan.png", IMREAD_COLOR);
//判断图像读取
if (!src.data) {
printf("Could not load image...\n");
}
//显示原图像
namedWindow("input img", WINDOW_AUTOSIZE);
imshow("input img", src);
创建一个和src图像大小类型一样的空图像
//dst = Mat(src.size(), src.type());
Scalar函数参数为B G R
//dst = Scalar(0, 0, 255);
//显示图像
namedWindow("output", WINDOW_AUTOSIZE);
cvtColor(src, dst, CV_BGR2GRAY);
imshow("output", dst);
//输出原图像通道数和灰度图像通道数
cout << "input image channels:" << src.channels() << endl;
cout << "output image channels:" << dst.channels() << endl;
//获取行指针
const uchar* firstRow = dst.ptr<uchar>(0);
cout << "first pixel value:" << *firstRow << endl;
//获取行和列数
int rows, cols;
rows = dst.rows;
cols = dst.cols;
cout << "image rows value:" << rows << endl;
cout << "image cols value:" << cols << endl;
//创建3*3矩阵
Mat M(3,3, CV_8UC3, Scalar(0, 0, 255));
cout << M << endl;
//显示创建的矩阵
namedWindow("M", WINDOW_AUTOSIZE);
imshow("M", M);
//创建一个和原图像大小类型一样的图像
Mat M1;
M1.create(src.size(), src.type());
M1 = Scalar(0, 255, 0);
namedWindow("M1", WINDOW_AUTOSIZE);
imshow("M1", M1);
//定义一个小数组
Mat csrc;
Mat Kernel = (Mat_<float>(3, 3) << 0, -1, 0, -1, 5, -1, 0, -1, 0);
//filter2D卷积运算函数
//函数解释博客链接:https://blog.csdn.net/keith_bb/article/details/53103026?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522163229585616780265424479%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=163229585616780265424479&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~top_positive~default-1-53103026.pc_search_all_es&utm_term=filter2D&spm=1018.2226.3001.4187
filter2D(src, csrc, -1, Kernel);
namedWindow("csrc", WINDOW_AUTOSIZE);
imshow("csrc", csrc);
//不加这个会闪退
cvWaitKey(0);
return 0;
}
结果
Iplimage数据结构:
IplImage
|-- int nChannels; // 色彩通道数(1,2,3,4)
|-- int depth; // 象素色深:
| // IPL_DEPTH_8U, IPL_DEPTH_8S,
| // IPL_DEPTH_16U,IPL_DEPTH_16S,
| // IPL_DEPTH_32S,IPL_DEPTH_32F,
| // IPL_DEPTH_64F
|-- int width; // 图像宽度(象素点数)
|-- int height; // 图像高度(象素点数)
|-- char* imageData; // 指针指向成一列排列的图像数据
| // 注意色彩顺序为BGR
|-- int dataOrder; // 0 - 彩色通道交叉存取 BGRBGRBGR,
| // 1 - 彩色通道分隔存取 BBBGGGRRR
| // 函数cvCreateImage只能创建交叉存取的图像
|-- int origin; // 0 - 起点为左上角,
| // 1 - 起点为右下角(Windows位图bitmap格式)
|-- int widthStep; // 每行图像数据所占字节大小
|-- int imageSize; // 图像数据所占字节大小 = 高度*每行图像数据字节大小
|-- struct _IplROI *roi;// 图像ROI. 若不为NULL则表示需要处理的图像
| // 区域.
|-- char *imageDataOrigin; // 指针指向图像数据原点
| // (用来校准图像存储单元的重新分配)
|
|-- int align; // 图像行校准: 4或8字节校准
| // OpenCV不采用它而使用widthStep
|-- char colorModel[4]; // 图像色彩模型 - 被OpenCV忽略
原文链接:https://blog.csdn.net/spaceyqy/article/details/25775797
例子:http://blog.csdn.net/to_utopia/article/details/4856171
参考
Opencv C++ 基本数据结构 Mat
OpenCV中 IplImage 与 Mat
B站视频
大佬们的博客,抱歉,查了太多资料,没办法一一写全。。。。。
可能会有错误,请大家积极指正,谢谢。