针对c ++类型测试opencv mat数据类型的最佳方法是什么?

时间:2015-09-04 16:14:15

标签: c++ templates opencv

我现在正试图在我自己的opencv lib中实现一些函数,这样就可以将rgb图像转换为灰度图像。

为了使函数尽可能通用,我想让它能够处理open cv(CV_8U,CV_8S,... CV64F)中的所有数据类型,即输出图像数据类型应该与输入匹配图像数据类型。这涉及定义一些将保存类型作为输入图像数据类型的指针。

我明白找出输入的数据类型并初始化相应的指针不能在运行时完成,所以我必须使用某种开关来在代码中确定它。

在代码中,我为实际工作定义了模板函数t_convert_RGB_to_Gray<T>(...)。然后我有一个多功能convert_RGB_to_Gray(...),以便能够确定数据类型并调用正确的转换函数。

我目前对数据类型测试有以下两种方法:

接近1

     switch(image.depth())
    {
        case CV_8U: gray = t_convert_RGB_to_Gray<unsigned char>(image, coeff_R, coeff_G, coeff_B); break;
        case CV_8S: gray = t_convert_RGB_to_Gray<char>(image, coeff_R, coeff_G, coeff_B); break;
        case CV_16U:gray = t_convert_RGB_to_Gray<uint16_t>(image, coeff_R, coeff_G, coeff_B); break;
        case CV_16S:gray = t_convert_RGB_to_Gray<int16_t>(image, coeff_R, coeff_G, coeff_B); break;
        case CV_32S:gray = t_convert_RGB_to_Gray<int32_t>(image, coeff_R, coeff_G, coeff_B); break;
        case CV_32F:gray = t_convert_RGB_to_Gray<float>(image, coeff_R, coeff_G, coeff_B); break;
        case CV_64F:gray = t_convert_RGB_to_Gray<double>(image, coeff_R, coeff_G, coeff_B); break;
        default:    gray = t_convert_RGB_to_Gray<unsigned char>(image, coeff_R, coeff_G, coeff_B); break;
    }

接近2

if (cv::DataType<unsigned char>::depth == image.depth())
{
    // variation 1.
    //gray = t_convert_RGB_to_Gray<unsigned char>(image, coeff_R, coeff_G, coeff_B);
    // variation 2.
    gray = t_convert_RGB_to_Gray<cv::DataType<unsigned char>::channel_type>(image, coeff_R, coeff_G, coeff_B);
}
else if
 ....
}

我的问题是,这样做是否有任何缺点?有没有更好的方法呢?

谢谢!

2 个答案:

答案 0 :(得分:2)

要完成Miki的答案,您可以采取类似于您的第一种方法:

switch(image.depth()) {
  case DataType<unsigned char>::type:
    gray = t_convert_RGB_to_Gray<unsigned char>(image, coeff_R, coeff_G, coeff_B);
    break;
  case DataType<int>::type:
    ...
}

答案 1 :(得分:1)

  

理想情况下,我期望的是一个函数,它将c ++类型作为参数,返回一个cv数据类型,即cv :: get_cv_type(float)// return:CV_32F(5)。

这可以使用DataType来完成,例如:

DataType<unsigned char>::type   == CV_8UC1 
DataType<char>::type            == CV_8SC1 
DataType<float>::type           == CV_32FC1
DataType<double>::type          == CV_64FC1
DataType<Vec3b>::type           == CV_8UC3 
DataType<Vec<int, 4>>::type     == CV_32SC4