如何将Matlab中的矩阵数据正确传输到C++版OpenCV中?
问题原因
你之前用imwrite+imread的组合读出来全是255,核心原因是这对函数是为常规图像存储设计的,处理double类型矩阵时会自动做两步转换:
- 把小于0的数值截断为0,大于1的数值截断为1
- 将0-1区间的数值线性映射到0-255的uint8整数范围再写入文件
只要你的57×1矩阵里存在大于1的数值,保存时就会被全截断为1,映射后就是255,读取结果自然错误。
可行方案
优先推荐无精度损失、依赖最少的二进制存储方案,操作如下:
方案1:二进制raw格式存储(最推荐,零依赖、无精度损失)
- Matlab端写入代码:
% 假设你的57×1 double矩阵存在变量mat_data中 fid = fopen('matrix_data.bin', 'wb'); fwrite(fid, mat_data, 'double'); % 按double类型写入二进制数据 fclose(fid);
- OpenCV端读取代码:
#include <opencv2/opencv.hpp> #include <fstream> // 预先创建57行1列的单通道64位浮点(即double)矩阵 cv::Mat cv_data(57, 1, CV_64FC1); // 打开二进制文件读取数据 std::ifstream fin("matrix_data.bin", std::ios::binary); fin.read(reinterpret_cast<char*>(cv_data.data), 57 * sizeof(double)); fin.close();
如果后续矩阵尺寸不固定,只需要在Matlab写入时先把行数、列数以int32类型写在文件开头,OpenCV读取时先读行列数再创建Mat对象即可,灵活度很高。
方案2:CSV文本格式存储(易查看,适合小数据量)
如果需要直接打开文件查看数值,可以存为CSV格式,注意该方法会有微小的浮点精度损失。
- Matlab端写入代码:
writematrix(mat_data, 'matrix_data.csv');
- OpenCV端读取代码:
// 按任意位深、单通道模式读取CSV cv::Mat cv_data = cv::imread("matrix_data.csv", cv::IMREAD_ANYDEPTH | cv::IMREAD_GRAYSCALE); // 如果imread读取CSV异常,直接用C++标准文件流逐行读取即可,57行数据量极小,无性能压力
注意事项
- 不要用
imwrite/imread处理非图像类的通用数值矩阵,这对函数内置的图像数值范围转换逻辑会破坏原始数据,仅适合保存归一化到0-1区间的double类型图像、0-255区间的uint8图像或0-65535区间的uint16图像。 - 如果需要跨环境传递更复杂的多维度矩阵、带名称的变量,可以使用YAML格式存储,OpenCV的
cv::FileStorage类原生支持YAML读写,Matlab也可以通过简单的文本写入生成符合规范的YAML文件。
内容的提问来源于stack exchange,提问作者Ori Hirshfeld
相关产品推荐
相关产品推荐

