elmass
elmass

Reputation: 117

OpenCv see each pixel value in an image

I'm working on Connected Component Labeling (CCL) operation in OpenCv (in C++ language). To see whether CCL works reliably, I must check each pixel value in the image while debugging. I have tried saving the result of CCL as an image, however I could not reach digital values of the pixels. Is there any way of doing this during debugging operation?

Upvotes: 0

Views: 1784

Answers (3)

Miki
Miki

Reputation: 41765

As already mentioned by @Gombat and e.g. here, in Visual Studio you can install Image Watch.

If you want to save the values of a Mat to a text file, you don't need to reinvent anything (check OpenCV Mat: the basic image container).

You can for example save a csv file simply like:

Mat img;
// ... fill matrix somehow
ofstream fs("test.csv");
fs << format(img, "csv");

Full example:

#include <opencv2\opencv.hpp>
#include <iostream>
#include <fstream>

using namespace std;
using namespace cv;

int main()
{
    // Just a green image
    Mat3b img(10,5,Vec3b(0,255,0));

    ofstream fs("test.csv");
    fs << format(img, "csv");

    return 0;
}

Upvotes: 1

Gombat
Gombat

Reputation: 2084

Of course there is, but it depends on the type of image you use.

http://docs.opencv.org/doc/user_guide/ug_mat.html#accessing-pixel-intensity-values

Which IDE do you use for debugging? There is a Visual Studio opencv plugin:

http://opencv.org/image-debugger-plug-in-for-visual-studio.html https://visualstudiogallery.msdn.microsoft.com/e682d542-7ef3-402c-b857-bbfba714f78d

To simply print a cv::Mat of type CV_8UC1 to a text file, use the code below:

// create the image
int rows(4), cols(3);
cv::Mat img(rows, cols, CV_8UC1);

// fill image
for ( int r = 0; r < rows; r++ )
{
  for ( int c = 0; c < cols; c++ )
  {
    img.at<unsigned char>(r, c) = std::min(rows + cols - (r + c), 255);
  }
}

// write image to file
std::ofstream out( "output.txt" );

for ( int r = -1; r < rows; r++ )
{
  if ( r == -1 ){ out << '\t'; }
  else if ( r >= 0 ){ out << r << '\t'; }

  for ( int c = -1; c < cols; c++ )
  {
    if ( r == -1 && c >= 0 ){ out << c << '\t'; }
    else if ( r >= 0 && c >= 0 )
    {
      out << static_cast<int>(img.at<unsigned char>(r, c)) << '\t';
    }
  }
  out << std::endl;
}

Simply replace img, rows, cols with your vars and leave the "fill image" part aside and it should work. In the first row and column are the indices of that row / column. "output.txt" will be left in your debugging working directory you can specify in the projects debugging settings in visual studio.

Upvotes: 0

ChronoTrigger
ChronoTrigger

Reputation: 8617

Convert the CCL matrix into values in the range [0, 255] and save it as an image. For example:

cv::Mat ccl = ...; // ccl operation returning CV_8U
double min, max;
cv::minMaxLoc(ccl, &min, &max);
cv::Mat image = ccl * (255. / max);
cv::imwrite("ccl.png", image);

Or store all the values in a file:

std::ofstream f("ccl.txt");
f << "row col value" << std::endl;
for (int r = 0; r < ccl.rows; ++r) {
  unsigned char* row = ccl.ptr<unsigned char>(r);
  for (int c = 0; c < ccl.cols; ++c) {
    f << r << " " << c << " " << static_cast<int>(row[c]) << std::endl;
  }
}

Upvotes: 0

Related Questions