Создание файла XML в OpenCV - PullRequest
0 голосов
/ 29 июля 2011

Я создал файл XML, но при попытке прочитать его я получаю сообщение об ошибке дублирующего ключа. Открыв файл XML, я заметил, что ничего не было вложено, и все рассматривалось как отдельный узел. Мне было интересно, есть ли способ правильно создать файл XML и иметь возможность проанализировать его. Ниже я включил свой код для записи XML-файла, мой XML-вывод и то, что я хотел бы, чтобы это было.

XML-код:

// 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:

<?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.7674386596679687e+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>
...

Ожидаемый результат

<?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>

Спасибо

Ответы [ 4 ]

2 голосов
/ 30 июля 2011

Вы можете встроить узел в другой узел.Сделайте это так (используя "{" и "}"):

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;
1 голос
/ 19 марта 2015

На самом деле мы видим ошибку «Дублированный ключ» в строке opencv / modules / core / src / persistence.cpp 711 Кажется, ключ имеет отношение к имени узла в вашем XML-файле: если у вас есть много узлов сто же имя, как показано ниже, у него будет дублированный ключ. И даже если вы не читали, а просто открыли этот файл, это произойдет. Итак, просто измените имена узлов, как насчет добавления индекса "node_1"?

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

0 голосов
/ 29 июля 2011

Файловое хранилище не предназначено для этого типа использования, однако вы можете использовать XML-парсер / писатель, самый простой, быстрый и самый модный из них - Xerces-C. Вы можете скачать его здесь

На самом деле, объект хранилища файлов создан для хранения простых данных, таких как калибровка, от одной среды выполнения к другой ... Из того, что я знаю, нет способа структурировать узлы между собой ...

Julien

РЕДАКТИРОВАТЬ:

ЧТЕНИЕ ДАННЫХ С МАТА

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);
    }
}

НАПИСАТЬ С XERCES-C

  • Пример "DOMPrint" показывает, как писать в документе с помощью сериализатора ...

Тем не менее, позвольте мне сказать вам, что я думаю, что OpenCV достаточно для вашего примера, является ли большой проблемой то, что ваши данные находятся в узлах рядом друг с другом? Я попытаюсь найти более простой способ, дайте мне подумать об этом, я опубликую здесь (все же, вы можете попробовать Xerces-C, это здорово и полезно)

0 голосов
/ 29 июля 2011

Вы также можете попробовать использовать JSON, который является более быстрым и простым для интерпретации

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...