Opencv总结

  • Post author:
  • Post category:其他



目录


一,调用库函数的通用问题


1,const的传递


2,异常


二,Mat的内存管理


1,三种创建Mat对象的方法


2,Mat的拷贝


(1)= 运算符


(2)copyTo函数


(3)clone函数


3,Mat的内存结构


一,调用库函数的通用问题

调用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通道的,不是三通道的。