37

我尝试使用 imshow 函数显示 CV_32F 类型的图像,但它显示了一个WHITE 图像。在文档中,考虑到浮点图像将被映射到 0-255 并显示,但它只显示一个白色图像。我尝试使用将其转换为 CV_8U

垫A=垫::ones(300,300,CV_32FC1)*1000;

做一些处理 - 将浮点值分配给 A 中的像素

……

垫B;

A.convertTo(B,CV_8U)

当我显示“B”时,我得到一张黑白图像,没有灰色阴影。A 中的浮点值像素是否正确映射到 0-255 ?我做错什么了吗?

A 中很少有值在初始化时是 1000,其余的是在处理过程中分配的一些浮点数。

4

1 回答 1

64

在 OpenCV 中,如果图像是浮点类型,则只有那些像素可以使用 可视化imshow,其值从 0.0 到 1.0,如果值大于 1.0,则显示为白色像素,如果小于 0.0 ,它将显示为黑色像素。要可视化浮点图像,请将其值缩放到 range 0.0 - 1.0

至于转换部分......当与默认参数一起使用时,该cv::Mat::convertTo函数只是创建一个指定类型的矩阵,然后从源矩阵复制值,然后将它们四舍五入到目标数据类型的最接近的可能值。如果该值超出范围,则将其限制为最小值或最大值。

在 的文档中imshow写道:

如果图像是 32 位浮点,则像素值乘以 255。即取值范围 [0,1] 映射到 [0,255]。

这意味着只有 0.0 到 1.0 范围内的值会被映射到 0 到 255。如果一个值大于 1.0,再乘以 255,它将变得大于 255。然后它将被钳制在CV_8U和最终它也会变成255。

在您的示例中,所有 1000 的值将在目标矩阵中变为 255,因为目标类型是CV_8U,最大可能值为 255。所有浮点值都将被floor编辑。没有进行自动映射。

为了将值适当地映射到函数CV_8U的第三个和第四个参数的使用范围cv::Mat::convertTo,以便在转换完成之前对值进行缩放。

假设矩阵A具有最小值和最大值Min,并且Max,其中Min!=Max

要正确地将值从 0 缩放到 255,您可以执行以下操作:

if (Min!=Max){ 
    A -= Min;
    A.convertTo(B,CV_8U,255.0/(Max-Min));
}

您也可以像这样直接执行此操作:

if (Min!=Max)
    A.convertTo(B,CV_8U,255.0/(Max-Min),-255.0*Min/(Max-Min));

(编辑考虑到zhangxaochen的评论)

于 2013-01-26T17:39:52.147 回答