xml 和 yaml 的区别

XML 和 YAML/YML 是两种常用的数据序列化格式,用于存储和读取结构化数据。以下是它们的核心区别和使用方法:

1. 格式特性对比

特性 XML YAML/YML
语法复杂度 标签嵌套,结构严格 缩进分层,更简洁
可读性 较低(冗余标签) 较高(类似自然语言)
文件大小 较大 (标签重复)
注释支持 支持 ( ) 支持 (# 注释)
数据类型明确性 需显式声明类型(如 type_id="opencv-matrix") 自动推断类型,更灵活
适用场景 需要严格结构或兼容旧系统 需要可读性和简洁性的配置文件

2. OpenCV 中的使用方法

写入数据示例

复制代码
#include <opencv2/opencv.hpp>

void saveData(const std::string& filename) {
    cv::FileStorage fs(filename, cv::FileStorage::WRITE);
    
    // 写入基本数据类型
    fs << "frameCount" << 100;
    fs << "resolution" << cv::Size(1920, 1080);
    
    // 写入矩阵(如相机矩阵)
    cv::Mat cameraMatrix = (cv::Mat_<double>(3,3) << 
        1000, 0, 960, 
        0, 1000, 540, 
        0, 0, 1);
    fs << "cameraMatrix" << cameraMatrix;
    
    // 写入结构体或自定义数据
    fs << "settings" << "{";
    fs << "exposure" << 0.8 << "gain" << 1.2;
    fs << "}";
    
    fs.release(); // 关闭文件
}

// 调用示例:
saveData("data.xml");   // XML 格式
saveData("data.yml");   // YAML 格式

读取数据示例

复制代码
cv::FileStorage fs("data.yml", cv::FileStorage::READ);

int frameCount;
cv::Size resolution;
cv::Mat cameraMatrix;

fs["frameCount"] >> frameCount;
fs["resolution"] >> resolution;
fs["cameraMatrix"] >> cameraMatrix;

// 读取嵌套结构
cv::FileNode settings = fs["settings"];
double exposure, gain;
settings["exposure"] >> exposure;
settings["gain"] >> gain;

fs.release();

3. 文件内容对比

XML 示例

复制代码
<?xml version="1.0"?>
<opencv_storage>
<frameCount>100</frameCount>
<resolution>1920 1080</resolution>
<cameraMatrix type_id="opencv-matrix">
  <rows>3</rows>
  <cols>3</cols>
  <dt>d</dt>
  <data>1000. 0. 960. 0. 1000. 540. 0. 0. 1.</data>
</cameraMatrix>
<settings>
  <exposure>8.0000000000000004e-01</exposure>
  <gain>1.2</gain>
</settings>
</opencv_storage>

YAML 示例

复制代码
%YAML:1.0
frameCount: 100
resolution: [1920, 1080]
cameraMatrix: !!opencv-matrix
  rows: 3
  cols: 3
  dt: d
  data: [1000., 0., 960., 0., 1000., 540., 0., 0., 1.]
settings:
  exposure: 8.0000000000000004e-01
  gain: 1.2

4. 如何选择格式?

  • 选择 XML:

    • 需要与旧版代码或工具兼容。

    • 数据需要严格的结构验证(如通过 XSD 校验)。

  • 选择 YAML:

    • 需要人工编辑和阅读配置文件。

    • 追求文件简洁性和可读性。

    • 需要更灵活的数据结构(如动态类型)。

5.常见问题

Q1:为何 YAML 文件中出现 !!opencv-matrix 标记?

  • 这是 OpenCV 的类型标记,用于明确矩阵数据的解析方式。手动编辑时需保留这些标记。

Q2:如何避免浮点数精度损失?

  • OpenCV 默认以双精度写入浮点数。若需更高精度,可手动转换为字符串:

    fs << "exposure" << cv::format("%.16f", 0.8);

Q3:如何处理自定义类的序列化?

  • 为自定义类实现 cv::FileStorage 的 << 和 >> 操作符重载:

    struct CustomData {
    int id;
    std::vector<float> values;
    };

    void operator<<(cv::FileStorage& fs, const CustomData& data) {
    fs << "{";
    fs << "id" << data.id << "values" << data.values;
    fs << "}";
    }

    void operator>>(const cv::FileNode& node, CustomData& data) {
    node["id"] >> data.id;
    node["values"] >> data.values;
    }

6. 最佳实践

  1. 统一文件扩展名:

    • 使用 .xml 表示 XML 文件,.yml 或 .yaml 表示 YAML 文件。
  2. 版本控制友好:

    • YAML 的缩进格式在版本控制(如 Git)中更易跟踪变更。
  3. 安全性:

    • 避免直接加载不可信来源的 XML/YAML 文件(防止注入攻击)。

通过合理选择 XML/YAML 格式,您可以高效管理 OpenCV 应用的配置和数据!

相关推荐
丨丨三戒丶6 分钟前
layui轮播图根据设备宽度图片等比例,高度自适应
前端·javascript·layui
24白菜头1 小时前
CSS学习笔记
前端·javascript·css·笔记·学习
GISer_Jing3 小时前
前端开发 Markdown 编辑器与富文本编辑器详解
前端·javascript
Aaaa小嫒同学4 小时前
在spark中配置历史服务器
服务器·javascript·spark
阿珊和她的猫4 小时前
动态指令参数:根据组件状态调整指令行为
前端·javascript·vue.js
xiegwei4 小时前
vue+element 导航 实现例子
前端·javascript·vue.js
露临霜5 小时前
vue实现AI问答Markdown打字机效果
前端·javascript·vue.js·ai·github
解道Jdon8 小时前
Redis宣布再次开源
javascript·reactjs
豆芽脚脚10 小时前
Auto.js 脚本:清理手机数据但保留账号
开发语言·javascript·智能手机·autojs