[英]FileStorage for OpenCV Python API
I'm currently using FileStorage class for storing matrices XML/YAML using OpenCV C++ API.我目前正在使用FileStorage类使用 OpenCV C++ API 存储矩阵XML/YAML 。
However, I have to write a Python Script that reads those XML/YAML files.但是,我必须编写一个 Python 脚本来读取这些XML/YAML文件。
I'm looking for existing OpenCV Python API that can read the XML/YAML files generated by OpenCV C++ API我正在寻找可以读取由OpenCV C++ API生成的XML/YAML文件的现有 OpenCV Python API
You can use PyYAML to parse the YAML file.您可以使用PyYAML来解析 YAML 文件。
Since PyYAML doesn't understand OpenCV data types, you need to specify a constructor for each OpenCV data type that you are trying to load.由于 PyYAML 不理解 OpenCV 数据类型,因此您需要为您尝试加载的每个 OpenCV 数据类型指定一个构造函数。 For example:例如:
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)
Once you've done that, loading the yaml file is simple:完成后,加载 yaml 文件很简单:
with open(file_name) as fin:
result = yaml.load(fin.read())
Result will be a dict, where the keys are the names of whatever you saved in the YAML.结果将是一个字典,其中键是您在 YAML 中保存的任何内容的名称。
Using the FileStorage functions available in OpenCV 3.2, I've used this with success:使用 OpenCV 3.2 中可用的 FileStorage 函数,我成功地使用了它:
import cv2
fs = cv2.FileStorage("calibration.xml", cv2.FILE_STORAGE_READ)
fn = fs.getNode("Camera_Matrix")
print (fn.mat())
In addition to @misha's response, OpenCV YAML's are somewhat incompatible with Python.除了@misha 的回应之外,OpenCV YAML 与 Python 有点不兼容。
Few reasons for incompatibility are:不兼容的几个原因是:
a: 2
, and not a:2
for Python] [例如:它应该是a: 2
,而不是 Python a:2
]The following function takes care of providing that:以下函数负责提供:
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")
NOTE: Above response is applicable only for yaml's.注意:以上响应仅适用于 yaml。 XML's have their own share of problems, something I haven't explored completely. XML 有自己的问题,我还没有完全探讨过。
I wrote a small snippet to read and write FileStorage-compatible YAMLs in Python:我写了一个小片段来在 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)
To improve on the previous answer by @Roy_Shilkrot I added support for numpy vectors as well as matrices:为了改进@Roy_Shilkrot 之前的回答,我添加了对 numpy 向量和矩阵的支持:
# 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"])
if mapping["cols"] > 1:
mat.resize(mapping["rows"], mapping["cols"])
else:
mat.resize(mapping["rows"], )
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):
if mat.ndim > 1:
mapping = {'rows': mat.shape[0], 'cols': mat.shape[1], 'dt': 'd', 'data': mat.reshape(-1).tolist()}
else:
mapping = {'rows': mat.shape[0], 'cols': 1, 'dt': 'd', 'data': mat.tolist()}
return dumper.represent_mapping(u"tag:yaml.org,2002:opencv-matrix", mapping)
yaml.add_representer(np.ndarray, opencv_matrix_representer)
Example:例子:
with open('output.yaml', 'w') as f:
yaml.dump({"a matrix": np.zeros((10,10)), "another_one": np.zeros((5,))}, f)
with open('output.yaml', 'r') as f:
print yaml.load(f)
Output:输出:
a matrix: !!opencv-matrix
cols: 10
data: [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
0.0, 0.0, 0.0, 0.0, 0.0]
dt: d
rows: 10
another_one: !!opencv-matrix
cols: 1
data: [0.0, 0.0, 0.0, 0.0, 0.0]
dt: d
rows: 5
Though I could not control the order of rows, cols, dt, data.虽然我无法控制行、列、dt、数据的顺序。
pip install opencv-contrib-python for video support to install specific version use pip install opencv-contrib-python pip install opencv-contrib-python 视频支持安装特定版本使用 pip install opencv-contrib-python
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.