这是将只读输入数组传递到OpenCV函数的代理类。
它被定义为:
typedef const _InputArray& InputArray ;
_InputArray是由Mat、Mat_
该类仅用于传递参数。也就是说,通常不应该声明该类的类成员、局部变量和全局变量。
首先需要说明的是_InputArray在mat.hpp文件中定义,对应接口的实现包括两个文件mat.inl.hpp和matrix_wrap.cpp,mat.inl.hpp是一些内联函数,而其他非内联接口则在matrix_wrap.cpp中实现。
(1)成员
int flags; |
对应KindFlag枚举,标识输入对象的类型 |
void* obj; |
输入对象的指针 |
Size sz; |
|
(2)接口
_InputArray (int _flags, void *_obj) |
_InputArray (const Mat &m) |
_InputArray (const std::vector< Mat > &vec) |
_InputArray (const UMat &um) |
int channels (int i=-1) const |
Mat getMat(int idx=-1) const; |
void getMatVector(std::vector |
cuda::GpuMat getGpuMat() const; |
ogl::Buffer getOGlBuffer() const; |
int getFlags() const; |
void* getObj() const; |
Size getSz() const; |
int dims(int i=-1) const; |
int cols(int i=-1) const; |
int rows(int i=-1) const; |
Size size(int i=-1) const; |
int depth(int i=-1) const; |
bool empty() const; |
void copyTo(const _OutputArray& arr) const; |
bool isMat() const; |
bool isVector() const; |
(3)接口实现说明
构造接口:
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; }
inline _InputArray::_InputArray() { init(0 + NONE, 0); }
inline _InputArray::_InputArray(const Mat& m) { init(MAT+ACCESS_READ, &m); }
inline _InputArray::_InputArray(const std::vector& vec) { init(STD_VECTOR_MAT+ACCESS_READ, &vec); }
template inline
_InputArray::_InputArray(const std::vector<_Tp>& vec)
{ init(FIXED_TYPE + STD_VECTOR + traits::Type<_Tp>::value + ACCESS_READ, &vec); }
inline bool _InputArray::isMat() const { return kind() == _InputArray::MAT; }
其他接口:
int _InputArray::type(int i) const
{
。。。
if( k == STD_VECTOR_MAT )
{
。。。
return vv[i >= 0 ? i : 0].type();
}
。。。
return obj->type();
}
如果类型为集合类型,则i可以传入指定的序号,type接口返回的就是指定序号对象的类型。
int _InputArray::channels(int i) const
{
return CV_MAT_CN(type(i));
}
相关宏定义如下:
#define CV_CN_MAX 512
#define CV_CN_SHIFT 3
#define CV_DEPTH_MAX (1 << CV_CN_SHIFT)
#define CV_MAT_CN_MASK ((CV_CN_MAX - 1) << CV_CN_SHIFT)
#define CV_MAT_CN(flags) ((((flags) & CV_MAT_CN_MASK) >> CV_CN_SHIFT) + 1)
假设对象为Mat,Mat的type接口定义如下:
The method returns a matrix element type. This is an identifier compatible with the CvMat type system, like CV_16SC3 or 16-bit signed 3-channel array, and so on.
int type() const;
Mat的type接口的实现如下:
inline int Mat::type() const
{
return CV_MAT_TYPE(flags);
}
#define CV_MAT_TYPE_MASK (CV_DEPTH_MAX*CV_CN_MAX - 1)
#define CV_MAT_TYPE(flags) ((flags) & CV_MAT_TYPE_MASK)
flags在构造函数赋值:
inline Mat::Mat(): flags(MAGIC_VAL), dims(0), rows(0), cols(0), data(0), datastart(0), dataend(0),datalimit(0), allocator(0), u(0), size(&rows), step(0)
{}
enum { MAGIC_VAL = 0x42FF0000, AUTO_STEP = 0, CONTINUOUS_FLAG = CV_MAT_CONT_FLAG, SUBMATRIX_FLAG = CV_SUBMAT_FLAG };
则_InputArray::channels返回结果:
=(((((( MAGIC_VAL) & CV_MAT_TYPE_MASK)) & CV_MAT_CN_MASK) >> CV_CN_SHIFT) + 1)
返回的结果代表什么暂时不清楚。
使用2x3矩阵作为Matx
std::vector vec;
// points or a circle
for( int i = 0; i < 30; i++ )
vec.push_back(Point2f((float)(100 + 30*cos(i*CV_PI*2/5)),
(float)(100 - 30*sin(i*CV_PI*2/5))));
cv::transform(vec, vec, cv::Matx23f(0.707, -0.707, 10, 0.707, 0.707, 20));
void myAffineTransform(InputArray _src, OutputArray _dst, InputArray _m)
{
// get Mat headers for input arrays. This is O(1) operation,
// unless _src and/or _m are matrix expressions.
Mat src = _src.getMat(), m = _m.getMat();
CV_Assert( src.type() == CV_32FC2 && m.type() == CV_32F && m.size() == Size(3, 2) );
// [re]create the output array so that it has the proper size and type.
// In case of Mat it calls Mat::create, in case of STL vector it calls vector::resize.
_dst.create(src.size(), src.type());
Mat dst = _dst.getMat();
for( int i = 0; i < src.rows; i++ )
for( int j = 0; j < src.cols; j++ )
{
Point2f pt = src.at(i, j);
dst.at(i, j) = Point2f(m.at(0, 0)*pt.x +
m.at(0, 1)*pt.y +
m.at(0, 2),
m.at(1, 0)*pt.x +
m.at(1, 1)*pt.y +
m.at(1, 2));
}
}
cv::_OutputArray与cv::_InputArray相似,只是用于输出。