openv中Mat用法.docx

上传人:b****5 文档编号:7647191 上传时间:2023-01-25 格式:DOCX 页数:13 大小:23.61KB
下载 相关 举报
openv中Mat用法.docx_第1页
第1页 / 共13页
openv中Mat用法.docx_第2页
第2页 / 共13页
openv中Mat用法.docx_第3页
第3页 / 共13页
openv中Mat用法.docx_第4页
第4页 / 共13页
openv中Mat用法.docx_第5页
第5页 / 共13页
点击查看更多>>
下载资源
资源描述

openv中Mat用法.docx

《openv中Mat用法.docx》由会员分享,可在线阅读,更多相关《openv中Mat用法.docx(13页珍藏版)》请在冰豆网上搜索。

openv中Mat用法.docx

openv中Mat用法

Mat本质上是由两个数据部分组成的类:

(包含信息有矩阵的大小,用于存储的方法,矩阵存储的地址等)的矩阵头和一个指针,指向包含了像素值的矩阵(可根据选择用于存储的方法采用任何维度存储数据)。

矩阵头部的大小是恒定的。

然而,矩阵本身的大小因图像的不同而不同,通常是较大的数量级。

因此,当你在您的程序中传递图像并在有些时候创建图像副本您需要花费很大的代价生成图像矩阵本身,而不是图像的头部。

OpenCV是图像处理库,它包含大量的图像处理函数。

若要解决的计算挑战,最终大部分时间你会使用库中的多个函数。

由于这一原因图像传给库中的函数是一种常见的做法。

我们不应忘记我们正在谈论往往是计算量相当大的图像处理算法。

我们想要做的最后一件事是通过制作不必要的可能很大的图像的拷贝进一步降低您的程序的速度。

    为了解决这一问题OpenCV使用引用计数系统。

其思想是Mat的每个对象具有其自己的头,但可能他们通过让他们矩阵指针指向同一地址的两个实例之间共享该矩阵。

此外,拷贝运算符将只能复制矩阵头部,也还将复制指针到大型矩阵,但不是矩阵本身。

1.MatA,C;//仅创建了头部

2.A=imread(argv[1],CV_LOAD_IMAGE_COLOR);//在此我们知道使用的方法(分配矩阵)

3.MatB(A);//使用拷贝构造函数

4.C=A;//赋值运算符

复制代码

    上文中的所有对象,以相同的单个数据矩阵的结束点。

他们头不同,但是使用的其中任何一个对矩阵进行任何修改,也将影响所有其他的。

在实践中的不同对象只是提供相同的底层数据不同的访问方法,然而,它们的头部是不同的。

真正有趣的部分是您可以创建仅指向完整数据的一小部分的头。

例如,要在图像中创建兴趣区域(ROI)您只需创建一个新头设置新边界:

1.

5px;margin-bottom:

5px;">MatD(A,Rect(10,10,100,100));//用矩形界定

5px;margin-bottom:

5px;">MatE=A(Range:

all(),Range(1,3));//用行和列来界定

复制代码

现在,你可能会问是否矩阵的本身可以属于多个Mat对象在不再需要时负责清理数据。

简短的回答是:

最后一个使用它的对象。

这对于使用引用计数的机制,每当有人复制Mat对象的头,矩阵的计数器被增加。

每当一个头被清除,此计数器被下调。

当该计数器变为零,矩阵也就被释放了。

因为有时会仍然也要复制矩阵的本身,存在着clone()或copyTo()函数。

1.

5px;margin-bottom:

5px;">MatF=A.clone();

5px;margin-bottom:

5px;">MatG;

5px;margin-bottom:

5px;">A.copyTo(G);

复制代码

现在modifyingForGwill不会影响由theMatheader指出的矩阵。

你要记得从所有的是:

        •输出图像分配OpenCV功能是自动(除非另行指定,否则)。

        •用c++OpenCV的接口就无需考虑内存释放。

        •赋值运算符和复制构造函数(构造函数)只复制头。

        •使用clone()或copyTo()函数将复制的图像的基础矩阵。

存储方法

    这是关于你是如何存储的像素值。

您可以选择的颜色空间和使用的数据类型。

色彩空间是指我们如何结合为了代码指定的颜色的颜色分量。

最简单的是灰色的规模。

在这里我们所掌握的颜色是黑色和白色。

组合的这些让我们能创造很多的灰度级。

    对于彩色的方法,我们有很多方法可供选择。

不过,每一就是将他们拆解成三个或四个基本组成部分,这些部分就会组合给所有其他的方法。

最受欢迎的这一个RGB,主要是因为这也是我们的眼睛如何建立中我们的眼睛的颜色。

