Generi c функция для преобразования cv :: Mat в std :: vector - PullRequest
1 голос
/ 08 января 2020

Мне интересно, существует ли обобщенный c подход для преобразования любого cv :: Mat в std :: vector. Для определенных c типов, например, uchar, я могу что-то вроде:

std::vector<uchar> convert(const cv::Ma& mat)
{
std::vector<uchar> array;
if (mat.isContinuous()) {
  array.assign(mat.data, mat.data + mat.total());
} else {
  for (int i = 0; i < mat.rows; ++i) {
    array.insert(array.end(), mat.ptr<uchar>(i), mat.ptr<uchar>(i)+mat.cols);
  }
}
return array;
}

Однако я хотел бы избежать дублирования моего кода для разных типов и иметь что-то вроде:

template<typename T>
std::vector<T> convert(const cv::Mat_<T>& mat)
{
std::vector<T> array;
if (mat.isContinuous()) {
  array.assign(mat.data, mat.data + mat.total());
} else {
  for (int i = 0; i < mat.rows; ++i) {
    array.insert(array.end(), mat.ptr(i), mat.ptr(i)+mat.cols);
  }
}
}

Который не работает, так как cv :: Mat шаблонизируется, например, через cv :: Vec4f. Конечно, я мог бы сейчас сделать что-то вроде

template<typename T, int C>
std::vector<T> convert(const cv::Mat_<cv::Vec<T,C>>& mat)

.. но для этого я получаю сообщение об ошибке: note: candidate template ignored: could not match 'Mat_<Vec<type-parameter-0-0, cn> >' against 'cv::Mat'

1 Ответ

1 голос
/ 08 января 2020

Вы можете принять любой Mat и ограничить его, используя SFINAE.

Например:

template<class Mat, std::enable_if_t<
         std::is_arithmetic_v<typename Mat::value_type>, int> = 0>
auto convert(const Mat& mat) {
    using T = typename Mat::value_type;
    std::vector<T> arr;
    // ...
    return arr;
}

template<class Mat, std::enable_if_t<
         std::is_arithmetic_v<typename Mat::value_type::value_type>, int> = 0>
auto convert(const Mat& mat) {
    using T = typename Mat::value_type::value_type;
    constexpr auto channels = typename Mat::value_type::channels; // = C
    std::vector<T> arr;
    // ...
    return arr;
}

Первая функция примет cv::Mat_<T> с любой арифметикой c T. Второй будет принимать cv::Mat_<T> с любым T, так что T::value_type является допустимым типом, который является арифметическим c (например, cv::Mat_<cv::Vec4f>).

Вы можете добавить больше ограничений, используя SFINAE, если необходимо.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...