编写接受cv :: Mat或cv :: UMat类型输入的模板函数

时间:2018-09-05 08:13:36

标签: c++ opencv templates mat

编写接受Mat或UMat类型的输入参数的函数的最简单,最简洁的方法是什么?

我应该使用InputArray,使用模板还是有更好的选择?我非常想为Mat和UMat编写具有相同实现的函数。

该函数应充分利用UMat抽象(优于OpenCL),并且运行速度与仅为UMat编写的速度大致相同,并且不必将UMats复制到Mats。

以下是我想为Mat和UMat定义的函数示例(请不要提出重构以删除本地Mat / UMat变量,这只是一个示例)

using namespace cv;    

void foo(const Mat & in1, const Mat & in2, Mat & out)
{
    Mat aux1;
    Mat aux2;
    exp(in1, aux1);
    exp(in2, aux2);
    add(aux1, aux2, out);
    return;
}

void foo(const UMat & in1, const UMat & in2, UMat & out)
{
    UMat aux1;
    UMat aux2;
    exp(in1, aux1);
    exp(in2, aux2);
    add(aux1, aux2, out);
    return;
}

2 个答案:

答案 0 :(得分:2)

在@Miki和@Gianni的建议下,我们可以为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.的常规模板类型选择InpputArray and OutputArray

void func(InputArray _src1, InputArray _src2, OutputArray _dst)
{
    Mat src1 = _src1.getMat(), src2 = _src2.getMat();
    CV_Assert( src1.type() == src2.type() && src1.size() == src2.size());
    Mat aux1 = Mat(src1.size(), src1.type());
    Mat aux2 = Mat(src1.size(), src1.type());
    cv::exp(src1, aux1);
    cv::exp(src2, aux2);

    _dst.create(src1.size(), src1.type());
    Mat dst = _dst.getMat();
    cv::add(aux1, aux2, dst);
}

现在您可以使用MatUMat甚至std::vector来进行测试

int test(){
    std::vector<float> vec1 = {1,2,3};
    std::vector<float> vec2 = {3,2,1};
    std::vector<float> dst;

    func(vec1, vec2, dst);
    // now dst is [22.8038, 14.7781, 22.8038]

}

答案 1 :(得分:0)

我使用了一个模板:

using namespace cv;    

// MatType is either cv::Mat or cv::UMat.
template<typename MatType>
void foo(const MatType& in1, const MatType& in2, MatType& out)
{
    MatType aux1;
    MatType aux2;
    exp(in1, aux1);
    exp(in2, aux2);
    add(aux1, aux2, out);
    return;
}

优势:

  • 根据输入类型轻松声明本地MatUMat
  • 没有MatUMat转换。

缺点:

  • 所有矩阵参数必须具有相同的类型,不能混用MatUMat