OpenCV FileStorage类读写XML/YML文件

本文介绍了 OpenCV 中用于 XML 和 YML 文件读写的 FileStorage 类,包括如何创建对象、使用 << 操作进行操作以及如何读取文件。详细解释了如何在 C++ 接口中实现数据的保存与获取。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

OpenCV FileStorage类读写XML/YML文件

        在OpenCV程序中,需要保存中间结果的时候常常会使用.xml / .yml文件,opencv2.0之前都是使用C风格的代码,当时读写XML文件分别使用函数cvLoad()和cvSave()。在2.0以后的OpenCV转为支持C++,这一举措大大减少了代码量以及编程时需要考虑的细节。

        新版本的OpenCV的C++接口中,imwrite()和imread()只能保存整数数据,且需要以图像格式。当需要保存浮点数据或者XML/YML文件时,之前的C语言接口cvSave()函数已经在C++接口中被删除,代替它的是FileStorage类。这个类非常的方便,封装了很多数据结构的细节,编程的时候可以根据统一的接口对数据结构进行保存。

    1. FileStorage类写XML/YML文件

         •   新建一个FileStorage对象,以FileStorage::WRITE的方式打开一个文件。

         •   使用 << 操作对该文件进行操作。

         •   释放该对象,对文件进行关闭。

        例子如下:

复制代码
    FileStorage fs("test.yml", FileStorage::WRITE);
    fs << "frameCount" << 5;
    time_t rawtime; time(&rawtime);
    fs << "calibrationDate" << asctime(localtime(&rawtime));
    Mat cameraMatrix = (Mat_<double>(3,3) << 1000, 0, 320, 0, 1000, 240, 0, 0, 1); //又一种Mat初始化方式
    Mat distCoeffs = (Mat_<double>(5,1) << 0.1, 0.01, -0.001, 0, 0);
    fs << "cameraMatrix" << cameraMatrix << "distCoeffs" << distCoeffs;
    
    //features为一个大小为3的向量,其中每个元素由随机数x,y和大小为8的uchar数组组成
    fs << "features" << "[";
    for( int i = 0; i < 3; i++ )
    {
        int x = rand() % 640;
        int y = rand() % 480;
        uchar lbp = rand() % 256;
        fs << "{:" << "x" << x << "y" << y << "lbp" << "[:";
        for( int j = 0; j < 8; j++ )
            fs << ((lbp >> j) & 1);
        fs << "]" << "}";
    }
    fs << "]";
    fs.release();
复制代码

         

    2. FileStorage类读XML/YML文件

       FileStorage对存储内容在内存中是以层次的节点组成的,每个节点类型为FileNode,FileNode可以使单个的数值、数组或者一系列FileNode的集合。FileNode又可以看做是一个容器,使用iterator接口可以对该节点内更小单位的内容进行访问,例如访问到上面存储的文件中"features"的内容。步骤与写文件类似:

         •   新建FileStorage对象,以FileStorage::READ 方式打开一个已经存在的文件

         •   使用FileStorage::operator []()函数对文件进行读取,或者使用FileNode和FileNodeIterator

         •   使用FileStorage::release()对文件进行关闭

         例子如下:

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

    //方式一: []操作符
    int frameCount = (int)fs["frameCount"];
    
    //方式二: FileNode::operator >>()
    string date;
    fs["calibrationDate"] >> date;
    
    Mat cameraMatrix2, distCoeffs2;
    fs["cameraMatrix"] >> cameraMatrix2;
    fs["distCoeffs"] >> distCoeffs2;
    
    //注意FileNodeIterator的使用,似乎只能用一维数组去读取里面所有的数据
    FileNode features = fs["features"];
    FileNodeIterator it = features.begin(), it_end = features.end();
    int idx = 0;
    std::vector<uchar> lbpval;
    for( ; it != it_end; ++it, idx++ )
    {
        cout << "feature #" << idx << ": ";
        cout << "x=" << (int)(*it)["x"] << ", y=" << (int)(*it)["y"] << ", lbp: (";
        (*it)["lbp"] >> lbpval;  //直接读出一维向量

        for( int i = 0; i < (int)lbpval.size(); i++ )
            cout << " " << (int)lbpval[i];
        cout << ")" << endl;
    }
    fs.release();
复制代码

        另外,注意在新建FileStorage对象之后,并以READ或WRITE模式打开文件之后,可以用FileStorage::isOpened()查看文件状态,判断是否成功打开了文件。

转自:http://www.cnblogs.com/summerRQ/articles/2524560.html

