2

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

4 回答 4

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

当我试图展示它时,我也会得到黑色图像。从文档

如果图像是 16 位无符号或 32 位整数,则像素除以 256。即取值范围 [0,255*256] 映射到 [0,255]。

因此,如果您将这些小数除以 255,您将得到 0(int类型)。这就是为什么imshow显示黑色图像。

于 2013-03-11T11:12:53.133 回答
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;
于 2014-05-22T10:17:23.673 回答
0

我相信这就是您正在寻找的。将您的图像转换为此 8 位单通道。CV_8UC1。您从 8 位图像开始并将其更改为 32 位单通道?为什么?保持8位。

于 2013-12-28T19:36:08.463 回答
0

如果要显示 32 位图像并看到有意义的结果,则需要在调用之前将其所有元素乘以 256 imshow。否则,imshow会将您的值缩小为零,您将获得黑色图像(正如 Astor 指出的那样)。

由于原始值是 8 位无符号的,它们必须小于 255。因此将它们乘以 256 是安全的,不会溢出 32 位整数。

编辑我刚刚意识到您的输出类型是有符号的32 位整数,但原始类型是无符号的 8 位整数。在这种情况下,您需要适当地缩放您的值(查看scaleAdd)。

最后,在开始丢弃图像通道之前,您可能需要确保图像是 YCbCr 格式。

于 2013-03-11T11:31:07.443 回答