本文最后更新于 197 天前,其中的信息可能已经有所发展或是发生改变。
MATLAB图像处理工具包中的im2bw
函数和imbinarize
函数均可以实现灰度图像的二值化功能,且在MATLAB R2018a之后推荐使用imbinarize
。但两者在内部处理图像的时候具有一些较为隐晦的预设,尤其是在图像的灰度级范围与图像像素存储的数据类型所具有的数值范围不同时,可能会出现一些预料外的输出。
源码解析
im2bw
im2bw
涉及到阈值的源码如下:
range = getrangefromclass(A);
if isinteger(A)
BWp = (A > range(2) *level);
elseif islogical(A)
%A is already a binary image and does not require thresholding
warning(message('images:im2bw:binaryInput'))
BWp = A;
else % double or single
BWp = (A > level);
end
其中,A
是输入图像,BWp
是输出的二值化图像,level
为输入的给定二值化阈值(归一化至[0,1]
)。可以发现,im2bw
函数在图像输入类型为整形的情况下,认为图像的灰度级为[0,A数据类型所能存储的最大值]
,并将level
乘以A
数据类型所能存储的最大值作为阈值进行二值化。而在其他数据类型的图像输入时则直接以level
作为阈值进行二值化。
imbinarize
imbinarize
涉及到阈值的源码如下:
function BW = binarize(I,T)
classrange = getrangefromclass(I);
switch class(I)
case {'uint8','uint16','uint32'}
BW = I > T*classrange(2);
case {'int8','int16','int32'}
BW = I > classrange(1) + (classrange(2)-classrange(1))*T;
case {'single','double'}
BW = I > T;
end
end
其中,I
是输入图像,BW
是输出的二值化图像,T
为输入的给定二值化阈值(归一化至[0,1]
)。与im2bw不同的是,其对整形和无符号整型进行了区分,其他细节基本相同。在无符号整形时,其仍然认为图像的灰度级为[0,I数据类型所能存储的最大值]
,并将T
乘以I
数据类型所能存储的最大值作为阈值进行二值化。
问题
若图像以整形存储,但其灰度级范围并与该数据类型的数值范围不一致(例如图像的灰度级范围为0~128,但图像以uint8
存储,数值范围为0~255,与灰度级范围不一致),则可能出现错误的二值化输出,即函数对图像进行二值化的阈值并不是我们期望的阈值。
解决方法
目前没有完美的解决办法,暂时想到的几种解决办法如下:
- 由于图像二值化的操作较为简单,对灰度级范围并与该数据类型的数值范围不一致的情况可以考虑自行编写函数进行二值化。
- 将图像数据类型强制转化为
double
或float
,并采用图像灰度值中位数作为阈值输入,强行使程序进入case {'single','double'} BW = I > T;
分支。 - 将图像转化为
double
或float
类型后,将其归一化至[0,1]
。