0

I wrote a code for watershed segmentation in C API. Now I am converting all those into C++. so, cvsaveimage becomes imwrite. But when I use imwrite ,all i get is a black image.

this is the code:-

Mat img8bit;
Mat img0;
img0 = imread("source.png", 1);           
Mat wshed(img0.size(), CV_32S);
wshed.setTo(cv::Scalar::all(0));
////after performing watershed segmentation and
        // displaying the watershed image from wshed//
wshed.convertTo(img8bit, CV_32FC3, 255.0);
imwrite("Watershed.png", img8bit);

The original image that I want to save is in wshed. I saw suggestions from the net that we need to convert it to 16 bit or higher so that the imwrite saves it right. Like you see,I tried that. But the wshed image is being displayed correctly when using imshow.The img0 is grey image/black and white while the wshed image is coloured. any help on this?

Edit- I changed the 4th line to

Mat wshed(img0.size(), CV_32FC3);
herohuyongtao
  • 49,413
  • 29
  • 133
  • 174
Abhishek V. Pai
  • 241
  • 1
  • 10
  • 27
  • 8 bit is easiest for writing/displaying the image! And in fact in your code you don't convert to 16 bit but you convert to float. – Micka Jan 12 '16 at 09:03
  • 3
    `wshed.setTo(cv::Scalar::all(0));` makes it all black...doesnt it? – Mailerdaimon Jan 12 '16 at 09:16
  • @micka- pls show me how to do that. – Abhishek V. Pai Jan 12 '16 at 09:30
  • @Mailerdaimon- Yes, But its just for initialization,The output is clearly view-able. And also, I first thought that was the reason ans tried commenting off that line but still nothing happened. – Abhishek V. Pai Jan 12 '16 at 09:30
  • 1
    @AbhishekV.Pai can you please print wshed.type() (after performing the algorithm) and post it? You say it is viewable, so you used cv::imshow to display it? – Micka Jan 12 '16 at 10:00
  • @micka- Yes I used imshow_- imshow("watershed transform", wshed); Printing wshed.type() gives me 16 – Abhishek V. Pai Jan 12 '16 at 10:12
  • Ummm... `imshow("watershed transform", wshed);` isnt showing the same image you are writing... It would need to be `imshow("watershed transform", img8bit);` – GPPK Jan 12 '16 at 12:12
  • @GPPK- I have no problem with showing the image. It saving the image,that I am having the problem with. – Abhishek V. Pai Jan 12 '16 at 12:43

2 Answers2

1

When calling Mat::convertTo() with a scalar (255 in your case), the values of every matrix item will be multiplied by this scalar value. This will cause all most every result pixel values exceed 255 (i.e. white pixels) except those of 0s where they remain 0 (i.e. black pixels). This is why you will get the black-white pixel in the end.

To make it work, simply change it to:

wshed.convertTo(img8bit, CV_32FC3);
herohuyongtao
  • 49,413
  • 29
  • 133
  • 174
0

You said:

The original image that I want to save is in wshed. I saw suggestions from the net that we need to convert it to 16 bit or higher so that the imwrite saves it right.

If saving the image does not work you should keep in mind that the image data has to be either 8-Bits or 16-Bit unsigned when using the imwrite Function, not 16-Bits or higher.

This is stated in the documentation:

The function imwrite saves the image to the specified file. The image format is chosen based on the filename extension (see imread() for the list of extensions). Only 8-bit (or 16-bit unsigned (CV_16U) in case of PNG, JPEG 2000, and TIFF) single-channel or 3-channel (with ‘BGR’ channel order) images can be saved using this function. If the format, depth or channel order is different, use Mat::convertTo() , and cvtColor() to convert it before saving. Or, use the universal FileStorage I/O functions to save the image to XML or YAML format.

Mailerdaimon
  • 6,003
  • 3
  • 35
  • 46