如何使用opencv中的OutputArray来接受Mat和vector<Mat>

引入

直接上栗子.
现在我需要实现这个函数:

bool generate(cv::String input,cv::OutputArray  output)

即根据一个input产生相应的Mat.
然而,产生的数量我们不能确定,可能是只需要一张Mat,也就是外边的调用如下:

Mat result;
generate(input,result)

或者是,我们可能需要产生的所有Mat:

vector<Mat> result;
generate(input,result)

那么问题来了我们应该如何让OutputArray自动知道我们输入的类型是什么呢?

步骤

1.判断OutputArray类型

只需要调用以下语句便可以知道类型信息:

int output_type = output.kind();

然后结合下边关于OutputArray类型信息的表,进行你希望的操作:

enum {
        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,//!65536
        MATX              = 2 << KIND_SHIFT,//!
        STD_VECTOR        = 3 << KIND_SHIFT,//!196608
        STD_VECTOR_VECTOR = 4 << KIND_SHIFT,//!262144
        STD_VECTOR_MAT    = 5 << KIND_SHIFT,//!327680
        EXPR              = 6 << KIND_SHIFT,//!393216
        OPENGL_BUFFER     = 7 << KIND_SHIFT,//!458752
        CUDA_HOST_MEM     = 8 << KIND_SHIFT,//!524288
        CUDA_GPU_MAT      = 9 << KIND_SHIFT,//!589824
        UMAT              =10 << KIND_SHIFT,//!655360
        STD_VECTOR_UMAT   =11 << KIND_SHIFT,//!720896
        STD_BOOL_VECTOR   =12 << KIND_SHIFT //!786432
    };

我这里只需要进行判断STD_VECTOR_MATMAT,so

if(output_type == _InputArray::STD_VECTOR_MAT){
	...
    }
    else if(output_type == _InputArray::MAT){
	...
    }

2.Mat赋值

很简单,没什么技术含量

 output.assign(the_mat_you_need);

3.vector<Mat>赋值

稍微复杂一些:
首先,为你的output先预留好内存空间

/**size(vector的大小) ,1(具体我也不清楚), type(其中Mat的类型) */
output.create(result.size(), 1, result[0].type());

然后,建立一个实际vector

        /**get vector*/
        std::vector<Mat> dst;
        output.getMatVector(dst);

最后,逐个导入

        for(size_t i = 0 ; i < result.size() ; i ++ ){
            Mat cur_mat = result[i];
            output.getMatRef(i) =cur_mat;
        }

总体代码

如下:

bool QRCodeEncoder::generate(cv::String input,cv::OutputArray  output,int mode,
              int version, int correction_level ,
              int mask_type , int structure_number  ){
    int output_type = output.kind();

    QREncoder my_qrcode(input,mode,version,correction_level,mask_type,-1,structure_number);
    if(my_qrcode.my_qrcodes.size() == 0)
        return false;

    vector<Mat> result = my_qrcode.my_qrcodes;
    if(output_type == _InputArray::STD_VECTOR_MAT){
        /**vector size*/
        output.create(result.size(), 1, result[0].type());
        /**get vector*/
        std::vector<Mat> dst;
        output.getMatVector(dst);

        for(size_t i = 0 ; i < result.size() ; i ++ ){
            Mat cur_mat = result[i];
            output.getMatRef(i) =cur_mat;
        }
    }
    else if(output_type == _InputArray::MAT){
        output.assign(my_qrcode.my_qrcodes[0]);
    }
    return true;
}

也是我尝试的结果,内在原理不是很明白,希望各位批评指正!

参考资料:

https://qiita.com/fukushima1981/items/9bba9327c1d62779c7a4

©️2020 CSDN 皮肤主题: 1024 设计师:上身试试 返回首页