You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Python读取含opencv-matrix的YAML文件报错及方案咨询

问题描述

我有如下test.yaml文件:

Camera.ColourOrder: "RGB"
Camera.ColourDepth: "UCHAR_8"
Camera.Spectrum: "Visible_NearIR"
IMU.T_b_c1: !!opencv-matrix
   rows: 4
   cols: 4
   dt: f
   data: [0.999903, -0.0138036, -0.00208099, -0.0202141,
         0.0137985, 0.999902, -0.00243498, 0.00505961,
         0.0021144, 0.00240603, 0.999995, 0.0114047,
         0.0, 0.0, 0.0, 1.0]

因文件包含!!opencv-matrix这类OpenCV相关对象,无法用Python内置YAML模块读取,尝试使用cv2.FileStorage读取时触发错误:

>>> import os
>>> 'test.yaml' in os.listdir()
True
>>> import cv2
>>> fs = cv2.FileStorage("test.yaml", cv2.FILE_STORAGE_READ)
cv2.error: OpenCV(4.8.1) /io/opencv/modules/core/src/persistence.cpp:699: error: (-5:Bad argument) Input file is invalid in function 'open'

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
SystemError: <class 'cv2.FileStorage'> returned a result with an error set

即使移除IMU.T_b_c1部分,仅保留Camera相关配置,仍出现相同错误。请问我忽略了什么?另外,是否有其他模块可读取此类含OpenCV对象的YAML文件?


解决方案

1. 错误核心原因:OpenCV FileStorage不兼容标准YAML写法

OpenCV的FileStorage并非通用YAML解析器,它有严格的格式要求:

  • 键名不能包含.:OpenCV会将.识别为层级分隔符,但标准YAML中带.的键名是合法的,这会直接导致解析失败
  • 部分版本要求文件开头必须加%YAML:1.0声明
  • !!opencv-matrix的标签写法不符合OpenCV原生存储规范

2. 修复文件适配OpenCV FileStorage

修改test.yaml为以下格式即可正常读取:

%YAML:1.0
Camera:
  ColourOrder: "RGB"
  ColourDepth: "UCHAR_8"
  Spectrum: "Visible_NearIR"
IMU:
  T_b_c1:
    rows: 4
    cols: 4
    dt: f
    data: [0.999903, -0.0138036, -0.00208099, -0.0202141,
          0.0137985, 0.999902, -0.00243498, 0.00505961,
          0.0021144, 0.00240603, 0.999995, 0.0114047,
          0.0, 0.0, 0.0, 1.0]

读取代码示例:

import cv2

fs = cv2.FileStorage("test.yaml", cv2.FILE_STORAGE_READ)
# 读取Camera参数
colour_order = fs.getNode("Camera").getNode("ColourOrder").string()
# 读取变换矩阵
T_b_c1 = fs.getNode("IMU").getNode("T_b_c1").mat()
fs.release()

3. 替代方案:用PyYAML+自定义构造器读取原文件

如果不想修改原文件,可以通过PyYAML配合自定义构造器解析!!opencv-matrix:

  • 先安装依赖:pip install pyyaml numpy
  • 解析代码:
import yaml
import numpy as np

# 自定义构造器处理!!opencv-matrix标签
def opencv_matrix_loader(loader, node):
    mapping = loader.construct_mapping(node, deep=True)
    rows = mapping['rows']
    cols = mapping['cols']
    dtype = np.float32 if mapping['dt'] == 'f' else np.float64
    return np.array(mapping['data'], dtype=dtype).reshape(rows, cols)

yaml.add_constructor('!!opencv-matrix', opencv_matrix_loader)

# 读取原文件
with open('test.yaml', 'r') as f:
    config = yaml.load(f, Loader=yaml.FullLoader)

# 访问参数示例
print(config['Camera.ColourOrder'])
print(config['IMU.T_b_c1'])

该方法可直接读取原格式文件,并将!!opencv-matrix转换为numpy数组,方便后续处理。

内容的提问来源于stack exchange,提问作者MsA

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 15:01:29