开发者

Creating an XML file in OpenCV

开发者 https://www.devze.com 2023-03-23 16:09 出处:网络
I have created an XML file, but when I try to read it in I get an error about a duplicate key. When I opened the XML file I noticed that nothing was nested and everything was treated as it\'s own indi

I have created an XML file, but when I try to read it in I get an error about a duplicate key. When I opened the XML file I noticed that nothing was nested and everything was treated as it's own individual node. I was wondering if there was a way to properly create the XML file and be able to parse through it as well. Below I have included my code for writing an XML file out, my XML output, and what I would like it to be.

XML Code:

// Open up the file so that we can write to it
cv::FileStorage fs;
fs.open(szFileName, cv::FileStorage::WRITE);

// Check if we actually created the file
if(fs.isOpened())
{
    fs << "Total_Images" << (int)vImages.size();
    //cv::write(fs, "Total Images", (int)vImages.size());

    for(int i = 0; i < (int)vImages.size(); i++)
    {
        char szSize[8];
        string szNode;
        szNode = "image_";
        itoa(i, szSize, 10);
        szNode += szSize;

        fs << "Node" << szNode;
        fs << "Width" << vImages[i]->GetWidth();
        fs << "Height" << vImages[i]->GetHeight();
        fs << "Keypoint_Size" << (int)vImages[i]->GetKeyPoints().size();

        for(int j = 0; j < vImages[i]->GetKeyPoints().size(); j++)
        {
            char szSize[256];
            fs << "Angle" << vImages[i]->GetKeyPoints()[j].angle;
            fs << "Class" << vImages[i]->GetKeyPoints()[j].class_id;
            fs << "Octave" << vImages[i]->GetKeyPoints()[j].octave;
            fs << "Pt_X" << vImages[i]->GetKeyPoints()[j].pt.x;
            fs << "Pt_Y" << vImages[i]->GetKeyPoints()[j].pt.y;
            fs << "Response" << vImages[i]->GetKeyPoints()[j].response;
            fs << "Size" << vImages[i]->GetKeyPoints()[j].size;
        }

        fs << "Descriptors" << vImages[i]->GetDescriptors();
    }

    fs.release();
}

XML Output:

<?xml version="1.0"?>
<opencv_storage>
<Total_Images>1</Total_Images>
<Node>image_0</Node>
<Width>500</Width>
<Height>266</Height>
<Keypoint_Size>268</Keypoint_Size>
<Angle>8.7332672119140625e+001</Angle>
<Class>0</Class>
<Octave>-1</Octave>
<Pt_X>1.7401049804687500e+002</Pt_X>
<Pt_Y>6.5084960937500000e+001</Pt_Y>
<Response>0.</Response>
<Size>1.1386331558227539e+001</Size>
<Angle>9.3859291076660156e+001</Angle>
<Class>0</Class>
<Octave>-1</Octave>
<Pt_X>1.767438659开发者_JS百科6679687e+002</Pt_X>
<Pt_Y>6.4983604431152344e+001</Pt_Y>
<Response>0.</Response>
<Size>1.2262072563171387e+001</Size>
<Angle>9.8604904174804688e+001</Angle>
<Class>0</Class>
<Octave>-1</Octave>
<Pt_X>1.1859683990478516e+002</Pt_X>
<Pt_Y>6.6855834960937500e+001</Pt_Y>
<Response>0.</Response>
<Size>1.1112688064575195e+001</Size>
...

Expected Output

<?xml version="1.0"?>
<opencv_storage>
<Total_Images>1</Total_Images>
<Node>image_0
    <Width>500</Width>
    <Height>266</Height>
    <Keypoint_Size>268</Keypoint_Size>
    <KeyPoint>
            <Angle>8.7332672119140625e+001</Angle>
        <Class>0</Class>
        <Octave>-1</Octave>
        <Pt_X>1.7401049804687500e+002</Pt_X>
        <Pt_Y>6.5084960937500000e+001</Pt_Y>
        <Response>0.</Response>
        <Size>1.1386331558227539e+001</Size>
    </KeyPoint>
    <KeyPoint>
        <Angle>9.3859291076660156e+001</Angle>
        <Class>0</Class>
        <Octave>-1</Octave>
        <Pt_X>1.7674386596679687e+002</Pt_X>
        <Pt_Y>6.4983604431152344e+001</Pt_Y>
        <Response>0.</Response>
        <Size>1.2262072563171387e+001</Size>
    </KeyPoint>
    <KeyPoint>
        <Angle>9.8604904174804688e+001</Angle>
        <Class>0</Class>
        <Octave>-1</Octave>
        <Pt_X>1.1859683990478516e+002</Pt_X>
        <Pt_Y>6.6855834960937500e+001</Pt_Y>
        <Response>0.</Response>
        <Size>1.1112688064575195e+001</Size>
    </KeyPoint>
    ...
</Node>

Thanks


You can embedd a node inside another node. Do it like this (using "{" and "}" ):

FileStorage fs;  // Open it and check that it is opened;

fs << "SimpleData"  << 1;

fs << "Structure << "{";
fs << "firstField"  << 1;
fs << "secondField"  << 2;
fs << "}"; // End of structure node

fs << "SimpleData2"  << 2;


Actually we can see the "Duplicated key" error in opencv/modules/core/src/persistence.cpp line 711 The key seems have sth to do with the node name in your xml file: once you have many nodes with the same name like below,it will has duplicated key.And even you haven't read but just open this file,it will occur.So, just modify your node names,how about add an index "node_1"?

<opencv_storage>
<mynodes>
    <node>1</node>
    <node>2</node>
    <node>3</node>
    <node>4</node>
    ...
    <node>10</node>
</mynodes>


You can also try to use JSON which is more fash and simple to interpret


File storage is not designed for this type of use, however you can use a XML-parser/writter, the easiest, fastest and most fashion one is Xerces-C. You can download it here

Actually, the filestorage object is made to store simple datas like calibration from one runtime to the other... From what i know there is no way to structure the nodes between each others...

Julien,

EDIT :

READ DATA FROM A MAT

for(int i=0;i<img.rows;i++) {
    unsigned char* row = img.data + i * img.step;
    for(int j=0;j<img.cols;j++) {
    unsigned char* channB = (row + 3*j);
    unsigned char* channG = (row + 3*j + 1);
    unsigned char* channR = (row + 3*j + 2);
    }
}

WRITE WITH XERCES-C

  • The "DOMPrint" example shows how to write in a document with a serializer...

However, let me tell you that i think that OpenCV is enough for your example, is it a big problem that yuor datas are in nodes next to each other ? I'll try to find an easier way, let me think of it, i'll post back here (still, you sould try Xerces-C it's great and usefull)

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号