<think>好的,我现在要解决用户提到的OpenCV中的cv::Exception异常问题,具体是persistence.cpp文件中的断言失败错误,错误信息是Assertion buf。首先,我需要理解用户的问题。用户提供了几个引用,其中提到了不同的OpenCV错误,比如detectMultiScale、imshow、imdecode等,但用户当前的问题是关于persistence.cpp中的断言失败,特别是Assertion buf。我需要根据这些信息来推断可能的原因和解决方案。 首先,persistence.cpp通常与文件读写操作有关,比如加载模型、读取配置文件XML/YAML文件。断言失败通常意味着某个条件不满足。例如,当尝试读取一个文件文件不存在、路径错误、权限不足或者文件损坏时,OpenCV会抛出这样的错误。用户提到的Assertion buf可能指的是缓冲区为空,这可能意味着文件没有被正确加载到内存中。 接下来,我需要参考用户提供的引用。引用[3]提到文件路径问题,用户移动图片到正确路径后解决了问题。引用[4]提到因为删除后恢复导致图片损坏,删除损坏文件后解决。这些案例都涉及文件路径或文件本身的问题。所以,针对persistence.cpp的错误,可能的原因包括文件路径错误、文件不存在、文件损坏、权限问题或格式不支持。 可能的解决步骤应该是: 1. 检查文件路径是否正确,确保没有拼写错误,并且路径是绝对路径或相对路径正确。特别是在不同操作系统下,路径分隔符可能不同,需要注意使用正确的斜杠。 2. 确认文件确实存在于指定路径,并且程序有权限访问该文件。有时候文件可能被其他程序占用,或者权限设置导致无法读取。 3. 验证文件是否完整且未损坏。例如,用户可能在下载或传输文件过程中中断,导致文件不完整。可以尝试重新下载或使用其他工具打开该文件,确认是否能正常读取。 4. 检查文件格式是否符合OpenCV的支持范围。例如,加载的模型文件(如XML/YAML)是否是正确的格式,或者是否是OpenCV版本支持的格式。有时候不同版本的OpenCV可能对文件格式有不同的要求。 5. 确认使用的OpenCV函数参数是否正确。比如,在调用cv::FileStorage读取文件时,是否正确指定了模式(如FileStorage::READ),或者是否正确初始化了对象。 6. 更新OpenCV版本。如果用户使用的是开发版本(如4.12.0-dev),可能存在已知的bug,尝试升级到稳定版本或修复版本,看是否能解决问题。 7. 检查文件编码或内容是否符合预期。例如,XML文件可能存在语法错误,导致解析失败,这时需要检查文件内容是否正确。 现在,根据这些可能性,我需要整理出结构化的解决方案,分步骤指导用户逐一排查。同时,结合用户提供的引用,特别是引用[3]和[4]中的案例,强调文件路径和文件完整性检查的重要性。此外,可能需要提醒用户注意权限问题和OpenCV版本兼容性。 最后,生成相关问题,帮助用户深入理解可能涉及的方面,比如如何调试文件加载问题,或者如何处理不同文件格式的异常。</think>针对OpenCV中`persistence.cpp`文件断言失败错误`Assertion buf`的解决方案如下: ### 问题分析 该错误通常发生在文件操作(如加载模型、配置文件XML/YAML文件)时,核心原因是**文件未正确加载到内存缓冲区**。可能由以下原因导致: 1. 文件路径错误或文件不存在 2. 文件权限不足或文件被占用 3. 文件内容损坏或格式错误 4. OpenCV版本兼容性问题 --- ### 分步解决方案 #### 1. 验证文件路径有效性 ```python import cv2 import os file_path = "your/file/path.xml" print(f"文件存在性检查: {os.path.exists(file_path)}") # 应返回True print(f"文件可读性检查: {os.access(file_path, os.R_OK)}") # 应返回True ``` - 使用**绝对路径**代替相对路径 - 检查路径分隔符: - Windows:`D:/project/data/file.xml`(正斜杠) - Linux/Mac:`/home/user/data/file.xml` - 特殊字符处理:路径中避免空格和中文[^3] #### 2. 检查文件完整性 - 尝试用文本编辑器直接打开目标文件 - 检查文件大小是否异常(如0KB文件) - 重新下载或生成文件(如模型文件损坏) #### 3. 验证文件格式 ```python try: fs = cv2.FileStorage(file_path, cv2.FileStorage_READ) if not fs.isOpened(): raise ValueError("文件打开失败") # 读取具体数据验证 node = fs.getNode("key_name") if node.empty(): print("有效数据缺失") except Exception as e: print(f"文件解析失败: {str(e)}") finally: fs.release() ``` #### 4. 权限与依赖检查 - 确保文件未被其他程序独占锁定 - 检查OpenCV构建时是否包含所需模块: ```bash # 检查OpenCV编译配置 python -c "import cv2; print(cv2.getBuildInformation())" ``` 确认输出包含`YES`的模块: ``` XML/YAML: YES ``` #### 5. 版本兼容性处理 - 升级到稳定版本: ```bash pip install --upgrade opencv-python ``` - 或从源码编译: ```bash git clone https://github.com/opencv/opencv.git cd opencv && mkdir build && cd build cmake -D BUILD_EXAMPLES=ON .. make -j4 ``` --- ### 典型错误场景 1. **YAML/XML文件格式错误**: ```yaml # 错误示例(缺少冒号) image_width 640 # 正确格式 image_width: 640 ``` 2. **文件加载时序问题**: ```python # 错误写法(未等待文件写入完成) with open("data.yml", "w") as f: f.write("key: value") fs = cv2.FileStorage("data.yml", cv2.FileStorage_READ) # 可能失败 # 正确做法(显式关闭文件) with open("data.yml", "w") as f: f.write("key: value") time.sleep(0.1) # 确保写入完成 ``` --- ### 调试建议 1. 使用最小化测试代码复现问题: ```python import cv2 fs = cv2.FileStorage("test.yml", cv2.FileStorage_WRITE) fs.write("test_key", 123) fs.release() fs_read = cv2.FileStorage("test.yml", cv2.FileStorage_READ) val = fs_read.getNode("test_key").real() print(f"读取验证值: {val}") ``` 2. 启用OpenCV详细日志: ```python cv2.utils.dumpConfiguration() # 查看运行时配置 ``` ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值