opencv中Mat的传值、传引用、拷贝

一.前言

    c++中,函数参数的传值、传引用、传指针是有区别的。 通常情况下:传值是对原对象的拷贝,在函数内对其进行的操作不会影响到原对象。 而传指针,是将指向原对象内存区域的一个指针作为函数参数,在函数内,访问和操作该指针指向的内存,会直接影响到原对象。引用的定义是原对象的一个绑定,可以理解为两个对象是一致的,修改其中一个,另一个也会改变。

    但是opencv中的Mat对象却并非这样。

二.实验

    1.传值

                    

                    

                    

        三张图分别为:原始图片src_1、将src_1 值传递给函数myDrawCircle生成的图、和函数调用结束后的src_1。

        可以发现Mat对象传值调用,函数内对其的操作将会影响原对象!

 

    2.传引用

        

        分别为调用函数前后的图片。

        引用是对原对象的绑定,对引用进行操作,会改变原对象!

    3.重载符=

    

        使用opencv中的重载符=,如Mat img=src;

        如上,使用=复制的图片,对其进行操作,会改变原图;

    4.拷贝构造函数

         Mat img(src);

         同=,对其进行操作,会改变原图;

    5.copyTo()函数

            Mat img;src.copyTo(img);

            

    src_3为原图,myDrawcircle4是在copyTo复制的图上画的圆,cur Src_3是在上述操作后的src_3。

    可以看出,copyTo函数复制的对象,对其进行操作,不会影响原对象

    6.clone()

 

        打开mat.hpp,clone的定义是这样的。显然,clone()同copyTo

三.总结

    Mat src=imread("./1.jpg");

    使用赋值运算符和拷贝构造函数只复制信息头,对其进行操作会作用在原对象上

    Mat A=src;

    Mat B(src);

    使用函数clone()或者copyTo可复制一副图像的矩阵,对其进行操作不会影响原对象

    Mat C,D;

    C=src.clone();

    src.copyTo(D);

   Mat对象做为函数参数,不仅是传引用,传指针,对于传值调用,在函数内对其进行的操作会作用到原对象

四.以上实验的代码

#include <opencv2/opencv.hpp>
#include <iostream>

void myDrawCirle(cv::Mat img)   //传值 
{
	cv::circle(img,cv::Point2i(img.cols/2,img.rows/2),30,cv::Scalar(0,0,255),-1,8);
	cv::imshow("myDrawCircle",img);
	cv::waitKey(3);
}

void myDrawCirle2(cv::Mat &img) //传引用
{
	cv::circle(img,cv::Point2i(img.cols/2,img.rows/2),30,cv::Scalar(0,0,255),-1,8);
	cv::imshow("myDrawCircle2",img);
	cv::waitKey(3);
}
void myDrawCirle3(cv::Mat img)  //clone()
{
	cv::Mat dst=img.clone();
	cv::circle(dst,cv::Point2i(img.cols/2,img.rows/2),30,cv::Scalar(0,0,255),-1,8);
	cv::imshow("myDrawCircle3",dst);
	cv::waitKey(3);
}
void myDrawCirle4(cv::Mat img)  //copyTo
{
	cv::Mat dst;
	img.copyTo(dst);
	cv::circle(dst,cv::Point2i(img.cols/2,img.rows/2),30,cv::Scalar(0,0,255),-1,8);
	cv::imshow("myDrawCircle4",dst);
	cv::waitKey(0);
}
void myDrawCirle5(cv::Mat img)  //赋值运算符
{
	cv::Mat dst=img;
	cv::circle(dst,cv::Point2i(img.cols/2,img.rows/2),30,cv::Scalar(0,0,255),-1,8);
	cv::imshow("myDrawCircle5",dst);
	cv::waitKey(3);
}
void myDrawCirle6(cv::Mat img)   //(拷贝)构造函数
{
	cv::Mat dst(img);
	cv::circle(dst,cv::Point2i(img.cols/2,img.rows/2),30,cv::Scalar(0,0,255),-1,8);
	cv::imshow("myDrawCircle6",dst);
	cv::waitKey(3);
}
int main()
{
	cv::Mat src_1=cv::imread("./小王子1.jpg");
	cv::Mat src_2=cv::imread("./小王子2.jpg");
	cv::Mat src_3=cv::imread("./小王子3.jpg");

	cv::imshow("src_1",src_1);
	cv::imshow("src_2",src_2);
	cv::imshow("src_3",src_3);
	
	myDrawCirle(src_1);         
	cv::imshow("curSrc_1",src_1);

	myDrawCirle2(src_2);
	cv::imshow("curSrc_2",src_2);

	myDrawCirle3(src_3);
	/*myDrawCirle4(src_3);
	myDrawCirle5(src_3);
	myDrawCirle6(src_3);*/
	cv::imshow("curSrc_3",src_3);

	cvWaitKey(0);
	return 0;
}

 

  • 15
    点赞
  • 37
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值