数据类型问题,histeq函数,当你的图像是double型时手巧,返回值是0或者1;当你的图像是uint8型时,返回值为0-255。
所以你编的代码里的:k=histeq(m)%对块图进行直方图均衡,m为double型,所以其k就是全1,闷薯冲那么x2中对应的位置也就是全1,蚂歼最后显示转化成uint8显示肯定为黑色。
所以把k=histeq(m)改成k=histeq(uint8(m))即可。运行结果如图
clearI = imread('E:\ebook\慧尘lena.bmp')
figure,imshow(I),title('original image')
len = 5
hstep = 2
wstep = 2
for k = 1:size(I,3)
img = I(:,:,k)
img = [img(:,len:-1:2) img img(:,end-1:-1:end-len)]
img = [img(len:-1:2,:) imgimg(end-1:-1:end-len,:)]%%其实就是图像扩展,参考wextend函数,当然你的方法也可以
[h w] = size(img)
med_out(:,:,k) = int16(zeros(h,w))%%转化成int16型数据,原因下面会说明
counts = zeros(h,w)
for i =1:hstep:h
if h-i >= len
for j = 1:wstep:w
if w-j >= len
rect =int16(histeq(img(i:i+len-1,j:j+len-1)))%同样转化成int16类型
med_out(i:i+len-1,j:j+len-1,k) =med_out(i:i+len-1,j:j+len-1,k)+rect%%rect和med_out转化成int16类型原因在于,你的med_out计算直方图均衡化并且前基禅把重复的像素的直方图均衡化结果进行累加,那么其累加的值很有可能超过255,所以你转化med_out为uint8型是不够的,它会把超过255的值强制为255。
counts(i:i+len-1,j:j+len-1) = counts(i:i+len-1,j:j+len-1)+1
end
end
end
end
med_out1(:,:,k) = double(med_out(len:end-len,len:end-len,k))%%这里对图像两边各扩展了四个像素,所以起始位置应该是len,而不是len+1,同样结束就是end-len
med_out1(:,:,k) = med_out1(:,:,k)./counts(len:end-len,len:end-len)
out(:,:,k) = uint8(med_out1(:,:,k))%%转锋庆化成uint8型
end
figure,imshow(out),title('poshe result')
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
这样改就可以了,运行后可以出结果,图片就不贴了!!
编程时要考虑数据范围是否过界的问题。
matlab全局直方图均衡化和局部直方图均衡化的优缺点如下:如果一幅图像整体偏暗或者偏亮,那么直方图均衡化的方法很适用。但直方图均衡化是一种全局处理方式,它对处理的数据不加选择,可能会增加背景干扰信息的对比度并且降低有用信号的对比度(如果图像某些区域对比度誉指很好,而另一些区域对比度不好,那采用直方图均衡化就不一燃慧定用)。此外,均衡化后图像的灰度级减少,某些细节将会消失;某些图像(如直方图有高峰),经过均衡化后对比度不自然的过分增强。针对直方图均衡化的缺点,已皮虚答经有局部的直方图均衡化方法出现。
1.全局直方图均衡化,是先将图像各元素的个数进行统计,再求出各像素值的概率,并进行概率对应的归一化,将归一化的概率乘上灰度值,根据原像素值和归一化后的像素值对应,通过find函数找到原来相应的像素改变为现在归一化后的像素,得到均衡化处理的图像。
2.局部直方图均衡化,分为子块不重叠、子块重叠和子块部分重叠,函数中可选择不同的方法计算。子块不重叠算法根据输入分割子块的大小为n,将图像划分为多块n*n大小的子块,单独对每块进行直方图均衡化;子块重叠算法根据输入分割子块的大小n,利用该分割子块的直方图信息对子块中心的像素进行均衡化,逐一处理完该子块所有像素点;子块部分重叠算法子块是将移动步长约取为子块尺寸的几分之一,子块均衡的灰度值用于映射子块所有像素的灰度值,并记录对多次被均衡的像素,将均衡结果取平均作为该像素在输出图像中的灰度值。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)