Reputation: 29
I need to convert a CV_8U image with 3 channels to an image which must be a single channel CV_32S. But when I'm trying to do so, the image I get is all black. I don't understand why my code is not working.
I'm dealing with a grayscale image, this is why I split the 3 channels image into a vector of single channel image, and then process only the first channel.
//markers->Image() returns a valid image, so this is not the problem
cv::Mat dst(markers->Image().size(), CV_32SC1);
dst = cv::Scalar::all(0);
std::vector<cv::Mat> vectmp;
cv::split(markers->Image(), vectmp);
vectmp.at(0).convertTo(dst, CV_32S);
//vectmp.at(0) is ok, but dst is black...?
Thank you in advance.
Upvotes: 2
Views: 4572
Reputation:
I believe this is what you are looking for. Convert your image to this, 8 bit, single channel. CV_8UC1. You are starting with a 8 bit image and changing it to 32 bit single channel? Why? Keep it 8 bit.
Upvotes: 0
Reputation: 1
I had the same problem, solved it indirectly by trying to convert a 8UC1 to 32S instead of 8UC3.
RgbToGray accept to create a gray image using 8UC3 or 8UC1 element type. 8UC1 image is my marker image.
I've done this in Opencvsharp :
Mat buf3 = new Mat(iplImageMarker);
buf3.ConvertTo(buf3, MatType.CV_32SC1);
iplImageMarker= (IplImage)buf3;
iplImageMarker=iplImageMarker* 256;
Upvotes: 0
Reputation: 21902
If you want to display your 32-bit image and see a meaningful result, you need to multiply all of its elements by 256 prior to calling imshow
. Otherwise, imshow
will scale your values down to zero and you will get a black image (as Astor has pointed out).
Since the original values are 8 bit unsigned, they must be less than 255. Therefore multiplying them by 256 is safe and will not overflow a 32-bit integer.
EDIT I just realized your output type is a signed 32-bit integer, but the original type is unsigned 8-bit integer. In that case, you need to scale your values appropriately (have a look at scaleAdd).
Finally, you may want to make sure your image is in YCbCr format before you start throwing away image channels.
Upvotes: 0
Reputation: 8725
Have you tried to get values of result image? Like this:
for (int i=0; i<result.rows; i++)
{
for (int j=0; j<result.cols; j++)
{
cout << result.at<int>(i,j) << endl;
}
}
I have converted (also used convertTo
) random gray-scale single-channel image to CV_32S
(it is a signed 32bit integer value for each pixel) my output was like this:
80
111
132
And when I tried to show it I also get black image. From documentation:
If the image is 16-bit unsigned or 32-bit integer, the pixels are divided by 256. That is, the value range [0,255*256] is mapped to [0,255].
So if you divide these small numbers to 255 than you will get 0 (int
type). That's why imshow
displays black image.
Upvotes: 3