将 cv::Mat 转换为 std::vector 的通用函数



我想知道是否有一种通用方法可以将任何cv::Mat转换为std::vector。 对于特定类型,例如 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'

您可以接受任何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;
}

第一个函数将接受具有任何算术Tcv::Mat_<T>。第二个将接受具有任何Tcv::Mat_<T>,使得T::value_type是算术的有效类型(例如,cv::Mat_<cv::Vec4f>(。

如果需要,您可以使用 SFINAE 添加更多约束。

最新更新