我正在尝试对 16 位灰度图像进行直方图均衡,原始直方图如下所示,其灰度级约为 25000:
我首先使用 MATLAB,但由于某种原因,输出中的总级别显着减少(只有 21!)。我尝试手动分配 20,000 的 bin 编号,但输出级别仍然很小 (67)。
然后我在 Python 中尝试了 Scikit-Image,一切都按预期工作——输出现在有 16,500 个级别,并且直方图非常平坦。
这是 MATLAB 命令:
J = histeq(I,2e4);
这是 Python 命令:
img_eq_sk = exposure.equalize_hist(img_16bit)
由于直方图均衡是一个基本操作,我希望 MATLAB 和 Python 的行为类似,但根据此 MATLAB 的结果甚至不如 Skimage 的好。
最佳答案
我可以验证您所看到的内容:
I = uint16(randn(1000,1000) * 5000 + 3e4);
imhist(I)
size(unique(I(:))) % returns: 31290 unique gray values
J = histeq(I,8e5); % actually uses only 6.5e4, the max for uint16
imhist(J)
size(unique(J(:))) % returns: 158 unique gray values
K = histeq(im2double(I),8e5);
imhist(K)
size(unique(K(:))) % returns: 175 unique gray values
当输入值需要显着拉伸(stretch)时,许多不同的灰度值最终会出现在同一个输出箱中,并且许多输出箱保持为空。
当使用双图像(上面代码中的K
)查看结果时,我们可以看到随着参数增加到histeq
,唯一输出灰度级的数量如何增加。 .
也就是说,输出被量化为一组值(上例中为 800,000),而不仅仅是输入。因此,如果其中许多输出箱是空的,则将很少有不同的输出灰度值。
没有必要以这种方式实现直方图均衡,从OP中使用的Python实现可以看出。然而,这种实现似乎并没有错,它只是不必要地量化了输出。
关于python - MATLAB 的直方图均衡有什么问题?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57421105/