编写接受类型 cv::Mat 或 cv::UMat 输入的模板函数
Writing template functions accepting inputs of type cv::Mat or cv::UMat
编写接受 Mat 或 UMat 类型输入参数的函数的最简单、最干净的方法是什么?
我应该使用 InputArray、模板还是有更好的选择?我目前拥有为 Mat 和 UMat 编写的具有相同实现的函数。
该函数应充分利用 OpenCL 上的 UMat 抽象,并且 运行 大致与专为 UMats 编写一样快,并且没有必须将 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;
}
@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);
}
现在您可以使用 Mat
或 UMat
甚至 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]
}
我使用了模板:
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;
}
优点:
- 很容易根据输入类型声明本地
Mat
s 或 UMat
s。
- 没有
Mat
⟷ UMat
转换。
缺点:
- 所有矩阵参数必须是同一类型,不能混合使用
Mat
和 UMat
。
编写接受 Mat 或 UMat 类型输入参数的函数的最简单、最干净的方法是什么?
我应该使用 InputArray、模板还是有更好的选择?我目前拥有为 Mat 和 UMat 编写的具有相同实现的函数。
该函数应充分利用 OpenCL 上的 UMat 抽象,并且 运行 大致与专为 UMats 编写一样快,并且没有必须将 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;
}
@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);
}
现在您可以使用 Mat
或 UMat
甚至 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]
}
我使用了模板:
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;
}
优点:
- 很容易根据输入类型声明本地
Mat
s 或UMat
s。 - 没有
Mat
⟷UMat
转换。
缺点:
- 所有矩阵参数必须是同一类型,不能混合使用
Mat
和UMat
。