How to read the text file and create Mat object in C++
Asked Answered
P

4

4

Hi i have being able to write a Mat object in to a text file. As follows,

std::fstream outputFile;
    outputFile.open( "myFile.txt", std::ios::out ) ;

    outputFile << des_object.rows << std::endl;
    outputFile << des_object.cols << std::endl;

    for(int i=0; i<des_object.rows; i++)
    {
        for(int j=0; j<des_object.cols; j++)
        {
            outputFile << des_object.at<float>(i,j) << std::endl;
        }

    }
    outputFile.close( );

In my code in the first 2 lines im printing the row count and the column count to use when im reading it back. But im unable to read the text file and create the Mat Object again.

The following is the code i tried. Not sure whether my code is correct.

Mat des_object1;
    std::ifstream file("myFile.txt");
    std::string str; 
    int rows;
    int cols;
    int a = 0;
    while (std::getline(file, str))
    {
        int i = 0;
        int j = 0;

        if(a == 0){
            rows = std::stoi( str );
        }else if(a == 1){
            cols = std::stoi( str );
        }else{

            for(i; i< rows; i++)
            {
                for(j; j<cols; j++)
                {
                     des_object1.at<float>(i,j) = ::atof(str.c_str());
                     break;
                }
            }

        }
        ++a;
    }
Puffy answered 5/10, 2013 at 17:48 Comment(0)
I
13

it's probably far easier, to use the opencv FileStorage:

// write:
Mat m;
FileStorage fs("myfile.txt",FileStorage::WRITE);
fs << "mat1" << m;

// read:
FileStorage fs("myfile.txt",FileStorage::READ);
fs["mat1"] >> m;
Incivility answered 5/10, 2013 at 17:57 Comment(3)
This work when i write the mat in to the file. But when i read it give me an empty onePuffy
@berak, the link that you provided mentions that FileStorage works for xml/yaml files, nothing mentioned about .txt files. I tried reading a .txt file but it gave me an error: Parsing error: Valid xml should start with '<?xml ...?>'> in icvXMLParse.................Rodomontade
This actually works on txt files. Try imreading something into m and use the code to write it to myfile.txt. Take a look at the output if you're interested. Then read it back to m by the provided reading code and save it with imwrite; you'll see it's saved and the image is viewableTransmutation
P
0

You got your inner loops in the wrong location: You'd need to keep the counter around for each iteration reading a line. It can be done a lot simpler, though:

if (in >> rows >> cols) {
    // resize the matrix to its proper size
    for (int r(0); r!= rows; ++r) {
        for (int c(0); c != cols; ++c) {
            if (!(in >> mat[r][c])) {
                throw std:: runtime_error("failed to read matrix");
            }
        }
    }
}
Paronychia answered 5/10, 2013 at 17:57 Comment(0)
A
0

try something like this:

initialize these two outside the while loop

int k=0;
int l=0;

and instead of using the for loop

if(j<cols){
    des_object1.at<float>(k,l) = ::atof(str.c_str());
}else{
    k=0;
    l++;
    des_object1.at<float>(k,l) = ::atof(str.c_str());
}
j++;
Ardeen answered 5/10, 2013 at 19:20 Comment(0)
B
0

I wrote a method for reading a Mat from an .asc that should work for .txt too.

Maybe there are more stylish and efficient ways to do that, but this method works and is easy to understand.

Head

int Load_From_Path_Text(Mat *pMA_Out, string path)

Variables

ifstream        IS_File;
string          ST_Line;
stringstream    SS_Line;
unsigned int    rows        = 0;
unsigned int    cols        = 0;
unsigned int    y           = 0;
unsigned int    x           = 0;
float           F_Value;

Get Size

IS_File.open(path);
while(getline(IS_File, ST_Line))
{
    if(cols == 0)
    {
        SS_Line << ST_Line;
        while(SS_Line >> F_Value)
            cols++;
    }

    rows++;
}
IS_File.close();

Create Image

*pMA_Out = Mat(rows, cols, CV_32FC1);

Read Data

IS_File.open(path);
while(getline(IS_File, ST_Line))
{
    SS_Line.clear();
    SS_Line << ST_Line;
    x = 0;

    while(SS_Line >> F_Value)
    {
        pMA_Out->at<float>(y, x) = F_Value;
        x++;
    }

    y++;
}
IS_File.close();

Example

1 1 1 -2
1 2 1 0.5
1 1 3 2.1
1 1 1 1.5

turns to this (after beeing converted to CV_8UC1 using normalize with CV_MINMAX to be displayed).

Bandanna answered 8/10, 2018 at 11:17 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.