OpenCV:YAML vs XML格式文件的读写操作

48 篇文章 4 订阅

参考文章:Opencv YAML和XML格式文件操作详解

  • YAML格式的文件拓展名包括:.yml 和 .yaml;
  • XML格式的文件拓展名为: .xml;
  • 在OpenCV中,使用FileStorage进行文件读写。XML文件操作与YAML一样,不过存在一些细小差别。
// write file保存数据
cv::FileStorage fs(fileName,cv::FileStorage::WRITE);
// read file读取数据
cv::FileStorage fs2(fileName,cv::FileStorage::READ);
// or use: cv::FileStorage::open
//或
FileStorage fs2;
fs2.open(fileName , cv::FileStorage::READ);
  • filename:文件路径名;
  • FileStorage文件操作模式共分为四种:READ,WRITE,APPEND,MEMORY;
  • 文档打开后很关心的一件事就是,进行确认是否成功。

FileStorage有自己的成员函数返回文件打开状态:

// bool FileStorage::isOpened() const;
if ( !fs.isOpened() ) // failed
{
    std::cout<<"Save File Failed!"<<std::endl;
    return ;
}
else // succeed
{
    ...
}
fs.release();//文件关闭;
  • FileStorage文件读与写的方法与C++语言中的文件流对象的使用很像,对>>和<<进行了重载,分别用于文件读取和写入。
  • FileStorage支持一些常用格式的直接读写,例如字符、字符串、数字、cv::Mat等。对于不支持的数据结构,只能按照规则自己去写啦~
filename fs(filename,FileStorage::WRITE);
fs << "frameCount" << 5;  // 字符和数字
cv::Mat_<double> cameraMat = cv::Mat_<double>::zeros(3, 3); 
fs << "Camera Intrinsic Matrix" << cameraMat; // cv::Mat
  • fs << “frameCount” <<5中”“内输出的字符串是有限制的,对于YAML有效范围是:[a-z],[A-Z],[0-9],”-“,”_”和空格。
  • XML与YAML基本一致,但是YAML字符之间加空格是允许的,XML不允许。如果出现以下BUG,请不要慌张,检查一下输入的字符是否有效就OK~

文件读取的方法有两种:

// first method: use (type) operator on FileNode.
int frameCount = (int)fs2["frameCount"];
// second second method: use cv::FileNode::operator >>
int frameCount;
fs2["frameCount"] >> frameCount;
  • Mat的操作:
    Mat intrinsic0,intrinsic1,dist_Coeffs0,dist_Coeffs1;
    FileStorage fs00("M0.xml",FileStorage::WRITE);
    fs00<<"M0"<<intrinsic0;
    fs00.release();
    FileStorage fs01("D0.xml",FileStorage::WRITE);
    fs01<<"D0"<<dist_Coeffs0;
    fs01.release();
    FileStorage fs10("M1.xml",FileStorage::WRITE);
    fs10<<"M1"<<intrinsic1;
    fs10.release();
    FileStorage fs11("D1.xml",FileStorage::WRITE);
    fs11<<"D1"<<dist_Coeffs1;
    fs11.release();
    FileStorage fsr("R.xml",FileStorage::WRITE);
    fsr<<"R"<<R;
    fsr.release();
    FileStorage fst("T.xml",FileStorage::WRITE);
    fst<<"T"<<T;
    fst.release();
    cout<<"save success ...\n"<<endl;

集合:

  • Opencv中将集合分为两类:映射和序列
  • 映射集合(Mappings, 又称named collections):每个元素有一个名字或者说关键字,并且可以通过名字访问其数据,类似于Key-Value结构
// Mappings read
cv::FileNode features = fs2["features"];
// 遍历查看
cv::FileNodeIterator it = features.begin();
std::cout<<
    "x="<<(int)(*it)["x"]<<
    " y="<<(int)(*it)["y"]<<
    " z="<<(int)(*it)["z"]<<std::endl;
  • 序列集合(Sequences,又称unnamed collections):数据没有名字名字或者关键字,一般通过序号(indices)访问数据
// Sequences write
int mySeq[5] = {0, 1, 2, 3, 4};
fs << "mySeq" << "[";
for ( int idx=0; idx<5; idx++ )
{
    fs << mySeq[idx];
}
fs << "]";


// Sequences read
cv::FileNode mySeq2 = fs2["mySeq"];
std::vector<int> seq;
cv::FileNodeIterator it = mySeq2.begin(), it_end = mySeq2.end();
for ( ; it != it_end; it++  )
{
    seq.push_back( (int)( *it ) );
    // std::cout<<(int)(*it)<<" "<<std::endl;
}
FileStorage fs("xxx.xml", CV_STORAGE_WRITE);//保存标定参数矩阵到本地
    if( fs.isOpened() )
    {
        fs << "M0" << monoCalibVars.intrinsic0 << "D0" << monoCalibVars.dist_Coeffs0
           << "M1" << monoCalibVars.intrinsic1 << "D1" << monoCalibVars.dist_Coeffs1
           <<"R"<<binoCalibVars.R<<"T"<<binoCalibVars.T;
        fs.release();
    }
    else
        cout << "Error: can not save the calibrate parameters\n";
    cout<<"save success ..."<<endl;
fs["leftValidArea"] >> roiVal1;
        m_Calib_Roi_L.x = roiVal1[0];
        m_Calib_Roi_L.y = roiVal1[1];
        m_Calib_Roi_L.width = roiVal1[2];
        m_Calib_Roi_L.height = roiVal1[3];

        fs["rightValidArea"] >> roiVal2;
        m_Calib_Roi_R.x = roiVal2[0];
        m_Calib_Roi_R.y = roiVal2[1];
        m_Calib_Roi_R.width = roiVal2[2];
        m_Calib_Roi_R.height = roiVal2[3];

        fs["QMatrix"] >> m_Calib_Mat_Q;
        fs["remapX1"] >> m_Calib_Mat_Remap_X_L;
        fs["remapY1"] >> m_Calib_Mat_Remap_Y_L;
        fs["remapX2"] >> m_Calib_Mat_Remap_X_R;
        fs["remapY2"] >> m_Calib_Mat_Remap_Y_R;
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值