opencv把图片读为matlab,2015-05-02-OpenCV 读取 Matlab .mat 文件的方法

在把 Matlab 转化成 OpenCV(C++) 的过程中,经常会遇见 load .mat 文件这个问题。正巧,Stackoverflow 上有个问题《Converting a .mat file from MATLAB into cv::Mat matrix in OpenCV》就是回答这个的。这篇博文的主要分为两部分,第 1 部分是将这个答案转述一遍,以方便日后需要;第 2 部分是在原答案的基础上的改进,以求在方便程度和灵活性上有一定的提高。

1. (翻译)将 MATLAB 的 .mat 文件转化成 OpenCV 的 cv::Mat 矩阵

由于 OpenCV 没法直接读取 MATLAB 的 .mat 文件,这就需要通过第三方的格式作为两者之间的桥梁。考虑到 OpenCV 的 FileStorage 类提供了 XML/YML 文件的存取功能。

例如,我们有一个如下的 yml 文件,文件名是 demo.yml

%YAML:1.0

Variable1: !!opencv-matrix

rows: 4

cols: 5

dt: f

data: [ -1.60522782e-03, -5.93489595e-03, 2.92204670e-03,

1.14785777e-02, -1.57432575e-02, -2.17529312e-02, 4.05947529e-02,

6.56594411e-02, 1.24527821e-02, 3.19751091e-02, 5.41692637e-02,

4.04683389e-02, 2.59191263e-03, 1.15112308e-03, 1.11024221e-02,

4.03668173e-03, -3.19138430e-02, -9.40114353e-03, 4.93452176e-02,

5.73473945e-02 ]

Variable2: !!opencv-matrix

rows: 7

cols: 2

dt: f

data: [ -2.17529312e-02, 4.05947529e-02, 5.73473945e-02,

6.56594411e-02, 1.24527821e-02, 3.19751091e-02, 5.41692637e-02,

4.03668173e-03, -3.19138430e-02, -9.40114353e-03, 4.93452176e-02,

4.04683389e-02, 2.59191263e-03, 1.15112308e-03 ]

接着,我们就可以用 OpenCV 的 FileStorage 类读取储存在 demo.yml 中的变量了,示例代码如下:

#include

#include

#include

#include

using namespace cv;

using namespace std;

int main (int argc, char * const argv[])

{

Mat var1;

Mat var2;

string demoFile = "demo.yml";

FileStorage fsDemo( demoFile, FileStorage::READ);

fsDemo["Variable1"] >> var1;

fsDemo["Variable2"] >> var2;

cout << "Print the contents of var1:" << endl;

cout << var1 << endl << endl;

cout << "Print the contents of var2:" << endl;

cout << var2 << endl;

fsDemo.release();

return 0;

}

至此,你所需要做的就是写一个你自己的 Matlab parser,类似于如下这样的:

function matlab2opencv( variable, fileName, flag)

[rows cols] = size(variable);

% Beware of Matlab's linear indexing

variable = variable';

% Write mode as default

if ( ~exist('flag','var') )

flag = 'w';

end

if ( ~exist(fileName,'file') || flag == 'w' )

% New file or write mode specified

file = fopen( fileName, 'w');

fprintf( file, '%%YAML:1.0\n');

else

% Append mode

file = fopen( fileName, 'a');

end

% Write variable header

fprintf( file, ' %s: !!opencv-matrix\n', inputname(1));

fprintf( file, ' rows: %d\n', rows);

fprintf( file, ' cols: %d\n', cols);

fprintf( file, ' dt: f\n');

fprintf( file, ' data: [ ');

% Write variable data

for i=1:rows*cols

fprintf( file, '%.6f', variable(i));

if (i == rows*cols), break, end

fprintf( file, ', ');

if mod(i+1,4) == 0

fprintf( file, '\n ');

end

end

fprintf( file, ']\n');

fclose(file);

由此,我们就可以将 Matlab 变量储存成 yml 文件,如下所示:

varA = rand( 3, 6);

varB = rand( 7, 2);

matlab2opencv( varA, 'newStorageFile.yml');

matlab2opencv( varB, 'newStorageFile.yml', 'a'); % append mode passed by 'a' flag

由此,我们就可以得到 newStorageFile.yml,如下所示:

%YAML:1.0

varA: !!opencv-matrix

rows: 3

cols: 6

dt: f

data: [ 0.430207, 0.979748, 0.258065,

0.262212, 0.221747, 0.318778, 0.184816,

0.438870, 0.408720, 0.602843, 0.117418,

0.424167, 0.904881, 0.111119, 0.594896,

0.711216, 0.296676, 0.507858]

varB: !!opencv-matrix

rows: 7

cols: 2

dt: f

data: [ 0.085516, 0.578525, 0.262482,

0.237284, 0.801015, 0.458849, 0.029220,

0.963089, 0.928854, 0.546806, 0.730331,

0.521136, 0.488609, 0.231594]

读取 varA 和 varB 的方法就跟之前读取 Variable1 和 Variable2 那样。

2. 改进的代码

需求

