I am trying to use FileStorage to read a XML file with this code:
#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 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.
OpenCV does not read arbitrary XML. With some changes to your file, it could read the file. If you can't change your file, you'll need to use a generic XML library.
cv::FileStorage
is made specifically to store and read OpenCV types (e.g. cv::Mat
). It assumes a specific structure to the file. This is specific to cv::FileStorage
. One such requirement is that all the data is contained in a <opencv_storage>
tag.
If you can change your file's format to fit cv::FileStorage
, then sure, you can use it to read the file.
cv:FileStorage
to write a list of strings:
# 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()
Pardon the Python, C++ would be mostly equivalent.
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")
assert all(
node.at(i).isString() for i in range(node.size()))
images = [
node.at(i).string()
for i in range(node.size())
]