我需要将具有3个通道的CV_8U图像转换为必须是单通道CV_32S的图像。但是当我试图这样做时,我得到的图像都是黑色的。我不明白为什么我的代码不起作用。
我正在处理灰度图像,这就是为什么我将3通道图像分割成单通道图像的矢量,然后只处理第一个通道。
//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...?
提前谢谢。
答案 0 :(得分:3)
您是否尝试过获取结果图片的值?像这样:
for (int i=0; i<result.rows; i++)
{
for (int j=0; j<result.cols; j++)
{
cout << result.at<int>(i,j) << endl;
}
}
我已将(也使用convertTo
)随机灰度单通道图像转换为CV_32S
(每个像素为有符号的32位整数值),我的输出如下:
80
111
132
当我试图展示它时,我也会得到黑色图像。来自documentation:
如果图像是16位无符号或32位整数,则像素为 除以256.即,值范围[0,255 * 256]被映射到 [0255]
因此,如果将这些小数字除以255,则会得到0(int
类型)。这就是imshow
显示黑色图片的原因。
答案 1 :(得分:0)
如果要显示32位图像并查看有意义的结果,则需要在调用imshow
之前将其所有元素乘以256。否则,imshow
会将您的值缩小到零,您将获得一个黑色图像(正如Astor指出的那样)。
由于原始值是8位无符号,因此它们必须小于255.因此将它们乘以256是安全的,不会溢出32位整数。
编辑我刚刚意识到您的输出类型是 signed 32位整数,但原始类型是 unsigned 8位整数。在这种情况下,您需要适当地缩放您的值(请查看scaleAdd)。
最后,在开始丢弃图像通道之前,您可能需要确保图像是YCbCr格式。
答案 2 :(得分:0)
我相信这就是你要找的东西。将图像转换为8位单通道。 CV_8UC1。您是从8位图像开始并将其更改为32位单通道?为什么?保持8位。
答案 3 :(得分:0)
我有同样的问题,通过尝试将8UC1转换为32S而不是8UC3来间接解决它。
RgbToGray接受使用8UC3或8UC1元素类型创建灰色图像。 8UC1图像是我的标记图像。
我在Opencvsharp中做到了这一点:
Mat buf3 = new Mat(iplImageMarker);
buf3.ConvertTo(buf3, MatType.CV_32SC1);
iplImageMarker= (IplImage)buf3;
iplImageMarker=iplImageMarker* 256;