人眼中为图片内容,在opencv中会被解析为一个数组,代表的即为像素,这些数值就存放在mat里,即为mat对象。
一、Mat对象与IplImage对象
- Mat对象OpenCV2.0之后引进的图像数据结构、自动分配内存、不存在内存泄漏的问题,是面向对象的数据结构。分了两个部分,头部与数据部分
- iplimage是从2001年OpenCV发布之后就一直存在,是C语言风格的数据结构,需要开发者自己分配与管理内存,对大的程序使用它容易导致内存泄漏问题
二、Mat对象构造函数与常用方法
常用方法:
void copyTo(Mat mat) //克隆
void convertTo(Mat dst, int type) //比如将长度八位的切换为浮点数
Mat clone()
int channels()
int depth() //深度
bool empty(); //是否空
uchar* ptr(i=0) //是否可以获取图像指针,i=0第0行,uchar指针类型,ptr书写
三、Mat对象的使用
- 部分复制:一般情况下只会复制Mat对象的头和指针部分,不会复制数据部分
Mat A= imread(imgFilePath);
Mat B(A) // 只复制 - 全复制:如果想把Mat对象的头部和数据部分一起复制,可以通过如下两个API实现
Mat F = A.clone(); 或 Mat G; A.copyTo(G);
Mat对象使用的四个要点:
- 输出图像的内存是自动分配的
- 使用OpenCV的C++接口,不需要考虑内存分配问题
- 赋值操作和拷贝构造函数只会复制头部分
- 使用clone与copyTo两个函数实现数据完全复制
四、Mat对象的创建
- cv::Mat::Mat构造函数
Mat M(2,2,CV_8UC3, Scalar(0,0,255)) 与通道数相同
其中前两个参数分别表示行(row)跟列(column)、第三个CV_8UC3中的8表示每个通道占8位、U表示无符号、C表示Char类型、3表示通道数目是3,第四个参数是向量表示初始化每个像素值是多少,向量长度对应通道数目一致
• 创建多维数组cv::Mat::create
int sz[3] = {2,2,2};
Mat L(3,sz, CV_8UC1, Scalar::all(0));• cv::Mat::create实现
Mat M;
M.create(4, 3, CV_8UC2); //此方式不能赋值
M = Scalar(127,127); // 赋值
cout << “M = " << endl << " " << M << endl << endl;
uchar* firstRow = M.ptr(0);
printf(”%d", *firstRow);
定义小数组
五、演示代码
#include <opencv2/core/core.hpp>
#include <opencv2/imgcodecs.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc.hpp>
#include <iostream>
using namespace cv;
using namespace std; //应用命名空间
int main(int argc, char** argv) { //定义主函数
Mat src = imread("D:/vcprojects/test1.jpg");// 定义读入图像
if (src.empty()) {
cout << "could not load image ..." << endl;
return -1;
}
namedWindow("input", CV_WINDOW_AUTOSIZE);
imshow("input", src);
/*
Mat dst;
dst = Mat(src. size(), src.type()); //初始化一个mat对象,创建一张空白图像,大小类型
dst = Scalar(127, 0, 255); //进行赋值,颜色
namedWindow("output", CV_WINDOW_AUTOSIZE);
imshow("ouyput", dst);*/
/*
Mat dst = src.clone(); //克隆为完全拷贝
namedWindow("output", CV_WINDOW_AUTOSIZE);
imshow("ouyput", dst); */
Mat dst;
//src.copyTo(dst); //输入参数dst 功能同上
namedWindow("output", CV_WINDOW_AUTOSIZE);
cvtColor(src, dst, COLOR_BGR2HSV);
printf("input image channels : %d\n", src.channels()); //显示通道数
printf("output image channels :%d\n",dst.channels());
int cols = dst.cols; //得到全部行列
int rows = dst.rows;
printf("rows : %d cols :%d\n", rows, cols);//\n换行操作
const uchar* firstRow = dst.ptr<uchar>(0);
printf("fist pixel value : %d\n", *firstRow);
Mat M(100, 100, CV_8UC3 ,Scalar(0, 0, 111)); //构造100*100的 定义一个红色的
cout << "M = " << endl << M << endl;//打出3*3的像素集合,可理解为小图像,每个像素有三个通道,可用于算法检测预期值,先RUN小图检测错误
imshow("output",M);
waitKey(0);
return 0;
}