Reputation: 901
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;
}
Upvotes: 4
Views: 12603
Reputation: 131
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).
Upvotes: 0
Reputation: 248
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++;
Upvotes: 0
Reputation: 39796
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;
Upvotes: 13
Reputation: 153840
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");
}
}
}
}
Upvotes: 0