文章目录

  • Mat类常用函数
  • create()
  • reshape()
  • resize()
  • setTo()
  • operator ()
  • Mat类的复制
  • copyTo() 与 clone()
  • 拷贝与赋值构造
  • Mat指针(ptr)与at

Mat类常用函数

使用的命名空间

#pragma once
#include <opencv2\opencv.hpp>
#include <iostream>

using namespace std;
using namespace cv;

create()

为Mat对象开辟一段的新的存储空间

opencv mat引用传参 opencv mat函数_赋值

与Mat对象初始化一样,可以使用四种方式,均要指定对象的size和类型。

使用size()测试create():

Mat m2;
	//m2 300行 ,200列
	m2.create(Size(200, 300), CV_8UC3);
	cout << "m2 rows:" << m2.rows << endl;
	cout << "m2 cols:" << m2.cols << endl;
	cout << "m2 size:" << m2.size() << endl;

运行截图:

opencv mat引用传参 opencv mat函数_c++_02

reshape()

可在不修改Mat对象数据的前提下,改变对象的通道数与行数。

改变前后满足 channels * cols * rows的值不变。

opencv mat引用传参 opencv mat函数_赋值_03

cn: 改变后的通道数
rows: 改变后的行数

他还有两个重载分别可指定维数和行列。

//reshape test
	Mat m3{ 1,2,3, 4,5,6, 7,8,9 };
	cout << "m3 size:" << m3.size() << endl;
	Mat m4;
	m4 = m3.reshape(1,3);
	//m4与m3指向同一个存储空间,修改其一,另一也修改
	m4 = Scalar(230);
	cout << "m4 size after reshape:" << m4.size() << endl;
	cout << m3.at<int>(4) << endl;

opencv mat引用传参 opencv mat函数_opencv mat引用传参_04

resize()

  • 两个不同的resize,Mat::reszie()修改对象的行数;

SZ :新的行数;
S :当需要添加新元素可以指定其值。

  • cv::resize()重新调整Mat对象的行与列,按指定方式插值填充
src:输入矩阵
 dst:输出矩阵
 dsize:输出的目标大小(列,行)
 fx:输出矩阵列数的权重
 fy:输出矩阵行数的权重
 interpolation:新值填充方式,默认线性插值
 dsize,fx,fy可以互相推导,不能同时为0;
 dsize为0,dst.cols= fy * src.cols ;
 dst.rows=fx * src.rows;
 fx,fy为0,dst.size = dsize;
//cv::resize test
Mat m5(Size(200, 300), CV_8UC3);
Mat m6;
resize(m5, m6, Size(400, 500), 0, 0, INTER_LINEAR);
cout << "m6 size" << m6.size() << endl;

opencv mat引用传参 opencv mat函数_计算机视觉_05

setTo()

为Mat对象赋指定值。

opencv mat引用传参 opencv mat函数_opencv mat引用传参_06

value:Scalar()对象
mask:掩码,通道大于等于1,类型必须是CV_8U,将掩码中非零位置对应在Mat对象上赋值为value。


operator ()

将原Mat的对象的指定区域拷贝给新对象,他们共用同一存储区域,修改新对象,就对象也会发生改变。

多用于对图像的某一区域进行动态修改、重新赋值。

opencv mat引用传参 opencv mat函数_opencv mat引用传参_07

可将矩形指定区域或者指定行列的矩阵地址返回。

Mat类的复制

copyTo() 与 clone()

copyTo()与clone()都是深拷贝,即拷贝前后的Mat对象不会共用相同的存储空间,修改赋值也互不影响。

他们的区别在于 clone()会直接开辟新的存储空间,将旧对象复制并返回新对象。

而copyTo()会判断拷贝与待拷贝对象的矩阵大小是否相同,若相同则不开辟新的空间,否则开辟新的空间在复制数据。

opencv mat引用传参 opencv mat函数_计算机视觉_08

opencv mat引用传参 opencv mat函数_c++_09

拷贝与赋值构造

Mat对象的拷贝构造()与赋值构造(=)均是浅拷贝,即拷贝前后对象共用相同的存储空间,改变其中一个的值,另一个也随之改变。

opencv mat引用传参 opencv mat函数_c++_10

矩阵赋值是一个O(1)运算。这意味着不复制数据,但共享数据,并且增加引用计数器(如果有)。在分配新数据之前,通过Mat::release取消引用旧数据。


Mat指针(ptr)与at

Mat对象的ptr与at用法类似,区别是ptr返回对应位置的指针,而at返回对应位置的引用。
使用ptr与at均要指定返回类型,常用的type与返回类型如下:

Mat type

返回类型

CV_8UC1

uchar

CV_8UC3

Vec3b

opencv mat引用传参 opencv mat函数_赋值_11

opencv mat引用传参 opencv mat函数_opencv_12

opencv mat引用传参 opencv mat函数_opencv_13

Vec3b = Vector<uchar , 3> ,大小为3的vector,存放数据类型为uchar,对应图像的三个通道。相应的有 Vec3f,Vec4b等类型。

Mat m7(Size(200, 300), CV_8UC3);
//使用uchar类型读取(100,200),赋值
//使用uchar指针指向三通道图像,可将uchar看做数组地址,直接用下标访问
uchar* mPtr1 = m7.ptr<uchar>(100,200);
mPtr1[0] = 60;
mPtr1[1] = 160;
mPtr1[2] = 230;
//使用Vec3b类型读取(100,100),赋值
Vec3b* mPtr2 = m7.ptr<Vec3b>(100, 100);
//mPtr2本身是一个指向Vec3b的指针,需要解引用获取Vec3b数组本身,在对每个通道赋值
(* mPtr2)[0] = 55;
(* mPtr2)[1] = 155;
(* mPtr2)[2] = 255;
//结果需要转为int
Vec3b mAt = m7.at<Vec3b>(100, 100);
cout << (int)mAt[0] << endl;
cout << (int)mAt[1] << endl;
cout << (int)mAt[2] << endl;

opencv mat引用传参 opencv mat函数_opencv mat引用传参_14