C++openCV Mat类常用函数、深拷贝、指针、at

文章目录

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

Mat类常用函数

使用的命名空间


#pragma once
#include 
#include 

using namespace std;
using namespace cv;

create()

为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;

运行截图:
C++openCV Mat类常用函数、深拷贝、指针、at_第1张图片


reshape()

可在不修改Mat对象数据的前提下,改变对象的通道数与行数。
改变前后满足 channels * cols * rows的值不变。
C++openCV Mat类常用函数、深拷贝、指针、at_第2张图片

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;

C++openCV Mat类常用函数、深拷贝、指针、at_第3张图片


resize()

  • 两个不同的resize,Mat::reszie()修改对象的行数;
    C++openCV Mat类常用函数、深拷贝、指针、at_第4张图片

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

  • cv::resize()重新调整Mat对象的行与列,按指定方式插值填充
    C++openCV Mat类常用函数、深拷贝、指针、at_第5张图片

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;

在这里插入图片描述


setTo()

为Mat对象赋指定值。
在这里插入图片描述

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


operator ()

将原Mat的对象的指定区域拷贝给新对象,他们共用同一存储区域,修改新对象,就对象也会发生改变。
多用于对图像的某一区域进行动态修改、重新赋值。
C++openCV Mat类常用函数、深拷贝、指针、at_第6张图片可将矩形指定区域或者指定行列的矩阵地址返回。


Mat类的复制

copyTo() 与 clone()

copyTo()与clone()都是深拷贝,即拷贝前后的Mat对象不会共用相同的存储空间,修改赋值也互不影响。
他们的区别在于 clone()会直接开辟新的存储空间,将旧对象复制并返回新对象。
而copyTo()会判断拷贝与待拷贝对象的矩阵大小是否相同,若相同则不开辟新的空间,否则开辟新的空间在复制数据。
在这里插入图片描述

在这里插入图片描述

拷贝与赋值构造

Mat对象的拷贝构造()与赋值构造(=)均是浅拷贝,即拷贝前后对象共用相同的存储空间,改变其中一个的值,另一个也随之改变。
C++openCV Mat类常用函数、深拷贝、指针、at_第7张图片

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


Mat指针(ptr)与at

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

Mat type 返回类型
CV_8UC1 uchar
CV_8UC3 Vec3b
C++openCV Mat类常用函数、深拷贝、指针、at_第8张图片

C++openCV Mat类常用函数、深拷贝、指针、at_第9张图片C++openCV Mat类常用函数、深拷贝、指针、at_第10张图片

Vec3b = Vector ,大小为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,c++,计算机视觉)