根据输入的数据类型,自适应地调整写入到 yml 文件的数据类型,以方便后面 cv::Mat 类型的数据访问。

先来一个稍微改动一下,写入 int 类型的代码:

function matlab2opencv_int( variable, fileName, flag)

[rows cols] = size(variable);

% Beware of Matlab's linear indexing

variable = variable';

% Write mode as default

if ( ~exist('flag','var') )

flag = 'w';

end

if ( ~exist(fileName,'file') || flag == 'w' )

% New file or write mode specified

file = fopen( fileName, 'w');

fprintf( file, '%%YAML:1.0\n');

else

% Append mode

file = fopen( fileName, 'a');

end

% Write variable header

fprintf( file, ' %s: !!opencv-matrix\n', inputname(1));

fprintf( file, ' rows: %d\n', rows);

fprintf( file, ' cols: %d\n', cols);

fprintf( file, ' dt: i\n');

fprintf( file, ' data: [ ');

% Write variable data

for i=1:rows*cols

fprintf( file, '%i', variable(i));

if (i == rows*cols), break, end

fprintf( file, ', ');

if mod(i+1,8) == 0

fprintf( file, '\n ');

end

end

fprintf( file, ']\n');

fclose(file);

有了上面的基础,下面自动的代码就可以是:

function dym_matlab2opencv(variable, fileName, flag, varClass)

% varClass: the variable class waiting for write:

% 'i': for int

% 'f': for float

% flag : Write mode

% 'w': for write

% 'a': for append

[rows, cols] = size(variable);

% Beware of Matlab's linear indexing

variable = variable';

% Write mode as default

if ( ~exist('flag','var') )

flag = 'w';

end

% float as default

if ( ~exist('varClass','var') )

if isfloat(variable)

varClass = 'f';

else isinteger(variable)

varClass = 'i';

end

end

if ( ~exist(fileName,'file') || flag == 'w' )

% New file or write mode specified

file = fopen( fileName, 'w');

fprintf( file, '%%YAML:1.0\n');

else

% Append mode

file = fopen( fileName, 'a');

end

% Write variable header

fprintf( file, ' %s: !!opencv-matrix\n', inputname(1));

fprintf( file, ' rows: %d\n', rows);

fprintf( file, ' cols: %d\n', cols);

fprintf( file, [' dt: ' varClass '\n']);

fprintf( file, ' data: [ ');

% Write variable data

for i=1:rows*cols

fprintf( file, ['%' varClass], variable(i));

if (i == rows*cols), break, end

fprintf( file, ', ');

if mod(i+1,8) == 0

fprintf( file, '\n ');

end

end

fprintf( file, ']\n');

fclose(file);

以上,初写于 2015-05-02,更新于 2015-07-23。

首发于 Yimian Dai's Homepage,转载请注明出处。

参考资料

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
引用\[1\]:(1)新建一个“24”的文件夹,把拍摄的标定图片放在“24”的文件夹里面,在“24”的文件夹里面新建一个“image”的文本文档,在“image”的文本文档里面输入“dir/s/b *.bmp>image.txt”保存然后退出。 (2)把image.txt的后缀改成bat,弹出重命名警告选择“是”。 (3)生成image.bat文件之后双击会生成一个image.txt的文本文档,image.txt里面存放的是图片的路径地址。 (4)运行代码 我用的是vs2015+opencv3.4.5+win10。vs版本过高可能报错。另外opencv库里面也有自带的标定代码。 运行代码只需要修改图片路径和标定板的行列数。标定的结果生成“result”文本文档保存在工程的debug目录下面 。 。 引用\[2\]:需要将两个摄像机的标定图片分开两个文件夹存放,并保证文件数量相同并且拍摄时刻一一对应。选择文件夹选项下面,可以设置棋盘格边长和单位,如果需要后续视差数据生成点云图,需要按实际长度填写。如果只是看效果,使用默认即可。 。 引用\[3\]: Tangential Distortion:当透镜和图像平面不平行时,会发生切向失真。切向畸变系数模拟了这种畸变。选中“计算切向失真”复选框时,校准器将估计切向失真系数。否则,校准器将切向畸变系数设置为零。切向畸变有D1,D2两个参数。 。 问题:matlab 标定文件读取 回答: 在Matlab读取标定文件,可以使用`calibrationData = load('filename.mat')`命令,其中`filename.mat`是标定文件的名称。这将加载标定文件中保存的所有数据,包括相机的内参、外参和畸变系数等信息。你可以通过访问`calibrationData`结构体的不同字段来获取所需的信息。例如,`calibrationData.CameraParameters`将给出相机的内参信息,`calibrationData.RotationVectors`将给出相机的旋转向量,`calibrationData.TranslationVectors`将给出相机的平移向量等。请确保标定文件的路径正确,并且文件格式是Matlab支持的格式。 #### 引用[.reference_title] - *1* [单目视觉标定(2)——matlab标定与opencv标定](https://blog.csdn.net/weixin_51512325/article/details/114677771)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* *3* [通过matlab进行立体标定并导出为opencv可加载文件](https://blog.csdn.net/length85/article/details/122220878)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值