【3】OpenCV入门-Mat详解

声明:本博客部分参考《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++;
    }
}
发布了7 篇原创文章 · 获赞 18 · 访问量 1898

猜你喜欢

转载自blog.csdn.net/qq_37981695/article/details/104214646
今日推荐