我尝试使用imshow函数显示CV_32F类型的图像,但它显示了一个白色图像。在文档中,给定浮点图像将映射到 0-255 并显示,但它只显示一个白色图像。我试图CV_8U使用
垫子 A=垫子::一(300,300,CV_32FC1)*1000;
执行一些处理 - 将浮点值分配给 A 中的像素
......
垫子B;
A.转换为(B,CV_8U)
当我显示"B"时,我得到的是黑白图像,没有灰色阴影。A 中的浮点值像素是否正确映射到 0-255?我做错了什么吗?
A 中的几个值在初始化时为 1000,其余值是在处理过程中分配的一些浮点数。
在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 到 255。如果值大于 1.0 并乘以 255,它将大于 255。然后它将被钳制到CV_8U
的范围,最终它也将变成 255。
在您的示例中,所有为 1000 的值在目标矩阵中将变为 255,因为目标类型为 CV_8U
,最大可能值为 255。所有浮点值都将被floor
编辑。不执行自动映射。
要将值适当地映射到CV_8U
范围,请使用函数 cv::Mat::convertTo
的第 3 和第 4 个参数,以便在转换完成之前缩放值。
假设矩阵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));
(根据张晓晨的评论编辑)