Paweł Jastrzębski
Paweł Jastrzębski

Reputation: 746

OpenCV fileStorage XML format - how to write and read multiple structures of the same type in one file

I am trying to implement writing multiple values to a XML file using OpenCV library.

I am trying to save one of the structures which I use in my project:

if (validCalib)
{ 
    QString calpath = path() + "/" + "calibration.xml"; 

    for (int i = 0; i < calibrations_.size(); ++i) 
    {
        QLOGX(" Writing calibration no. " << i); 
        calibrations_[i]->append(calpath.toStdString()); 
        xml.writeTextElement(XML_CALIBSTRUCT, calpath); 
    } 
} 

The line calibrations_[i]->append(calpath.toStdString()); is a wrapper around the following code:

void Calibration3D::append(const std::string &path) const
{
LOGX("Storing calibration in: '" << path << "'");

cv::FileStorage fsCal(path, cv::FileStorage::APPEND);
fsCal << "imgSizeW" << imgSize_.width;
fsCal << "imgSizeH" << imgSize_.height;
fsCal << "error" << error_;

fsCal << "cam1M" << cam1_.camera_;
fsCal << "dist1M" << cam1_.distort_;
fsCal << "cam1Err" << cam1_.error_;
fsCal << "cam2M" << cam2_.camera_;
fsCal << "dist2M" << cam2_.distort_;
fsCal << "cam2Err" << cam2_.error_;

fsCal << "rot" << rot_;
fsCal << "trans" << trans_;
fsCal << "ess" << ess_;
fsCal << "fund" << fund_;
}

It generates a following file:

<?xml version="1.0"?>
<opencv_storage>
<imgSizeW>1624</imgSizeW>
<imgSizeH>1232</imgSizeH>
<error>1.0434992866920401e-001</error>
<cam1M type_id="opencv-matrix">
  <rows>3</rows>
  <cols>3</cols>
  <dt>d</dt>
  <data>
    5.8336770199129896e+003 0. 7.9461884987678354e+002 0.
    5.8346113022077216e+003 6.2767580661716852e+002 0. 0. 1.</data></cam1M>
<dist1M type_id="opencv-matrix">
  <rows>1</rows>
  <cols>5</cols>
  <dt>d</dt>
  <data>
    -4.1521842761754475e-002 -1.2257987732483255e+000
    1.8424136500047315e-003 -1.3132630808037672e-003 0.</data></dist1M>
<cam1Err>9.9465113482762754e-002</cam1Err>
<cam2M type_id="opencv-matrix">
  <rows>3</rows>
  <cols>3</cols>
  <dt>d</dt>
  <data>
    5.8076598763871389e+003 0. 8.1187260416598792e+002 0.
    5.8094240172010641e+003 6.3986386929850755e+002 0. 0. 1.</data></cam2M>
<dist2M type_id="opencv-matrix">
  <rows>1</rows>
  <cols>5</cols>
  <dt>d</dt>
  <data>
    -9.2121454522962165e-002 1.8926990233429226e+000
    1.7827799056532767e-003 -5.5230657283086685e-004 0.</data></dist2M>
<cam2Err>1.0166116306730072e-001</cam2Err>
<rot type_id="opencv-matrix">
  <rows>3</rows>
  <cols>3</cols>
  <dt>d</dt>
  <data>
    8.4241672981065119e-001 -5.8573511631213023e-003
    -5.3879471487058994e-001 1.0809897944575920e-002
    9.9992338290376193e-001 6.0311216804594652e-003
    5.3871810758647809e-001 -1.0905033683970737e-002
    8.4241550365528961e-001</data></rot>
<trans type_id="opencv-matrix">
  <rows>3</rows>
  <cols>1</cols>
  <dt>d</dt>
  <data>
    5.0365870692993354e+002 -5.1969545995371860e+000
    1.3064843970613484e+002</data></trans>
<ess type_id="opencv-matrix">
  <rows>3</rows>
  <cols>3</cols>
  <dt>d</dt>
  <data>
    -4.2119898469169144e+000 -1.3058175683709450e+002
    -5.1659517636726635e+000 -1.6126963413464023e+002
    4.7271613740233587e+000 -4.9468259208850623e+002
    9.8225007195261931e+000 5.0358967767424525e+002
    2.3753527526426321e-001</data></ess>
