OpenCV剖析(1)

OpenCV模块介绍

  • Core
  • Image Processing
  • video
  • feature2d
  • objdetect
  • highgui
  • Video I/O
  • GPU

CV_EXPORTS说明

CV_EXPORTS博文连接

saturate_cast

@param v Function parameter.
 @sa add, subtract, multiply, divide, Mat::convertTo
 */
template<typename _Tp> static inline _Tp saturate_cast(uchar v)    { return _Tp(v); }
/** @overload */
template<typename _Tp> static inline _Tp saturate_cast(schar v)    { return _Tp(v); }
/** @overload */
template<typename _Tp> static inline _Tp saturate_cast(ushort v)   { return _Tp(v); }
/** @overload */
template<typename _Tp> static inline _Tp saturate_cast(short v)    { return _Tp(v); }
/** @overload */
template<typename _Tp> static inline _Tp saturate_cast(unsigned v) { return _Tp(v); }
/** @overload */
template<typename _Tp> static inline _Tp saturate_cast(int v)      { return _Tp(v); }
/** @overload */
template<typename _Tp> static inline _Tp saturate_cast(float v)    { return _Tp(v); }
/** @overload */
template<typename _Tp> static inline _Tp saturate_cast(double v)   { return _Tp(v); }
/** @overload */
template<typename _Tp> static inline _Tp saturate_cast(int64 v)    { return _Tp(v); }
/** @overload */
template<typename _Tp> static inline _Tp saturate_cast(uint64 v)   { return _Tp(v); }

template<> inline uchar saturate_cast<uchar>(schar v)        { return (uchar)std::max((int)v, 0); }
template<> inline uchar saturate_cast<uchar>(ushort v)       { return (uchar)std::min((unsigned)v, (unsigned)UCHAR_MAX); }
template<> inline uchar saturate_cast<uchar>(int v)          { return (uchar)((unsigned)v <= UCHAR_MAX ? v : v > 0 ? UCHAR_MAX : 0); }
template<> inline uchar saturate_cast<uchar>(short v)        { return saturate_cast<uchar>((int)v); }
template<> inline uchar saturate_cast<uchar>(unsigned v)     { return (uchar)std::min(v, (unsigned)UCHAR_MAX); }
template<> inline uchar saturate_cast<uchar>(float v)        { int iv = cvRound(v); return saturate_cast<uchar>(iv); }
template<> inline uchar saturate_cast<uchar>(double v)       { int iv = cvRound(v); return saturate_cast<uchar>(iv); }
template<> inline uchar saturate_cast<uchar>(int64 v)        { return (uchar)((uint64)v <= (uint64)UCHAR_MAX ? v : v > 0 ? UCHAR_MAX : 0); }
template<> inline uchar saturate_cast<uchar>(uint64 v)       { return (uchar)std::min(v, (uint64)UCHAR_MAX); }

上述代码节选自

saturate.hpp
可以清楚的看到saturate_cast使用了模板重载以及模板特化技术

CV_8U/CV_8S/CV_16U/CV_16S/CV_32S/CV_32F/CV_64F及相关说明

#define CV_CN_SHIFT   3
#define CV_DEPTH_MAX  (1 << CV_CN_SHIFT)

#define CV_8U   0
#define CV_8S   1
#define CV_16U  2
#define CV_16S  3
#define CV_32S  4
#define CV_32F  5
#define CV_64F  6
#define CV_USRTYPE1 7

#define CV_MAT_DEPTH_MASK       (CV_DEPTH_MAX - 1)
#define CV_MAT_DEPTH(flags)     ((flags) & CV_MAT_DEPTH_MASK)

#define CV_MAKETYPE(depth,cn) (CV_MAT_DEPTH(depth) + (((cn)-1) << CV_CN_SHIFT))
#define CV_MAKE_TYPE CV_MAKETYPE

这里主要对

CV_MAKETYPE

进行说明
比如CV_8U为0,那么CV_8UCX(x=1,2,3,4),计算公式

CV_8UCX = (CV_8U+(X-1)*8)

上述源码中是使用宏定义进行运算

InputArray/OutputArray探究

首先是InputArray/OutputArray的定义,可以看出InputArray/OutputArray是引用类型而且是const,接下来先看_InputArray,之后看_OutputArray,最后再看_InputOutputArray

