freq(255) freq(256) 值中的直方图均衡误差
Histogram Equalization error in freq(255) freq(256) values
我的直方图均衡初始代码完美地计算了 freq(1) 到 freq(254),但错误地计算了 freq(255) 和 freq(256)。 freq(255) 处的结果错误地是 freq(255) 和 freq(256) 处实际结果的总和。并且 freq(256) 始终保持为 0.
freq=zeros(256,1);
probf=zeros(256,1);
probc=zeros(256,1);
cum=zeros(256,1);
output=zeros(256,1);
numofpixels = 1080*1920;
value = 500;
%calculating the frequency
for i=1:1080
for j=1:1920
value=mdata(i,j,1);
freq(value+1)=freq(value+1)+1;
probf(value+1)=freq(value+1)/numofpixels;
end
end
所以我将初始代码修改为以下代码,我在其中分别检查任何像素的值是否为 254 和 255。这非常有效。背后的原因可能是什么?
freq=zeros(256,1);
probf=zeros(256,1);
probc=zeros(256,1);
cum=zeros(256,1);
output=zeros(256,1);
numofpixels = 1080*1920;
maximum254 = 0;
maximum255 = 0;
value = 500;
%calculating the frequency
for i=1:1080
for j=1:1920
value=mdata(i,j,1);
if value < 254
freq(value+1)=freq(value+1)+1;
end
if value==254
freq(255)=freq(255)+1;
maximum254 = maximum254 +1;
end
if value==255
freq(256)=freq(256)+1;
maximum255 = maximum255 +1;
end
probf(value+1)=freq(value+1)/numofpixels;
end
end
最有可能的罪魁祸首是您的图像 uint8
并且数据类型正在饱和。您注意到您需要将强度加 1 以对结果进行分箱,因为 MATLAB 从索引 1 开始索引。但是,当您达到强度 255 时,加 1 应该得到 256,但它实际上 饱和 到 255。这就是为什么 256 处的 bin 始终为 0,因为您永远不会生成超过 255 的任何值。
实际发生的情况是,那些被合并为 254 的值正在与 255 合并,因为 uint8(254+1) = uint8(255+1) = 255
。这就是索引 254 和 255 处的计数错误,而 bin 256 为 0 的原因。
因此,为确保您的数据不饱和,您需要将数据转换为对 8 位数据不饱和的类型。 double
是一个很好用的类型。因此,在执行直方图均衡之前,只需将 mdata
转换为 double
,因此:
mdata = double(mdata);
执行此操作后,当您 运行 您的代码时,它现在应该可以工作,您不必手动检查强度范围较高端的那些值。
我的直方图均衡初始代码完美地计算了 freq(1) 到 freq(254),但错误地计算了 freq(255) 和 freq(256)。 freq(255) 处的结果错误地是 freq(255) 和 freq(256) 处实际结果的总和。并且 freq(256) 始终保持为 0.
freq=zeros(256,1);
probf=zeros(256,1);
probc=zeros(256,1);
cum=zeros(256,1);
output=zeros(256,1);
numofpixels = 1080*1920;
value = 500;
%calculating the frequency
for i=1:1080
for j=1:1920
value=mdata(i,j,1);
freq(value+1)=freq(value+1)+1;
probf(value+1)=freq(value+1)/numofpixels;
end
end
所以我将初始代码修改为以下代码,我在其中分别检查任何像素的值是否为 254 和 255。这非常有效。背后的原因可能是什么?
freq=zeros(256,1);
probf=zeros(256,1);
probc=zeros(256,1);
cum=zeros(256,1);
output=zeros(256,1);
numofpixels = 1080*1920;
maximum254 = 0;
maximum255 = 0;
value = 500;
%calculating the frequency
for i=1:1080
for j=1:1920
value=mdata(i,j,1);
if value < 254
freq(value+1)=freq(value+1)+1;
end
if value==254
freq(255)=freq(255)+1;
maximum254 = maximum254 +1;
end
if value==255
freq(256)=freq(256)+1;
maximum255 = maximum255 +1;
end
probf(value+1)=freq(value+1)/numofpixels;
end
end
最有可能的罪魁祸首是您的图像 uint8
并且数据类型正在饱和。您注意到您需要将强度加 1 以对结果进行分箱,因为 MATLAB 从索引 1 开始索引。但是,当您达到强度 255 时,加 1 应该得到 256,但它实际上 饱和 到 255。这就是为什么 256 处的 bin 始终为 0,因为您永远不会生成超过 255 的任何值。
实际发生的情况是,那些被合并为 254 的值正在与 255 合并,因为 uint8(254+1) = uint8(255+1) = 255
。这就是索引 254 和 255 处的计数错误,而 bin 256 为 0 的原因。
因此,为确保您的数据不饱和,您需要将数据转换为对 8 位数据不饱和的类型。 double
是一个很好用的类型。因此,在执行直方图均衡之前,只需将 mdata
转换为 double
,因此:
mdata = double(mdata);
执行此操作后,当您 运行 您的代码时,它现在应该可以工作,您不必手动检查强度范围较高端的那些值。