<fund type_id="opencv-matrix">
  <rows>3</rows>
  <cols>3</cols>
  <dt>d</dt>
  <data>
    2.7779018317104696e-008 8.6107808772984268e-007
    -3.6379467295147945e-004 1.0632864450905678e-006
    -3.1162232035265673e-008 1.8201493171578327e-002
    -1.0791410825328929e-003 -1.9964962350893754e-002 1.</data></fund>
 <!-- resumed -->

<imgSizeW>1624</imgSizeW>
<imgSizeH>1232</imgSizeH>
<error>7.4143478139918727e+001</error>
<cam1M type_id="opencv-matrix">
  <rows>3</rows>
  <cols>3</cols>
  <dt>d</dt>
  <data>
    4.5249661359074507e+003 0. 3.8802378752536885e+002 0.
    4.7322013075897985e+003 -4.6265793355141220e+001 0. 0. 1.</data></cam1M>
<dist1M type_id="opencv-matrix">
  <rows>1</rows>
  <cols>5</cols>
  <dt>d</dt>
  <data>
    4.9921668140553797e+000 -3.9127832752862915e+001
    -1.2848597924228053e-001 5.1729958527179563e-002 0.</data></dist1M>
<cam1Err>9.9465117306014511e-002</cam1Err>
<cam2M type_id="opencv-matrix">
  <rows>3</rows>
  <cols>3</cols>
  <dt>d</dt>
  <data>
    4.0809201332391053e+003 0. -2.5863160533898072e+003 0.
    5.5465207503753049e+002 -1.0031409700981827e+001 0. 0. 1.</data></cam2M>
<dist2M type_id="opencv-matrix">
  <rows>1</rows>
  <cols>5</cols>
  <dt>d</dt>
  <data>
    2.1904296242925554e+000 -3.9306686802274299e-001
    1.8437752313918845e-001 -6.1134319745319177e-001 0.</data></dist2M>
<cam2Err>1.0166116351399195e-001</cam2Err>
<rot type_id="opencv-matrix">
  <rows>3</rows>
  <cols>3</cols>
  <dt>d</dt>
  <data>
    7.8478700811122082e-001 -3.2115568696367880e-001
    -5.3006450233035418e-001 3.5509697225959491e-001
    9.3396756794800728e-001 -4.0133805119286346e-002
    5.0795225385060261e-001 -1.5672781103611425e-001
    8.4700702538758266e-001</data></rot>
<trans type_id="opencv-matrix">
  <rows>3</rows>
  <cols>1</cols>
  <dt>d</dt>
  <data>
    1.8785463165085166e+003 1.2890651672036026e+002
    -1.3964346923814824e+003</data></trans>
<ess type_id="opencv-matrix">
  <rows>3</rows>
  <cols>3</cols>
  <dt>d</dt>
  <data>
    5.6134808692706054e+002 1.2840214772478846e+003
    5.3140487474538034e+001 -2.0501156396900251e+003
    7.4289339504802365e+002 -8.5094146734464744e+002
    5.6590194965857836e+002 1.7959003954385691e+003
    -7.0644431417887716e+000</data></ess>
<fund type_id="opencv-matrix">
  <rows>3</rows>
  <cols>3</cols>
  <dt>d</dt>
  <data>
    -7.7975382126785714e-007 -1.7054919545854610e-006
    -1.1035803155575678e-004 2.0952752203606181e-005
    -7.2600788482834914e-006 3.0886930796631743e-002
    -5.0144317270169004e-003 -1.4218361475375632e-002 1.</data></fund>
    </opencv_storage>

When I write only one instance of the structure, there is no problem with reading it, but when I'm trying to open the file presented above (which was saved by the code sample presented at the beginning of the post) the program crashes at the opening of that file:

else if (name == XML_CALIBSTRUCT)
    {
        QString filename = xml.readElementText();

        cv::FileStorage fsCal(filename.toStdString(), cv::FileStorage::READ); 

Upvotes: 0

Views: 3799

Answers (1)

morynicz
morynicz

Reputation: 2342

Try to encapsulate the instances of structure with { and }. Here is an answer to similar question with a link to some working code. Sorry for half-baked answer.

Upvotes: 1

Related Questions