How this is done in the most recent update of opencv is not stated at all in the documentation.
This minimal example should be enough to show you how the process works. Effectively, the current Python wrapper for OpenCV looks much more like the C++ version, and you now use cv2.FileStorage
directly instead of cv2.cv.Save
and cv2.cv.Load
.
The Python cv2.FileStorage
now is its own file handler like it is inside C++. In C++, if you wanted to write to a file with FileStorage, you would do the following:
cv::FileStorage opencv_file("test.xml", cv::FileStorage::WRITE);
cv::Mat file_matrix;
file_matrix = (cv::Mat_<int>(3, 3) << 1, 2, 3,
3, 4, 6,
7, 8, 9);
opencv_file << "my_matrix" << file_matrix
opencv_file.release();
And to read you would do the following:
cv::FileStorage opencv_file("test.xml", cv::FileStorage::READ);
cv::Mat file_matrix;
opencv_file["my_matrix"] >> file_matrix;
opencv_file.release();
In Python, if you want to write, you have to do the following:
# Notice how it’s almost exactly the same. Imagine cv2 is the namespace for cv.
# In C++, the only difference is FILE_STORGE_WRITE is exposed directly in cv2
cv_file = cv2.FileStorage("test.xml", cv2.FILE_STORAGE_WRITE)
# Creating a random matrix
matrix = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
print("write matrix\n", matrix)
# This corresponds to a key value pair, and internally OpenCV takes your NumPy
# object and transforms it into a matrix just
# like you would do with << in C++
cv_file.write("my_matrix", matrix)
# Note you *release*; you don't close() a FileStorage object
cv_file.release()
If you want to then read the matrix it is a bit more contrived.
# Just like before, we specify an enum flag, but this time it is
# FILE_STORAGE_READ
cv_file = cv2.FileStorage("test.xml", cv2.FILE_STORAGE_READ)
# For some reason __getattr__ doesn't work for FileStorage object in Python.
# However, in the C++ documentation, getNode, which is also available,
# does the same thing.
# Note we also have to specify the type to retrieve, otherwise we only get a
# FileNode object back instead of a matrix
matrix = cv_file.getNode("my_matrix").mat()
print("read matrix\n", matrix)
cv_file.release()
The output of the read and write Python examples should be:
write matrix
[[1 2 3]
[4 5 6]
[7 8 9]]
read matrix
[[1 2 3]
[4 5 6]
[7 8 9]]
And the XML looks like this:
<?xml version="1.0"?>
<opencv_storage>
<my_matrix type_id="opencv-matrix">
<rows>3</rows>
<cols>3</cols>
<dt>i</dt>
<data>
1 2 3 4 5 6 7 8 9</data></my_matrix>
</opencv_storage>