如何将`cv::Mat` 的`type` 传递给函数?

问题描述

根据cv::Mat Class Reference,构造函数之一是:

    Mat (int rows,int cols,int type,void *data,size_t step=AUTO_STEP)

现在,我有 rs2::frame,我想将它们转换为 cv::Mat。所以,我定义了一个函数,在转换中,我想指定 cv::Mat::type输出 cv::Mat 应该是 CV_8SC1 类型还是 CV_16SC1 类型等等.

截至目前,我的功能是这样的:

cv::Mat foo(rs2::frame fr,std::string mat_type) {
    .
    .
    .
}

对于mat_type,如上所示,我正在传递字符串,即"CV_8SC1""CV_16SC1" 等,并且在函数体中,我正在手动比较字符串:

    .
    .
    if(mat_type == "CV_8SC1") {
        return cv::Mat(width,height,CV_8SC1,...);
    } else if ...
    .
    .
    .
    else {
        
    }

但是,这不是很有效,对吧?假设将来,如果我需要另一种类型的 cv::Mat,那么我必须通过向 if... else... 语句添加新条件来更新函数

那么,我怎样才能避免这种情况并做其他更有效的事情呢?我的意思是,有没有办法直接传递 cv::Mat::type 而不是传递等效的字符串然后在函数体中进行比较?

只是为了提前澄清:我的问题与这些问题不同:

  1. 传递 cv::Mats 的最佳做法是什么 - link
  2. 如何通过网络传递 cv::Mat? - link

解决方法

请注意,类型定义如下:

#define     CV_16S   3

我认为您应该传递一个 int(在 OpenCV 的源代码中为 or uint64_t ):

yourFunction(rs2::frame fr,int mat_type)

然后调用并调用您的函数,例如:

yourFunction(fr,cv::CV_8SC1)

您可以看到定义 here ,并且有一个很酷的易于使用的矩阵 here

然后,在你的函数中做一个 switch case:

switch(mat_type) {
    case cv::CV_8SC1 : //Something
    case cv::CV_32S : //Something else
.
.
.

}

无论如何,您必须为每种类型(这是正常的)做一个案例。 并且不要忘记必要的包含以在您使用它的任何地方访问 cv

,

如果您的问题是“您不认为运行时类型检查有点不切实际,并且在处理越来越多的类型时不能很好地扩展吗?”那么答案是肯定的,但是当您使用像 cv::Mat 这样的类型擦除对象时,这就是您的签名。

仅供参考,OpenCV 中有一个 cv::Mat_<T> 类型,您可以使用它,以防您在编译时知道数据类型并且不想丢失该信息。