用于OpenCV Python API的FileStorage
c++
image-processing
opencv
python
3
0

我目前正在使用FileStorage类使用OpenCV C ++ API存储矩阵XML / YAML

但是,我必须编写一个Python脚本来读取那些XML / YAML文件。

我正在寻找可以读取由OpenCV C ++ API生成的XML / YAML文件的现有OpenCV Python API

参考资料:
Stack Overflow
收藏
评论
共 4 个回答
高赞 时间 活跃

您可以使用PyYAML来解析YAML文件。

由于PyYAML无法理解OpenCV数据类型,因此您需要为要加载的每种OpenCV数据类型指定一个构造函数。例如:

import yaml
def opencv_matrix(loader, node):
    mapping = loader.construct_mapping(node, deep=True)
    mat = np.array(mapping["data"])
    mat.resize(mapping["rows"], mapping["cols"])
    return mat
yaml.add_constructor(u"tag:yaml.org,2002:opencv-matrix", opencv_matrix)

完成此操作后,加载yaml文件很简单:

with open(file_name) as fin:
    result = yaml.load(fin.read())

结果将是一个dict,其中的键是您保存在YAML中的名称的名称。

收藏
评论

除了@misha的响应外,OpenCV YAML还是与Python不兼容。

不兼容的原因如下:

  1. OpenCV创建的Yaml在“:”后没有空格。而Python需要它。 [例如:对于Python,它应该是a: 2 ,而不是a:2 ]
  2. OpenCV创建的YAML文件的第一行是错误的。将“%YAML:1.0”转换为“%YAML 1.0”。或在阅读时跳过第一行。

以下功能负责提供该功能:

import yaml
import re
def readYAMLFile(fileName):
    ret = {}
    skip_lines=1    # Skip the first line which says "%YAML:1.0". Or replace it with "%YAML 1.0"
    with open(scoreFileName) as fin:
        for i in range(skip_lines):
            fin.readline()
        yamlFileOut = fin.read()
        myRe = re.compile(r":([^ ])")   # Add space after ":", if it doesn't exist. Python yaml requirement
        yamlFileOut = myRe.sub(r': \1', yamlFileOut)
        ret = yaml.load(yamlFileOut)
    return ret

outDict = readYAMLFile("file.yaml")

注意:以上回复仅适用于Yaml。 XML有自己的问题,我还没有完全探讨过。

收藏
评论

我写了一个小片段来用Python读写与FileStorage兼容的YAML:

# A yaml constructor is for loading from a yaml node.
# This is taken from @misha 's answer: http://stackoverflow.com/a/15942429
def opencv_matrix_constructor(loader, node):
    mapping = loader.construct_mapping(node, deep=True)
    mat = np.array(mapping["data"])
    mat.resize(mapping["rows"], mapping["cols"])
    return mat
yaml.add_constructor(u"tag:yaml.org,2002:opencv-matrix", opencv_matrix_constructor)

# A yaml representer is for dumping structs into a yaml node.
# So for an opencv_matrix type (to be compatible with c++'s FileStorage) we save the rows, cols, type and flattened-data
def opencv_matrix_representer(dumper, mat):
    mapping = {'rows': mat.shape[0], 'cols': mat.shape[1], 'dt': 'd', 'data': mat.reshape(-1).tolist()}
    return dumper.represent_mapping(u"tag:yaml.org,2002:opencv-matrix", mapping)
yaml.add_representer(np.ndarray, opencv_matrix_representer)

#examples 

with open('output.yaml', 'w') as f:
    yaml.dump({"a matrix": np.zeros((10,10)), "another_one": np.zeros((2,4))}, f)

with open('output.yaml', 'r') as f:
    print yaml.load(f)
收藏
评论

使用OpenCV 3.2中可用的FileStorage函数,我成功地使用了它:

import cv2
fs = cv2.FileStorage("calibration.xml", cv2.FILE_STORAGE_READ)
fn = fs.getNode("Camera_Matrix")
print (fn.mat())
收藏
评论
新手导航
  • 社区规范
  • 提出问题
  • 进行投票
  • 个人资料
  • 优化问题
  • 回答问题

关于我们

常见问题

内容许可

联系我们

@2020 AskGo
京ICP备20001863号