typedef const _InputArray& InputArray;
typedef InputArray InputArrayOfArrays;
typedef const _OutputArray& OutputArray;
typedef OutputArray OutputArrayOfArrays;
typedef const _InputOutputArray& InputOutputArray;
typedef InputOutputArray InputOutputArrayOfArrays;

_InputArray

在OpenC开篇介绍中对InputArray的介绍就是一种代理(proxy)类,而且是只读的,从上面代码片段也可以看出,const引用,在OpenCV中有这样一段话

where InputArray is a class that can be constructed from Mat, Mat< T>, Matx< T, m, n>, std::vector< T>, std::vector< std::vector< T> >, std::vector< Mat>, std::vector< Mat_< T> >, UMat, std::vector< UMat> or double. It can also be constructed from a matrix expression.

其实在_InputArray类中定义了相应的枚举值表示对应可以代理的类型,OpenCV文档中是有的,这里就不列举出来了

在介绍_InputArray类的构造函数之前必须介绍_InputArray的两个私有成员函数

void init(int _flags, const void* _obj);
void init(int _flags, const void* _obj, Size _sz);

这两个成员函数的定义在mat.inl.hpp中如下:

inline void _InputArray::init(int _flags, const void* _obj)
{ flags = _flags; obj = (void*)_obj; }

inline void _InputArray::init(int _flags, const void* _obj, Size _sz)
{ flags = _flags; obj = (void*)_obj; sz = _sz; }

这里说明一下
- flags表示的为类型,通过阅读源码发现flags=type+ACCESS_READ(type为_InputArray中的枚举值,ACCESS_READ为mat.hpp中定义的枚举值,ACCESS_READ是针对_InputArray而言的,表示只读)
- obj就是具体需要读取的对象,如Mat,Matx,vector<>
- sz一般用于Matx
- 这三个都是私有成员变量

下面只罗列部分构造函数,这些内联构造函数调用init函数进行初始化,有关函数模板的构造函数,这里没有列举

inline _InputArray::_InputArray() { init(NONE, 0); }
inline _InputArray::_InputArray(int _flags, void* _obj) { init(_flags, _obj); }
inline _InputArray::_InputArray(const Mat& m) { init(MAT+ACCESS_READ, &m); }
inline _InputArray::_InputArray(const std::vector<Mat>& vec) { init(STD_VECTOR_MAT+ACCESS_READ, &vec); }
inline _InputArray::_InputArray(const UMat& m) { init(UMAT+ACCESS_READ, &m); }
inline _InputArray::_InputArray(const std::vector<UMat>& vec) { init(STD_VECTOR_UMAT+ACCESS_READ, &vec); }

_InputArray其他成员函数就不再列举,因为大多数的成员函数转换成原本对应的类型,原理都大同小异,首先判断flags,然后定出类型,将obj转换成对应的类型,进行操作

_OutputArray

_OutputArray共有继承_InputArray,首先介绍其构造函数,节选

inline _OutputArray::_OutputArray() { init(ACCESS_WRITE, 0); }
inline _OutputArray::_OutputArray(int _flags, void* _obj) { init(_flags|ACCESS_WRITE, _obj); }
inline _OutputArray::_OutputArray(Mat& m) { init(MAT+ACCESS_WRITE, &m); }
inline _OutputArray::_OutputArray(std::vector<Mat>& vec) { init(STD_VECTOR_MAT+ACCESS_WRITE, &vec); }
inline _OutputArray::_OutputArray(UMat& m) { init(UMAT+ACCESS_WRITE, &m); }
inline _OutputArray::_OutputArray(std::vector<UMat>& vec) { init(STD_VECTOR_UMAT+ACCESS_WRITE, &vec); }

可以看出其构造函数调用了父类的init函数只是flags=type+ACCESS_WRITE

_OutputArray中getXXX函数返回的是obj的引用,而_InputArray返回的不是引用,
同时_OutputArray新增的一些成员函数,也主要是对obj成员进行操作,即可以更改obj中的数据
总而言之_OutputArray提供了对obj成员进行改变的一系列成员函数

_InputOutputArray

_InputOutputArray公有继承自_OutputArray,它本身没有增加新的成员函数,定义了一系列构造函数,构造函数实现方式和_OutputArray类似,调用init函数,这里需要注意的是flags=type+ACCESS_RW这里ACCESS_RW表示可读写
其他没有太大变化

猜你喜欢

转载自blog.csdn.net/sinat_23185975/article/details/79708767