how to save std::vector to a text file i

2020-08-01 05:47发布

问题:

In my code, i'm inserting the key points to a vector as shown in the code, can anyone tell me how to save this to a text file.

Mat object = imread("face24.bmp",  CV_LOAD_IMAGE_GRAYSCALE);

    if( !object.data )
    {
    // std::cout<< "Error reading object " << std::endl;
    return -2;
    }

    //Detect the keypoints using SURF Detector

    int minHessian = 500;

    SurfFeatureDetector detector( minHessian );

    std::vector<KeyPoint> kp_object;

    detector.detect( object, kp_object );

i want to save the kp_object vecor to a text file.

回答1:

I assume that KeyPoint is the OpenCV KeyPoint class. In this case you can just add at the end of the code you posted:

std::fstream outputFile;
outputFile.open( "outputFile.txt", std::ios::out ) 
for( size_t ii = 0; ii < kp_object.size( ); ++ii )
   outputFile << kp_object[ii].pt.x << " " << kp_object[ii].pt.y <<std::endl;
outputFile.close( );

In your includes add

#include <fstream>    


回答2:

You can use the FileStorage to write and read data without writing your own serialization code. For writing you can use:

std::vector<KeyPoint> keypointvector;
cv::Mat descriptormatrix
// do some detection and description
// ...
cv::FileStorage store("template.bin", cv::FileStorage::WRITE);
cv::write(store,"keypoints",keypointvector;
cv::write(store,"descriptors",descriptormatrix);
store.release();

and for reading you can do something similar:

cv::FileStorage store("template.bin", cv::FileStorage::READ);
cv::FileNode n1 = store["keypoints"];
cv::read(n1,keypointvector);
cv::FileNode n2 = store["descriptors"];
cv::read(n2,descriptormatrix);
store.release();

This is for binary files of course. It actually depends what you want to facilitate; if you later want to parse the txt file into Matlab, you will encounter that it's pretty slow.



回答3:

I would suggest you to take the effort to implement boost/serialization.

it's a bit overkill to just save/restore a single structure, but it's future proofs, and worth learning.

With a fictious structure declaration:

#include <boost/archive/text_oarchive.hpp>
#include <boost/serialization/vector.hpp>
#include <fstream>

struct KeyPoints {
    int x, y;
    std::string s;

    /* this is the 'intrusive' technique, see the tutorial for non-intrusive one */
    template<class Archive>
    void serialize(Archive & ar, const unsigned int version)
    {
        ar & x;
        ar & y;
        ar & s;
    }
};

int main(int argc, char *argv[])
{
    std::vector<KeyPoints> v;
    v.push_back( KeyPoints { 10, 20, "first" } );
    v.push_back( KeyPoints { 13, 23, "second" } );

    std::ofstream ofs("filename");
    boost::archive::text_oarchive oa(ofs);
    oa << v;
}

that's all