一.前言
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;
}