机器视觉算法(第7期)----OpenCV中很重要的辅助对象

原创
2019/03/29 08:00
阅读数 53

上期我们一起学习了OpenCV中常用的数据类型,
机器视觉算法(第6期)----OpenCV中的基础数据类型
今天我们主要认识一下OpenCV中很重要的几个辅助对象。

1. TermCriteria类

在OpenCV中的很多算法都需要一个终止条件以确定何时退出。通常终止条件的形式要么是达到允许的有限迭代次数(称为COUNT或MAX_ITER),要么是某种形式的误差参数(如果接近于如此程度,就可以退出,称为EPS,即epsilon的简称)。在程序中,可以通过TermCriteria的公有变量来设置,当然,最常用的是通过他的构造函数进行设置。

TermCriteria( int type, int maxCount, double epsilon )

其中type设置为COUNT或EPS,也可以同时使用(用|连接)。设置过type之后,还需要设置相应的maxCount或epsilon。

2. Range类

Range类用于确定一个连续的整数序列,Range对象有两个元素start和end,跟上面的TermCriteria相似,通常在构造函数中设置。

cv::Range( int start, int end )

这个Range的范围包括初始值start,但不包括终止值end。该类中有两个成员函数,一个是empty()用来测试一个range是否为空,另一个是all(),用来获取对象的可用范围。

3. Ptr模板和垃圾收集

我们知道智能指针是C++中一个非常有用类型。这个指针允许我们创建一个对象的引用,然后把它传递到世界各地,可以创建更多的对该对象的引用,然后这些引用都会被计数,当引用超出作用范围的时候,智能指针的引用计数就会减少,一旦所有的引用都消失,那么这个对象就会自动清理释放。而作为程序员的我们,不必去记录这些东西。
接下来,我们了解下它的工作原理。首先,我们需要对想要封装的类对象定义一个指针模板的实例。可以通过如下调用实现:

cv::Ptr<Matx33f> p( new cv::Matx33f ) 
or
cv::Ptr<Matx33f> p = makePtr<cv::Matx33f>()

实现之后,就拥有一个智能指针p,可以当做标准指针来用比如支持操作符*和->等。一旦我们得到p,就可以创建其他相同类型的对象了,而不需要把一个指向新对象的指针传递给他们。
举个例子,比如像创建一个Ptr<Matx33f> q,当你把p的值传递给q时,在后台的某个地方,智能指针就开始计数了。你可以像正常指针一样使用,但是这里实际上仍然只存在一个Mat33f实例,p和q同时指向它。当p超出生命周期被释放后,q就知道它是原始矩阵仅存的引用了,这个时候如果q的生命周期也结束的时候,就会去释放原始矩阵。有点类似于教室里最后一个同学离开的时候要关门关灯一样。
cv::Ptr()<>模板类有一些成员函数可以了解下:
addref()和release()增加和减少指针内部的引用计数(慎用)。
empty()函数,用来确定一个智能指针是否指向一个已经被释放掉的对象。
delete_obj()函数,这个函数是当引用清零之后自动调用,自定义类型的时候需要重载,用来释放对象的。
下面我们来通过一个例子来学习一下智能指针的应用。
这里我们创建一个指向FILE的智能指针,这里需要为Ptr<FILE>模板重载delete_obj()函数。

template<> inline void cv::Ptr<FILE>::delete_obj() 
{
fclose(obj);
}

接下来就可以使用这个指针做一些操作,而在离开范围的时候,不用自己去释放,如下:

{
cv::Ptr<FILE> f(fopen("myfile.txt", "r"));
if(f.empty())
throw ...; // Throw an exception, we will get to this later on...
fprintf(f, ...);
...
}

也就是说在最后的大括号,f离开作用范围,f内部的引用计数变为0,delete_obj()被f的析构函数调用,自动释放内存。

4. Exception类和异常处理

OpenCV用异常来处理错误,OpenCV定义了自己的异常类cv::Exception,它继承自STL的std::exception。Exception类型有成员code,err,func,file和line,分别指一个数字对应的错误代码,对应产生异常错误的字符串,错误发生的函数名,错误发生的文件和错误出现在文件中的行数。err,func和file都是STL字符串。
有几个内置的宏,用于自己生成异常。CV_Error(errorcode, description)会生成并抛出一个有固定文字描述的异常,CV_Assert(condition)和CV_DbgAssert(condition)都会测试程序中所设定的条件,如果条件不符合,则抛出异常。这些宏是抛出异常的首选方法,因为它们会自动为你处理函数,文件和行。

5. DataType<>模板

当OpenCV库函数需要传递特定数据类型的概念时,它们会创建一个DataType<>类型的对象,DataType<>本身是一个模板,传递的实际对象是这个模板的特化。

6. InputArray类和OutputArray类

许多OpenCV的函数都把数组作为变量并把数组作为返回值,但是在OpenCV中有各种各样的数组。我们已经了解到OpenCV支持一些小的数组类型,比如:Scalar,Vec,Matx,还有std::vector<>和后面讲讨论的大型数组(Mat和SparseMat),为了防止接口变得复杂,OpenCV定义了InputArray类和OutputArray类,它们表示“上面的任何一个”。
其实,InputArray和OutputArray之间的区别主要在于前者假设为常量(只读),后面的是变量。与InputArray相关的是特殊函数noArray(),它的返回值可以被用在任何需要InputArray的地方,以强调输入的是并没有被使用的输入量,有些函数有可选的输出数组,当不需要对应的输出时,可以传递noArray()


智能算法,与您携手,沉淀自己,引领AI! 


本文分享自微信公众号 - 智能算法(AI_Algorithm)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。

展开阅读全文
打赏
0
0 收藏
分享
加载中
更多评论
打赏
0 评论
0 收藏
0
分享
返回顶部
顶部