目录
一、感兴趣区域
可以使用感兴趣区域(Region of Interest,ROI)来截取图像的特定区域。减少不必要的图片信息,减少数据运算量
1.1 源码
Rect(_Tp _x,_Tp _y,_Tp _width,_Tp _height)
cv::Range::Range ( int _start,
int _end
)
_ Tp _ x和_Tp _y:代表矩形左上角坐标
_width:对应图片宽度也就是像素矩阵的列数
_height:对应图片高度也就是像素矩阵的行数
二、深拷贝和浅拷贝
2.1 定义:
创建Mat类时,除了图片数据本身,还创建了一个矩阵头,里面存放了一些图像信息,如下图:
引用次数代表了这个图像被引用了几次,假设已经读取了一张图片img,如下所示引用次数则为2:
Mat a = img;
Mat b = img;
每当你创建一个矩阵对象并将其赋值给其他变量时,引用计数会增加。当你销毁或重新分配矩阵对象时,引用计数会减少。引用计数的主要目的是在确保内存安全的同时,实现高效的内存管理。
-
当你将一个矩阵对象赋值给另一个变量时,新的变量会共享相同的矩阵数据,引用计数会增加。这意味着你可以使用多个变量来访问和操作相同的矩阵,而不需要进行显式的数据复制。
-
当引用计数为零时,表示没有任何变量引用矩阵数据,该数据将被释放,内存将被回收。
-
当引用计数不为零时,矩阵数据将继续存在于内存中,直到最后一个引用变量被销毁或重新分配给其他对象。
所以当我改变Mat图像里的数据时,所有指向该数据的对象都会被改变,这就是浅拷贝。
深拷贝就是创建变量是分配新的内存用于存储数据,因此原数据和深拷贝后的数据的地址是不同的,改变其中一个,另外一个并不会变化。
2.2 源码
void cv::Mat::copyTo ( OutputArray m ) const
void cv::Mat::copyTo ( OutputArray m,
InputArray mask
) const
//img.copyTo(outarry);
void cv::copyTo ( InputArray src,
OutputArray dst,
InputArray mask
)
三种都是深拷贝,只是使用方式不同,前两Mat类内的成员方法,另外一种则是直接将输出图像放在CV命名空间中
-
mask:掩码矩阵,掩码矩阵内像素为0的地方被舍弃,不为0的地方则保留,其数据类型只能是CV_8U,可以是单通道或者多通道,需要与原图像有相同尺寸
int main()
{
Mat img = imread("E:\\学习\\OPEN-CV学习\\lena.png");
if (img.empty())
{
cout << "can not open picture" << endl;
}
Mat img1 = imread("E:\\学习\\OPEN-CV学习\\1.jpg");
Mat smallpic,copy_qian, copy_depth, copy_depth1;
resize(img1, smallpic, Size(200, 200));
copy_qian = img1;//浅拷贝
//深拷贝
smallpic.copyTo(copy_depth);
copyTo(smallpic, copy_depth1, smallpic);
Mat RIO1, RIO2;
//截取感兴趣区域的两种方式
Rect rect(100, 100, 1500, 1000);
RIO1 = img1(rect);
RIO2 = img1(Range(200, 1550), Range(200,1300));
waitKey(1);
return 0;
}
截取图像示意:
左边为RIO1,右边为RIO2