目录
一,调用库函数的通用问题
调用Opencv的库函数,有一些和调用其他库函数相同的问题:
1,const的传递
如果库函数使用的参数是非const的,那么调用者都是非const的,
这会沿着参数的传递链进行传递,除非有一层使用拷贝,再往上层才能变成const调用。
2,异常
有些异常Opencv会捕获再往上抛出异常,需要调用代码来处理。
3,Array
很多函数的入参都是InputArray、utputArray、InputOutputArray,只看函数签名无法判断是不是const入参。
二,Mat的内存管理
1,三种创建Mat对象的方法
Mat image1;
Mat image2(500, 500, CV_8U);
char ch[100];
Mat image3(10, 10, CV_8U, ch);
第一种创建空Mat不会分配内存,第二种创建对象并分配内存,第三种根据给定内存创建对象。
2,Mat的拷贝
(1)= 运算符
直接把data指针拷贝过来,不拷贝数据。参见
Opencv源码解析
(2)copyTo函数
copyTo在各种场景下都是深拷贝。
场景一,目标Mat是空的
int main()
{
Mat img = Mat(10,10, CV_8U);
Mat img2;
img.copyTo(img2);
return 0;
}
这种情况下会调用create函数给目标Mat分配内存。
PS:如果源是空的,或者源和目标都是空的,运行貌似没问题。
场景二,源和目标尺寸一致
int main()
{
Mat img = Mat(10, 10, CV_8U);
uchar ch[100];
Mat img2(10, 10, CV_8U, ch);
img.copyTo(img2);
if (img2.data == ch)cout << "data ptr not changed";
else cout << "data ptr changed";
return 0;
}
输出:data ptr not changed
说明拷贝的时候,img2的data指针并没有改变。
场景三,源比目标的尺寸不一致
第一行改成
Mat img = Mat(10, 11, CV_8U);
输出:data ptr changed
这种情况下会调用create函数给目标Mat分配内存。
改成其他各种尺寸也都试过了,只要不是行和列都一样,都会重新分配内存。
(3)clone函数
opencv\opencv-4.2.0\modules\core\include\opencv2\core\mat.inl.hpp中的源代码:
inline
Mat Mat::clone() const
{
Mat m;
copyTo(m);
return m;
}
直接调用copyTo做一个深拷贝。
3,Mat的内存结构
Mat中存放的是一个二维或多维数组,维度之间是有唯一顺序的,满足如下规律:
对于2维数组,每一行都是连续的,行和行之间可能不连续,但是他们的首地址一定是等间距的。
对于n(n>2)维数组,其实就是若干个n-1维数组组合而成,这些数组都递归满足本规律,这些数组的首地址一定是等间距的。
间距信息保存在step数组中,利用他可以实现所有元素的随机访问、几乎不耗时间的截取操作。
三,关于图片格式
jpg是有损压缩,png是无损压缩。
png彩色图像是4通道的,不是三通道的。