将Mat对象的类型从CV_32F更改为CV_8U

Kar*_*gan 31 floating-point opencv mat

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

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

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

......

Mat B;

A.convertTo(B,CV_8U)

当我看到'B'我得到黑白图像时,没有灰色阴影.A中的浮点值像素是否正确映射到0-255?我做错了吗?

A中的几个值在初始化时为1000,而休息是在处理期间分配的一些浮点数.

sga*_*zvi 56

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

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

在文档中imshow,写道:

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

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

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

要将值适当地映射到CV_8U使用函数的第3和第4个参数的范围cv::Mat::convertTo,以便在转换完成之前缩放值.

假设矩阵A具有最小值和最大值,Min并且Max在哪里Min!=Max.

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

if (Min!=Max){ 
    A -= Min;
    A.convertTo(B,CV_8U,255.0/(Max-Min));
}
Run Code Online (Sandbox Code Playgroud)

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

if (Min!=Max)
    A.convertTo(B,CV_8U,255.0/(Max-Min),-255.0*Min/(Max-Min));
Run Code Online (Sandbox Code Playgroud)

(考虑到zhangxaochen的评论编辑)

  • `beta`字段应为`-255.0*Min /(Max-Min)`而不是`-255.0/Min`. (5认同)