综述
该目的是函数的形参类型基于实际情况而定,不需要传入指针等情况
InputArray
- 其中 _InputArray 是一个类,可以从
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>
或double
。它也可以从矩阵表达式构造。 - 可选输入参数:如果某些输入数组可能为空,则传递
cv::noArray()
(或者像您之前所做的那样简单地传递cv::Mat()
)。 - 该类仅用于传递参数。也就是说,通常你 不应该 声明这种类型的类成员、局部和全局变量。
- 如果您想设计自己的函数或类方法,可以操作多种类型的数组,您可以使用 InputArray(或 OutputArray)作为相应的参数。在函数内部,您应该使用 _InputArray::getMat() 方法为数组构造矩阵头(不复制数据)。
class CV_EXPORTS _InputArray
{
public:
enum KindFlag {
KIND_SHIFT = 16,
FIXED_TYPE = 0x8000 << KIND_SHIFT,
FIXED_SIZE = 0x4000 << KIND_SHIFT,
KIND_MASK = 31 << KIND_SHIFT,
NONE = 0 << KIND_SHIFT,
MAT = 1 << KIND_SHIFT,
MATX = 2 << KIND_SHIFT,
STD_VECTOR = 3 << KIND_SHIFT,
STD_VECTOR_VECTOR = 4 << KIND_SHIFT,
STD_VECTOR_MAT = 5 << KIND_SHIFT,
#if OPENCV_ABI_COMPATIBILITY < 500
EXPR = 6 << KIND_SHIFT, //!< removed: https://github.com/opencv/opencv/pull/17046
#endif
OPENGL_BUFFER = 7 << KIND_SHIFT,
CUDA_HOST_MEM = 8 << KIND_SHIFT,
CUDA_GPU_MAT = 9 << KIND_SHIFT,
UMAT =10 << KIND_SHIFT,
STD_VECTOR_UMAT =11 << KIND_SHIFT,
STD_BOOL_VECTOR =12 << KIND_SHIFT,
STD_VECTOR_CUDA_GPU_MAT = 13 << KIND_SHIFT,
#if OPENCV_ABI_COMPATIBILITY < 500
STD_ARRAY =14 << KIND_SHIFT, //!< removed: https://github.com/opencv/opencv/issues/18897
#endif
STD_ARRAY_MAT =15 << KIND_SHIFT
};
_InputArray();
_InputArray(int _flags, void* _obj);
_InputArray(const Mat& m);
_InputArray(const MatExpr& expr);
_InputArray(const std::vector<Mat>& vec);
template<typename _Tp> _InputArray(const Mat_<_Tp>& m);
template<typename _Tp> _InputArray(const std::vector<_Tp>& vec);
_InputArray(const std::vector<bool>& vec);
template<typename _Tp> _InputArray(const std::vector<std::vector<_Tp> >& vec);
_InputArray(const std::vector<std::vector<bool> >&) = delete; // not supported
template<typename _Tp> _InputArray(const std::vector<Mat_<_Tp> >& vec);
template<typename _Tp> _InputArray(const _Tp* vec, int n);
template<typename _Tp, int m, int n> _InputArray(const Matx<_Tp, m, n>& matx);
_InputArray(const double& val);
_InputArray(const cuda::GpuMat& d_mat);
_InputArray(const std::vector<cuda::GpuMat>& d_mat_array);
_InputArray(const ogl::Buffer& buf);
_InputArray(const cuda::HostMem& cuda_mem);
template<typename _Tp> _InputArray(const cudev::GpuMat_<_Tp>& m);
_InputArray(const UMat& um);
_InputArray(const std::vector<UMat>& umv);
template<typename _Tp, std::size_t _Nm> _InputArray(const std::array<_Tp, _Nm>& arr);
template<std::size_t _Nm> _InputArray(const std::array<Mat, _Nm>& arr);
template<typename _Tp> static _InputArray rawIn(const std::vector<_Tp>& vec);
template<typename _Tp, std::size_t _Nm> static _InputArray rawIn(const std::array<_Tp, _Nm>& arr);
Mat getMat(int idx=-1) const;
Mat getMat_(int idx=-1) const;
UMat getUMat(int idx=-1) const;
void getMatVector(std::vector<Mat>& mv) const;
void getUMatVector(std::vector<UMat>& umv) const;
void getGpuMatVector(std::vector<cuda::GpuMat>& gpumv) const;
cuda::GpuMat getGpuMat() const;
ogl::Buffer getOGlBuffer() const;
int getFlags() const;
void* getObj() const;
Size getSz() const;
_InputArray::KindFlag kind() 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 sizend(int* sz, int i=-1) const;
bool sameSize(const _InputArray& arr) const;
size_t total(int i=-1) const;
int type(int i=-1) const;
int depth(int i=-1) const;
int channels(int i=-1) const;
bool isContinuous(int i=-1) const;
bool isSubmatrix(int i=-1) const;
bool empty() const;
void copyTo(const _OutputArray& arr) const;
void copyTo(const _OutputArray& arr, const _InputArray & mask) const;
size_t offset(int i=-1) const;
size_t step(int i=-1) const;
bool isMat() const;
bool isUMat() const;
bool isMatVector() const;
bool isUMatVector() const;
bool isMatx() const;
bool isVector() const;
bool isGpuMat() const;
bool isGpuMatVector() const;
~_InputArray();
protected:
int flags;
void* obj;
Size sz;
void init(int _flags, const void* _obj);
void init(int _flags, const void* _obj, Size _sz);
};
OutputArray
- 该类型与 InputArray 非常相似,只是它用于输入/输出和输出函数参数。
- 该类型基本都是引用 ,毕竟要作为输出使用
class CV_EXPORTS _OutputArray : public _InputArray
{
public:
enum DepthMask
{
DEPTH_MASK_8U = 1 << CV_8U,
DEPTH_MASK_8S = 1 << CV_8S,
DEPTH_MASK_16U = 1 << CV_16U,
DEPTH_MASK_16S = 1 << CV_16S,
DEPTH_MASK_32S = 1 << CV_32S,
DEPTH_MASK_32F = 1 << CV_32F,
DEPTH_MASK_64F = 1 << CV_64F,
DEPTH_MASK_16F = 1 << CV_16F,
DEPTH_MASK_ALL = (DEPTH_MASK_64F<<1)-1,
DEPTH_MASK_ALL_BUT_8S = DEPTH_MASK_ALL & ~DEPTH_MASK_8S,
DEPTH_MASK_ALL_16F = (DEPTH_MASK_16F<<1)-1,
DEPTH_MASK_FLT = DEPTH_MASK_32F + DEPTH_MASK_64F
};
_OutputArray();
_OutputArray(int _flags, void* _obj);
_OutputArray(Mat& m);
_OutputArray(std::vector<Mat>& vec);
_OutputArray(cuda::GpuMat& d_mat);
_OutputArray(std::vector<cuda::GpuMat>& d_mat);
_OutputArray(ogl::Buffer& buf);
_OutputArray(cuda::HostMem& cuda_mem);
template<typename _Tp> _OutputArray(cudev::GpuMat_<_Tp>& m);
template<typename _Tp> _OutputArray(std::vector<_Tp>& vec);
_OutputArray(std::vector<bool>& vec) = delete; // not supported
template<typename _Tp> _OutputArray(std::vector<std::vector<_Tp> >& vec);
_OutputArray(std::vector<std::vector<bool> >&) = delete; // not supported
template<typename _Tp> _OutputArray(std::vector<Mat_<_Tp> >& vec);
template<typename _Tp> _OutputArray(Mat_<_Tp>& m);
template<typename _Tp> _OutputArray(_Tp* vec, int n);
template<typename _Tp, int m, int n> _OutputArray(Matx<_Tp, m, n>& matx);
_OutputArray(UMat& m);
_OutputArray(std::vector<UMat>& vec);
_OutputArray(const Mat& m);
_OutputArray(const std::vector<Mat>& vec);
_OutputArray(const cuda::GpuMat& d_mat);
_OutputArray(const std::vector<cuda::GpuMat>& d_mat);
_OutputArray(const ogl::Buffer& buf);
_OutputArray(const cuda::HostMem& cuda_mem);
template<typename _Tp> _OutputArray(const cudev::GpuMat_<_Tp>& m);
template<typename _Tp> _OutputArray(const std::vector<_Tp>& vec);
template<typename _Tp> _OutputArray(const std::vector<std::vector<_Tp> >& vec);
template<typename _Tp> _OutputArray(const std::vector<Mat_<_Tp> >& vec);
template<typename _Tp> _OutputArray(const Mat_<_Tp>& m);
template<typename _Tp> _OutputArray(const _Tp* vec, int n);
template<typename _Tp, int m, int n> _OutputArray(const Matx<_Tp, m, n>& matx);
_OutputArray(const UMat& m);
_OutputArray(const std::vector<UMat>& vec);
template<typename _Tp, std::size_t _Nm> _OutputArray(std::array<_Tp, _Nm>& arr);
template<typename _Tp, std::size_t _Nm> _OutputArray(const std::array<_Tp, _Nm>& arr);
template<std::size_t _Nm> _OutputArray(std::array<Mat, _Nm>& arr);
template<std::size_t _Nm> _OutputArray(const std::array<Mat, _Nm>& arr);
template<typename _Tp> static _OutputArray rawOut(std::vector<_Tp>& vec);
template<typename _Tp, std::size_t _Nm> static _OutputArray rawOut(std::array<_Tp, _Nm>& arr);
bool fixedSize() const;
bool fixedType() const;
bool needed() const;
Mat& getMatRef(int i=-1) const;
UMat& getUMatRef(int i=-1) const;
cuda::GpuMat& getGpuMatRef() const;
std::vector<cuda::GpuMat>& getGpuMatVecRef() const;
ogl::Buffer& getOGlBufferRef() const;
cuda::HostMem& getHostMemRef() const;
void create(Size sz, int type, int i=-1, bool allowTransposed=false, _OutputArray::DepthMask fixedDepthMask=static_cast<_OutputArray::DepthMask>(0)) const;
void create(int rows, int cols, int type, int i=-1, bool allowTransposed=false, _OutputArray::DepthMask fixedDepthMask=static_cast<_OutputArray::DepthMask>(0)) const;
void create(int dims, const int* size, int type, int i=-1, bool allowTransposed=false, _OutputArray::DepthMask fixedDepthMask=static_cast<_OutputArray::DepthMask>(0)) const;
void createSameSize(const _InputArray& arr, int mtype) const;
void release() const;
void clear() const;
void setTo(const _InputArray& value, const _InputArray & mask = _InputArray()) const;
void assign(const UMat& u) const;
void assign(const Mat& m) const;
void assign(const std::vector<UMat>& v) const;
void assign(const std::vector<Mat>& v) const;
void move(UMat& u) const;
void move(Mat& m) const;
};
案例
cv::Mat
中.at<类型>(行,列)
取对应数据
Code
void PointCvMat(const cv::Mat& mat,const std::string& head_str = "") {
std::cout<<head_str<<" data: \n"<<mat<<std::endl;
}
void ComputeL_6x4(double * l_6x4) {
for(int i=0;i<6;i++) {
double * row = l_6x4 + 4 * i;
row[0] = i * 10 + 0;
row[1] = i * 10 + 1;
row[2] = i * 10 + 2;
row[3] = i * 10 + 3;
}
}
void TestChangeL(cv::InputArray _src,cv::OutputArray _dst) {
cv::Mat src = _src.getMat();
_dst.createSameSize(_src,src.type());
cv::Mat dst = _dst.getMat();
int rows = src.rows,cols = src.cols;
CHECK_EQ(src.rows,dst.rows);
CHECK_EQ(src.cols,dst.cols);
LOG(INFO)<<"r:"<<rows<<" c:"<<cols;
for(int i =0; i< rows;i++) {
for(int j =0; j< cols;j++) {
dst.at<double>(rows-1-i,cols-1 -j) = src.at<double>(i,j);
}
}
}
TEST(FunctionTest,cvMatTest1) {
double l_6x4[6 * 4], b4[4] = {0};
cv::Mat L_6x41,L_6x4 = cv::Mat(6, 4, CV_64F, l_6x4);
cv::Mat B4 = cv::Mat(4, 1, CV_64F, b4);
PointCvMat(L_6x4,"front");
std::cout<<"------------------"<<std::endl;
L_6x4.setTo(0);
PointCvMat(L_6x4,"set_zero");
std::cout<<"------------------"<<std::endl;
ComputeL_6x4(l_6x4);
PointCvMat(L_6x4,"back ");
std::cout<<"------------------"<<std::endl;
TestChangeL(L_6x4,L_6x41);
PointCvMat(L_6x41,"TestChange ");
std::cout<<"------------------"<<std::endl;
}