我想知道是否有一种通用方法可以将任何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;
}
第一个函数将接受具有任何算术T
的cv::Mat_<T>
。第二个将接受具有任何T
的cv::Mat_<T>
,使得T::value_type
是算术的有效类型(例如,cv::Mat_<cv::Vec4f>
(。
如果需要,您可以使用 SFINAE 添加更多约束。