70

I want to dump the values of a matrix in OpenCV to the console using cout. I quickly learned that I do not understand OpenvCV's type system nor C++ templates well enough to accomplish this simple task.

Would a reader please post (or point me to) a little function or code snippet that prints a Mat?

Regards, Aaron

PS: Code that uses the newer C++ Mat interface as opposed to the older CvMat interface is preferential.

5 Answers 5

111

See the first answer to Accessing a matrix element in the "Mat" object (not the CvMat object) in OpenCV C++
Then just loop over all the elements in cout << M.at<double>(0,0); rather than just 0,0

Or better still with the C++ interface:

cv::Mat M;
cout << "M = " << endl << " "  << M << endl << endl;
4
  • 3
    Brilliant. I should haves shoved a Mat to cout in the first place just to see if someone had implemented <<. A little more experimentation and trust would have payed off for me.
    – ahoffer
    Commented Nov 3, 2011 at 19:31
  • I have just asked a question about this. Is the ostream operator<< available in 2.1 and where is this stuff documented? Commented Apr 4, 2012 at 15:09
  • @ahoffer, funny you mentioned that: docs.opencv.org/4.1.0/dc/d84/…
    – Anže
    Commented May 21, 2019 at 8:52
  • 3
    One thing to add: Make sure you include #include <opencv2/core.hpp> and not #include <opencv2/core/mat.hpp> as the operator is overloaded elsewhere. Commented Jan 23, 2020 at 13:34
10

If you are using opencv3, you can print Mat like python numpy style:

Mat xTrainData = (Mat_<float>(5,2) << 1, 1, 1, 1, 2, 2, 2, 2, 2, 2);

cout << "xTrainData (python)  = " << endl << format(xTrainData, Formatter::FMT_PYTHON) << endl << endl;

Output as below, you can see it'e more readable, see here for more information.

enter image description here

But in most case, there is no need to output all the data in Mat, you can output by row range like 0 ~ 2 row:

#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>

#include <iostream>
#include <iomanip>

using namespace cv;
using namespace std;

int main(int argc, char** argv)
{
    //row: 6, column: 3,unsigned one channel
    Mat image1(6, 3, CV_8UC1, 5);

    // output row: 0 ~ 2
    cout << "image1 row: 0~2 = "<< endl << " "  << image1.rowRange(0, 2) << endl << endl;

    //row: 8, column: 2,unsigned three channel
    Mat image2(8, 2, CV_8UC3, Scalar(1, 2, 3));

    // output row: 0 ~ 2
    cout << "image2 row: 0~2 = "<< endl << " "  << image2.rowRange(0, 2) << endl << endl;

    return 0;
}

Output as below:

enter image description here

3
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>

#include <iostream>
#include <iomanip>

using namespace cv;
using namespace std;

int main(int argc, char** argv)
{
    double data[4] = {-0.0000000077898273846583732, -0.03749374753019832, -0.0374787251930463, -0.000000000077893623846343843};
    Mat src = Mat(1, 4, CV_64F, &data);
    for(int i=0; i<4; i++)
        cout << setprecision(3) << src.at<double>(0,i) << endl;

    return 0;
}
3

I think using the matrix.at<type>(x,y) is not the best way to iterate trough a Mat object! If I recall correctly matrix.at<type>(x,y) will iterate from the beginning of the matrix each time you call it(I might be wrong though). I would suggest using cv::MatIterator_

cv::Mat someMat(1, 4, CV_64F, &someData);;
cv::MatIterator_<double> _it = someMat.begin<double>();
for(;_it!=someMat.end<double>(); _it++){
    std::cout << *_it << std::endl;
}
0

Additionally to the above excellent answers, you can print out Mat values by FileStorage, of course if your case considers utilizing a file

// create our writer 
FileStorage fs("test.yml", FileStorage::WRITE);
fs << "Result" << Mat::eye(5,5, CV_64F);
// release the file 
fs.release();

// read file
FileStorage fs2("test.yml", FileStorage::READ);

Mat r2;
fs2["Result"] >> r2;
std::cout << r2 << std::endl;

fs2.release();

Not the answer you're looking for? Browse other questions tagged or ask your own question.