声明:本博客部分参考《OpenCV3编程入门》这本书
1.Mat与lpIlmage对象
Mat对象是OpenCV2.0之后引进的图像数据结构、自动分配内存、不存在内存泄漏问题,是面向对象
的数据结构。Mat分头部和数据部分。
lpllmage是从2001年OpenCV发布之后就一直存在的,是C语言风格的数据结构,需要开发者自己分配
和管理内存,容易造成内存泄漏。
2.Mat中的常见函数
(1)构造函数
(2)其他方法
void copyTo(Mat mat)
void convertTo(Mat dst, int type)
Mat clone()
int channels()
int depth()
bool empty();
uchar* ptr(i=0)
3.Mat创建
(1)通过构造函数
Mat c(300, 300, CV_8UC3, Scalar(255,0,0));
上面的代码会生成一个蓝色的300x300的窗口。
①前两个参数分别为图像的高(row)和宽(col)
②CV_8UC3表示图像的格式:CV_[位数][带符号与否][类型前缀]C[通道数]:数据类型和通道数。其中通道数也可以不指定
常见的有:CV_8UC1、CV_8UC3、CV_8UC4、CV_32FC1、CV_32FC3、CV_32FC4
③最后一位是颜色值:OpenCV中三原色的分布是按Blue、Green、Red来的。
备注:这种方式创建的是二维矩阵,下面介绍创建维数大于等于3的矩阵。
int sz[3] = {2,2,2};
Mat L(3,sz,CV_8UC,Scalar::all(0));
①参数一指定维数,上述代码中为3。
②参数二指定各个维数的大小。
③参数三、四见前面介绍。其中all(0)表示BGR分量都是0。
(2)通过create函数构造
Mat c;
c.create(300, 300, CV_8UC3);
这种方式有个缺陷,你不可以给你创建的图像直接设置颜色。
(3)采用Matlab中的方法
//4x4的单位矩阵
Mat E = Mat::eye(4,4,CV_64F)
//2x2的1矩阵
Mat O = Mat::ones(2,2,CV_32F);
//3x3的0矩阵
Mat Z = Mat::zeros(3,3,CV_8UC1);
(4)使用逗号分隔符初始化
Mat C = (Mat_<double>(3,3) << 0,-1,0,-1,5,-1,0,-1,0)
//生成3x3的矩阵
4.Mat的拷贝
普通的赋值和拷贝只会拷贝Mat结构的头部,只有clone()和copyTo()才能实现完全拷贝
Mat F = A.clone();
A.copyTo(G);
A.copyTo(G,CV_8UC3);
其中copyTo()可以指定拷贝往的Mat对象的数据类型。
5.Mat对象元素的输出显示
(1)直接使用“<<”运算符
Mat c(2, 2, CV_8UC3, Scalar(255, 255, 255));
cout << c;
//[255, 255, 255, 255, 255, 255;
//255, 255, 255, 255, 255, 255]
这里就要将以下Mat中的数据组织形式了,上面代码中c是三通道的,所以每个像素有3个颜色值,所有每一行3个值表示一个像素。
(2)使用"<<"+format()函数
Mat r(2, 2, CV_8UC3, Scalar(255, 255, 255));
//python风格输出
cout << "Python" << endl;
cout << format(r, Formatter::FMT_PYTHON) << endl;
//逗号风格输出
cout << "逗号" << endl;
cout << format(r, Formatter::FMT_CSV) << endl;
//Numpy风格输出
cout << "Numpy" << endl;
cout << format(r, Formatter::FMT_NUMPY) << endl;
//c风格输出
cout << "C语言" << endl;
cout << format(r, Formatter::FMT_C) << endl;
/*Python
[[[255, 255, 255], [255, 255, 255]],
[[255, 255, 255], [255, 255, 255]]]
逗号
255, 255, 255, 255, 255, 255
255, 255, 255, 255, 255, 255
Numpy
array([[[255, 255, 255], [255, 255, 255]],
[[255, 255, 255], [255, 255, 255]]], dtype='uint8')
C语言
{255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255}*/
6.Mat对象的一些属性
(1)Mat::rows和Mat::cols,这两个分别是图像的行数(高)和列数(宽),都是公有变量可以直接访问
(2)Mat::channels()-返回图像的通道数。
(3)Mat::depth()-返回图像的深度,即Mat中的数据类型8U或者32F,不考虑通道数。
(4)Mat::type()-图像的数据类型。
7.访问图像中的单个像素
(1)at()方法
//访问单通道图像
uchar pixle = src.at<uchar>(row,col);
//访问多通道图像(CV_8UC3)
Vec3b bgr = src.at<Vec3b>(row,col);
//(CV_32UC3)
Vec3f bgr = src.at<Vec3f>(row,col);
需要结合图像的type()类型来操作。
(2)指针操作
for (size_t row = 0; row < rows; ++row)
{
//获取行指针
uchar *prow = cornerImage.ptr(row);
for (size_t col = 0; col < cols; ++col)
{
int rvalue = static_cast<int>(*prow);
prow++;
}
}