其基准的颜色是红、绿、蓝。

编写代码的一种颜色的透明度有时第四个元素:

添加alpha(A)。

但是,它们很多颜色系统每个具有自身的优势:

        •RGB是最常见的是我们的眼睛使用类似的事情,我们显示系统还撰写使用这些颜色。

        ·单纯疱疹和合肥分解颜色到他们的色相、饱和度和亮度值/组件,这是我们来描述颜色更自然的方式。

您使用,例如可驳回的最后一个组件,使你不那么明智的输入图像的光照条件的算法。

        •YCrCb使用流行的JPEG图像格式。

        •CIEL*b*a是均匀颜色空间,它是非常方便的如果您需要测量给定的颜色,以另一种颜色的距离。

    现在,每个建筑构件都自己有效的域。

这会导致使用的数据类型。

我们如何存储组件的定义只是如何精细的控制,我们已于其域。

最小的数据类型可能是char类型,这意味着一个字节或8位。

这可能是有符号(值-127到+127)或无符号(以便可以存储从0到255之间的值)。

虽然这三个组件的情况下已经给16万可能的颜色来表示(如RGB的情况下)我们可能通过使用浮点数(4字节=32位)或double(8字节=64位)数据类型的每个组件获得甚至更精细的控制。

然而,请记住增加组件的大小也会增加在内存中的整张图片的大小。

显式创建Mat对象

    在Load,ModifyandSaveanImage 教程中,你已经可以看到如何使用readWriteImageVideo:

'imwrite()'函数将一个矩阵写到一个图像文件中。

然而,出于调试目的显示的实际值就方便得多。

您可以实现此通过Mat的<<运算符。

不过,请注意这仅适用于二维矩阵。

    虽然Mat是一个伟大的图像容器类,它也是一般矩阵类。

因此,利用Mat创建和操作多维矩阵是可能的。

您可以通过多种方式创建Mat的对象:

•Mat()构造函数

MatM(2,2,CV_8UC3,Scalar(0,0,255));

cout<<"M="<

    对于二维的和多通道的图像,我们首先定义它们的大小:

按行和列计数。

    然后我们需要指定的数据类型,用于存储元素和每个矩阵点通道的数量。

为此,我们根据以下的约定可以作出多个定义:

CV_[每一项的位数][有符号或无符号][类型前缀]C[通道数]

例如,CV_8UC3意味着我们使用那些长的8位无符号的char类型和每个像素都有三个项目的这三个通道的形成。

这是预定义的四个通道数字。

Scalar是四个元素短向量。

指定此和可以初始化所有矩阵点与自定义的值。

但是如果你需要更多您可以创建与上部宏和频道号码放在括号中,您可以看到下面的类型。

    使用C\C++数组和通过构造函数来初始化

1.

5px;margin-bottom:

5px;">intsz[3]={2,2,2};

5px;margin-bottom:

5px;">MatL(3,sz,CV_8UC

(1),Scalar:

:

all(0));

复制代码

上例为我们展示了如何创建一个二维以上的矩阵。

首先指定其维度数,然后传入一个包含了尺寸每个维度信息的指针,其他都保持不变。

•为一个已经存在的IplImage创建一个头:

IplImage*img=cvLoadImage("greatwave.png",1);

Matmtx(img);//转换IplImage*->Mat

•Create()函数:

M.create(4,4,CV_8UC

(2));

cout<<"M="<

你不能通过这个构造来初始化矩阵中的数值。

它只会在新的居住尺寸与旧的矩阵尺寸不合时重新分配矩阵的数据空间。

•MATLAB风格的初始化函数:

zeros(),ones(),

eyes().指定使用的尺寸和数据类型

1.

5px;margin-bottom:

5px;">MatE=Mat:

:

eye(4,4,CV_64F);

5px;margin-bottom:

5px;">cout<<"E="<

5px;margin-bottom:

5px;">MatO=Mat:

:

ones(2,2,CV_32F);

5px;margin-bottom:

5px;">cout<<"O="<

5px;margin-bottom:

5px;">MatZ=Mat:

:

zeros(3,3,CV_8UC1);

5px;margin-bottom:

5px;">cout<<"Z="<

复制代码

•对于小的矩阵来说你可以使用逗号隔开的初始化函数:

MatC=(Mat_(3,3)<<0,-1,0,-1,5,-1,0,-1,0);

cout<<"C="<

•为一个已有的Mat对象创建一个新的头然后clone()或者copyTo()这个头.

MatRowClone=C.row

(1).clone();

cout<<"RowClone="<

打印格式

注意:

你可以通过用randu()函数产生的随机值来填充矩阵。

你需要给定一个上限和下限来确保随机值在你期望的范围内:

MatR=Mat(3,2,CV_8UC3);

randu(R,Scalar:

:

all(0),Scalar:

:

all(255));

在上一个例子中你可以看到默认的格式选项。

尽管如此,OpenCV允许你在符合以下规则的同时格式化你的输出:

•默认

cout<<"R(default)="<

•Python

cout<<"R(python)="<

•Commaseparatedvalues(CSV)

cout<<"R(csv)="<

•Numpy

cout<<"R(numpy)="<

•C

cout<<"R(c)="<

打印出其它常见数据项

OpenCV通过<<操作符也为其他常用OpenCV数据结构提供打印输出的支持,如:

•2D点

Point2fP(5,1);

cout<<"Point(2D)="<

•3D点

Point3fP3f(2,6,7);

cout<<"Point(3D)="<

•std:

:

vector通过cv:

:

Mat

vectorv;

v.push_back((float)CV_PI);v.push_back

(2);v.push_back(3.01f);

cout<<"VectoroffloatsviaMat="<

•点的std:

:

vector

vectorvPoints(20);

for(size_tE=0;E

vPoints[E]=Point2f((float)(E*5),(float)(E%7));

cout<<"Avectorof2DPoints="<

这里大多数的例程都是在一个小控制台程序里运行。

你可以在这里下载或是在cpp示例文件夹下找到。

你可以在YouTube.上找到一个快速的实例演示

Mat:

:

~Mat

Mat的析构函数。

C++:

Mat:

:

~Mat()

析构函数调用Mat:

:

release()。

Mat:

:

operator=

提供矩阵赋值操作。

C++:

Mat&Mat:

:

operator=(constMat&m)

C++:

Mat&Mat:

:

operator=(constMatExpr_Base&expr)

C++:

Mat&Mat:

:

operator=(constScalar&s)

参数:

m –被赋值的右侧的矩阵。

矩阵的赋值是一个复杂度为O

(1)的操作。

这就意味着没有数据段复制并且有数量的递增两矩阵将使用同一引用计数器。

在给矩阵赋新数据之前先由Mat:

:

release()释放引用。

expr –被赋值的矩阵表达式对象。

作为第一种赋值方式的逆操作第二种形式可以被重新用到具有适当大小和尺寸的已分配空间的矩阵上以适应表达式的结果。

矩阵表达式扩展得到的实函数将自动处理这个分配过程。

例如:

C=A+B扩展成add(A,B,C),andadd()要当心C重新分配数据的操作。

.

s –标量赋值给每一个矩阵元,矩阵的大小和类型将不会改变。

有现成的赋值运算符。

由于他们各不相同请阅读运算符参数说明。

Mat:

:

operatorMatExpr

提供一种Mat-to-MatExpr转换运算符

C++:

Mat:

:

operatorMatExpr_()const

转换运算符不能显示调用而是由矩阵表达式引擎(MatrixExpressionengine)内部调用Thecastoperatorshouldnotbecalledexplicitly.ItisusedinternallybytheMatrixExpressionsengine.

Mat:

:

row

创建一个指定行数的矩阵头。

.

C++:

MatMat:

:

row(inti)const

参数:

i– 一个0基的行索引.

该方法创建一个具有指定了行数的新矩阵头的矩阵并返回它。

这是一个复杂度为O

(1)的操作,无须考虑矩阵的尺寸。

新矩阵和原矩阵共享一份基础数据。

这是一个典型基本矩阵处理操作的例子,axpy是LU和许多其它算法都使用的一个函数

inlinevoidmatrix_axpy(Mat&A,inti,intj,doublealpha)

{

A.row(i)+=A.row(j)*alpha;

}

Note:

在当前实现中,下面的代码不会无法按预期的效果工作:

MatA;

...

A.row(i)=A.row(j);//不起作用

发生这种情况是因为A.row(i)形成临时矩阵头进一步分配给另一个矩阵头。

请记住,每个操作复杂度为O

(1),即没有复制任何数据。

因此,如果你预期第j行被复制到第i行,那么上述赋值不成立。

要做到这一点,应该把这种简单的赋值转换到表达式中或使用Mat:

:

copyTo()方法:

MatA;

...

//可行,但看上去有点目的不明确。

A.row(i)=A.row(j)+0;

//这是有点儿长,但这是推荐的方法。

A.row(j).copyTo(A.row(i));

Mat:

:

col

创建一个具有指定了矩阵头中列数这个参数的矩阵

C++:

MatMat:

:

col(intj)const

参数:

j –一个0基(从0开始)的列索引

该方法创建一个具有指定了矩阵头中列数这个参数的新矩阵并作为函数返回值。

这是一种复杂度为O

(1)的操作,不用考虑矩阵的尺寸大小。

新矩阵和原始矩阵共享一份基础数据。

参看Mat:

:

row()说明信息。

Mat:

:

rowRange

为指定的行span创建一个新的矩阵头。

C++:

MatMat:

:

rowRange(intstartrow,intendrow)const

C++:

MatMat:

:

rowRange(constRange&r)const

参数:

startrow –一个包容性的0基(从0开始)的行span起始索引.。

endrow –一个0基的独占性的行span.终止索引。

r –Range结构包含着起始和终止的索引值。

该方法给矩阵指定的行span创建了新的头。

与Mat:

:

row()和Mat:

:

col()相类似这是一个复杂度为O

(1)的操作。

Mat:

:

colRange

为指定的行span创建一个矩阵头。

C++:

MatMat:

:

colRange(intstartcol,intendcol)const

C++:

MatMat:

:

colRange(constRange&r)const

参数:

startcol –一个包容性的0基(从0开始)的span列起始索引。

endcol –一个0基的独占性的列span.终止索引。

r –Range结构包含着起始和终止的索引值。

该方法给矩阵指定的列span创建了新的头。

与Mat:

:

row()和Mat:

:

col()相类似这是一个复杂度为O

(1)的操作。

Mat:

:

diag

提取或创建矩阵对角线。

C++:

MatMat:

:

diag(intd)const

C++:

staticMatMat:

:

diag(constMat&matD)

参数:

d –对角线的索引值,可以是以下的值:

–d=0是主对角线

–d>0表示下半部的对角线。

例如:

d=1对角线是紧挨着住对角线并位于矩阵下方。

–d<0表示来自矩阵上半部的对角线。

例如:

d=1表示对角线被设置在对角线的上方并紧挨着。

matD –单列用于形成矩阵对角线的列。

该方法为指定的矩阵创建一个新的头。

然后新矩阵被分割为单独的列矩阵。

类似于Mat:

:

row()和Mat:

:

col(),它是复杂度为O

(1)操作。

Mat:

:

clone

创建一个数组及其基础数据的完整副本。

C++:

MatMat:

:

clone()const

该方法创建了一个完整的数组副本。

原始的step[]不会被考虑在内的。

因此数组的副本是一占用total()*elemSize()字节的连续阵列。

Mat:

:

copyTo

把矩阵复制到另一个矩阵中。

C++:

voidMat:

:

copyTo(OutputArraym)const

C++:

voidMat:

:

copyTo(OutputArraym,InputArraymask)const

参数:

m –目标矩阵。

如果它的尺寸和类型不正确,在操作之前会重新分配。

mask –操作掩码。

它的非零元素表示矩阵中某个要被复制。

该方法把矩阵的复制到另一个新的矩阵中在复制之前该方法会调用

m.create(this->size(),this->type);

因此,目标矩阵会在必要的情况下重新分配

尽管m.copyTo(m)worksflawlessly,该函数并不处理源矩阵和目标矩阵之间有重叠的部分的情况。

当操作掩码指定以及上述的Mat:

:

create重新分配矩阵,新分配的矩阵在数据复制到里面之前全都被初始化为0。

Mat:

:

convertTo

在缩放或不缩放的情况下转换为另一种数据类型。

C++:

voidMat:

:

convertTo(OutputArraym,intrtype,doublealpha=1,doublebeta=0)const

参数:

m –目标矩阵。

如果它的尺寸和类型不正确,在操作之前会重新分配。

rtype –要求是目标矩阵的类型,或者在当前通道数与源矩阵通道数相同的情况下的depth。

如果rtype为负,目标矩阵与源矩阵类型相同。

beta –可选的delta加到缩放值中去。

该方法将源像素值转化为目标类型saturate_cast<>要放在最后以避免溢出

m(x;y)=saturate_cast(α*(*this)(x;y)+β)

Mat:

:

assignTo

提供了一个convertTo的功能形式。

C++:

voidMat:

:

assignTo(Mat&m,inttype=-1)const

Parameters

m –目标阵列。

type –要求是目标阵列depth或-1(如果阵列的类型和源矩阵类型相同)

这是一个internally使用的由MatrixExpressions引擎调用的方法。

Mat:

:

setTo

将阵列中所有的或部分的元素设置为指定的值。

C++:

Mat&Mat:

:

setTo(constScalar&s,InputArraymask=noArray())

参数:

s –把标量赋给阵列并转化到阵列的实际类型。

mask –与*this尺寸相同的操作掩码。

这是Mat:

:

operator=(constScalar&s)运算符的一个高级变量。

Mat:

:

reshape

在无需复制数据的前提下改变2D

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 小学教育 > 小升初

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1