OpenCV:使用C ++将CV_8UC3图像转换为CV_32S1图像

时间:2013-03-11 06:03:51

标签: c++ opencv type-conversion mat watershed

我需要将具有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...?

提前谢谢。

4 个答案:

答案 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;