opencv c++ mat转vector

本文介绍了一种使用C++标准库中的vector实现二维矩阵(mat)到二维浮点数数组的转换方法。通过双重循环遍历矩阵的每一行和每一列,将矩阵中的每个元素复制到vector中。此方法适用于图像处理或数据预处理等场景。

数据类型float根据具体场景不同而不同,mat是已有的值

std::vector<std::vector<float>> vec;
for (int x = 0; x < mat.rows; x++) {
		for (int y = 0; y < mat.cols; y++) {
                vec[x][y] = mat.at<float>(x, y);
                 //std::cout << mat.at<float>(x, y) << std::endl;
         }
 }
<think>我们需要将OpenCVMat(单列,N行)换为C++vector。由于Mat可以是多种数据类型,这里我们假设是常见的浮点型或整型。注意:Mat的数据可能是连续的,也可能是不连续的(例如子矩阵)。我们使用clone()确保连续,或者直接访问数据并处理步长问题。以下代码提供了几种方法,包括:1.使用Mat的迭代器2.使用指针直接访问数据3.使用reshape和std::copy(高效方式)我们以换为vector<float>为例,其他数据类型类似。注意:Mat的类型可以通过Mat::type()获取。确保Mat是单通道的(因为vector是一维的,我们按单通道处理)。步骤:1.检查Mat是否为空2.确保Mat是单列,且通道数为1(或者如果是多通道,我们只取其中一个通道?但问题要求是N*1,所以应该是单通道单列)3.根据数据类型进行换我们假设Mat的数据类型为CV_32F(float)或CV_64F(double),并分别处理。但是问题没有指定Mat的具体类型,所以我们将提供通用方法,包括类型检查和换。不过,为了简单起见,我们主要处理常见类型:float和double。整数类型可以类似处理。方法一:使用指针(高效)方法二:使用OpenCVMat_类(简化访问)方法三:使用reshape和copy(需要数据类型匹配,且连续)我们推荐使用指针方法,因为它直接且高效。下面给出代码:</think> 在OpenCV中将一个N×1的`cv::Mat`换为`std::vector`有多种高效方法。以下是最优解决方案和代码实现: ### 推荐方法:直接内存复制(最高效) 当Mat数据类型与vector元素类型匹配时,直接内存复制是最快的方法: ```cpp #include <vector> #include <opencv2/opencv.hpp> // 将单列浮点型Mat换为vector<float> std::vector<float> matN1ToVec(const cv::Mat& mat) { // 1. 验证输入格式 CV_Assert(mat.cols == 1 && "Input must be N×1 matrix"); CV_Assert(mat.type() == CV_32FC1 && "Matrix must be float type"); // 2. 获取原始数据指针 const float* data = mat.ptr<float>(0); // 3. 直接内存复制(避免元素级拷贝) return std::vector<float>(data, data + mat.rows); } ``` ### 完整示例代码 ```cpp #include <iostream> #include <vector> #include <opencv2/opencv.hpp> int main() { // 创建示例数据: 5行×1列的浮点矩阵 cv::Mat mat = (cv::Mat_<float>(5,1) << 1.1, 2.2, 3.3, 4.4, 5.5); // 方法1: 直接内存复制(推荐) std::vector<float> vec1 = std::vector<float>( mat.ptr<float>(0), mat.ptr<float>(0) + mat.rows ); // 方法2: 使用OpenCV迭代器 std::vector<float> vec2; vec2.reserve(mat.rows); // 预分配内存 cv::MatConstIterator_<float> it = mat.begin<float>(); while (it != mat.end<float>()) { vec2.push_back(*it++); } // 验证结果 std::cout << "Direct copy: "; for (float v : vec1) std::cout << v << " "; std::cout << "\nIterator method: "; for (float v : vec2) std::cout << v << " "; return 0; } ``` ### 性能对比表 | 方法 | 时间复杂度 | 内存使用 | 适用场景 | |------|------------|----------|----------| | 直接内存复制 | **O(1)*** | 最优 | 类型匹配且连续内存 | | OpenCV迭代器 | O(N) | 额外迭代器开销 | 需要类型安全校验 | | for循环+at() | O(N) | 高(函数调用开销) | 不推荐(性能差) | | clone().reshape() | O(N) | 高(临时对象) | 多维矩阵换时 | > *注:严格说是O(N),但连续内存复制比元素级复制快10-100倍 ### 关键优化技术 1. **数据连续性保证**: ```cpp if (!mat.isContinuous()) { mat = mat.clone(); // 确保内存连续 } ``` 2. **通用类型处理**: ```cpp template<typename T> std::vector<T> matToVector(const cv::Mat& mat) { CV_Assert(mat.cols == 1); return std::vector<T>( mat.ptr<T>(0), mat.ptr<T>(0) + mat.rows ); } ``` 3. **多维矩阵处理**: ```cpp // 将任意N×1矩阵展平为向量 cv::Mat flattened = mat.reshape(1, mat.rows); ``` ### 不同类型换指南 | Mat类型 | 对应vector类型 | 注意事项 | |---------|----------------|----------| | CV_8U (uchar) | `std::vector<uint8_t>` | 无符号字节数据 | | CV_32S (int) | `std::vector<int32_t>` | 整型数据 | | CV_32F (float) | `std::vector<float>` | 浮点数据(推荐) | | CV_64F (double) | `std::vector<double>` | 双精度数据 | | CV_16U (ushort) | `std::vector<uint16_t>` | 16位图像数据 | ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值