Using OpenCV FileStorage to read a XML file

I am trying to use FileStorage to read a XML file.

This is the code that I’m using

#include <opencv2/opencv.hpp>

int main(int argc, const char * argv[]) {
    
  cv::FileStorage fs("/Users/thewoz/Desktop/01.xml", cv::FileStorage::READ);
  
  return 0;
  
}

the code gives me the following error:

persistence.cpp:706: error: (-5:Bad argument) Input file is invalid in function 'open'

this is the xml file:

<?xml version="1.0"?>
<images>
"20170720_024951.jpg"
"20170720_025001.jpg"
"20170720_025014.jpg"
"20170720_025023.jpg"
"20170720_025034.jpg"
"20170720_025048.jpg"
"20170720_025103.jpg"
"20170720_025115.jpg"
"20170720_025124.jpg"
"20170720_025133.jpg"
"20170720_025147.jpg"
"20170720_025155.jpg"
"20170720_025211.jpg"
</images>

I don’t understand what the problem is.

It’s not for reading arbitrary XML files.

Ah,
That was not clear at all.
So I can’t load any XML file?
Which ones can I open?
This doesn’t seem to me to be written in a big way in the documentation.

crosspost:

OpenCV does not read arbitrary XML.

cv::FileStorage is made to store and read OpenCV types like cv::Mat only. It assumes a specific structure to the file. This is specific to cv::FileStorage.

For your data as it is formatted, you need to use a library for XML in general. OpenCV is not supposed to read arbitrary XML.


If you can change your file’s format to fit cv::FileStorage, then sure, you can use it to read the file.

cv:FileStorage would produce this format:

# images = ['20170720_024951.jpg', '20170720_025001.jpg', '20170720_025014.jpg', '20170720_025023.jpg', '20170720_025034.jpg', '20170720_025048.jpg', '20170720_025103.jpg', '20170720_025115.jpg', '20170720_025124.jpg', '20170720_025133.jpg', '20170720_025147.jpg', '20170720_025155.jpg', '20170720_025211.jpg']

fs = cv.FileStorage(
    "opencv-filestorage.xml",
    cv.FileStorage_WRITE | cv.FileStorage_FORMAT_XML)
fs.write("images", images)
fs.release()

The XML file:

<?xml version="1.0"?>
<opencv_storage>
<images>
  "20170720_024951.jpg" "20170720_025001.jpg" "20170720_025014.jpg"
  "20170720_025023.jpg" "20170720_025034.jpg" "20170720_025048.jpg"
  "20170720_025103.jpg" "20170720_025115.jpg" "20170720_025124.jpg"
  "20170720_025133.jpg" "20170720_025147.jpg" "20170720_025155.jpg"
  "20170720_025211.jpg"</images>
</opencv_storage>

That format you can read with cv::FileStorage.

fs = cv.FileStorage(
    "opencv-filestorage.xml",
    cv.FileStorage_READ | cv.FileStorage_FORMAT_XML)
node = fs.getNode("images")
assert node.isSeq()
print(node.size(), "images")
images = [
    node.at(i).string()
    for i in range(node.size())
]
2 Likes

Thank you very much for the explanation and sorry for the crosspost