How to read / write a matrix from a persistent XML / YAML file in OpenCV 3 using python?

I was trying to read and write matrices to persistent file storage (like XML) using anaconda current cv2

(which is OpenCV 3.x in my opinion). I have looked at this solution online and people are linking to something like this:

object = cv2.cv.Load(file)
object = cv2.cv.Save(file)

      

source . This doesn't work with the current anaconda python cv2

. People are suggesting solutions like this yaml example , but I'm confused as to why so many codeplates are required for this simple function. find this acceptable solution. I want something as simple as the old solution.

+3


source to share


1 answer


I knew how to solve this problem before I asked about it, but the only reason I knew how to solve this is because I also learned to do it concurrently in C ++. How it is done in the latest opencv update is not specified at all in the documentation . I couldn't find anywhere on the net with a solution to this, so hopefully those of you who don't use C ++ can figure out how to do this in python with a lot of difficulty.

This minimal example should be sufficient to show how this process works. Actually the current python shell for opencv looks more like the C ++ version and you are now using cv2.FileStorage

directly instead of cv2.cv.Save

and cv2.cv.Load

.

Python cv2.FileStorage

is now its own file handler just like inside C ++. In C ++, if you want to write to a file with FileStorage, you must 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 need to do the following



#notice how its almost exactly the same, imagine cv2 is the namespace for cv 
#in C++, 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, 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 read the matrix then, this is a little 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 other wise 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 python read and write 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>

      

+5


source







All Articles