确定数据类型并用作模板类型名

时间:2018-07-31 08:50:27

标签: opencv c++11 templates

我需要从openCV Mat类型获取数据类型,然后在显式实例化的类中使用它:

template class Tensor<float>;
template class Tensor<uint16_t>;
template class Tensor<int8_t>;

我仅具有C ++ 11的访问权限,并且不允许使用boost,所以这样的事情是不可能的:

std::map<int, std::any> cvToTypeMap = {{CV_32F, float}, //std::any <- C++17
                                       {CV_16U, uint16_t},
                                       {CV_8S,  int8_t}};
Tensor<cvToTypeMap[my_cv_mat.type()]> my_class_var(...);

如您所见,问题是我的地图需要这种不同的类型。

如果我没记错的话,我也不能使用decltype(*my_cv_mat.data),因为它是uchar

现在有实现这一目标的任何想法吗?

1 个答案:

答案 0 :(得分:1)

您可以拥有一个工作图,并手动将int编码为数字类型映射,而不是尝试创建类型映射。然后,我们需要一个张量生成器,它将使用cv::Mat来创建适当的张量对象。

您将必须编写如下特征:

template <int CVType>
struct int_to_numeric_type;

template <> struct int_to_numeric_type<CV_32F> { using type = float; };
template <> struct int_to_numeric_type<CV_16U> { using type = uint16_t; };
// ...
template <int CVType>
struct tensor_type {
    using type = Tensor<
                     typename int_to_numeric_type<CVType>::type
                 >;
};

完成此操作后,张量生成器可以与此类似:

template <int CVType>
struct TensorBuilder {
    std::reference_wrapper<cv::Mat const> mat;
    TensorBuilder(cv::Mat const& matrix) : mat(matrix) {}

    typename tensor_type<CVType>::type make_tensor(/*Stuff other than matrix*/) const {
        // Extract all the stuff from mat you need and perform the numeric logic here
        return typename tensor_type<CVType>::type(...);
    }
};

现在,我们的张量生成器可以从cv::Mat对象隐式构造,我们将与std::function一起使用它。让我们去找工人:

template <int CVType>
void do_work(TensorBuilder<CVType> builder /*, ... */) {
    auto tensor = builder.make_tensor();
    // Do whatever you fancy with your tensor (ie, that's the body of your actual function)
}

然后,我们可以将这些工作人员嵌入到std::function<void(cv::Mat const&/*, ...*/)>的地图中!

std::map<int, std::function<void(cv::Mat const& /*,...*/)> > workerMap {
    {CV_32F, &do_work<CV_32F>},
    {CV_16U, &do_work<CV_16U>}
};

当时的用法是

// my_cv_map gets implicitly converted to TensorBuilder<...>, allowing the worker to work with the proper tensor type.
workerMap[my_cv_map.type()](my_cv_map /*,...*/);