**
基于图像分块的可变阈值处理
**
全局阈值处理在光照不均的图像方面效果很好,但是在光照变化较剧烈的情况下单独使用Otsu算法计算出的阈值不再足以对图像进行处理。
全局阈值处理:
f = imread('original image.jpg');
k=graythresh(f); %得到最优阈值
g=im2bw(f,k); %阈值分割
subplot(1,2,1);
imshow(f);
title('光照不均的图像');
subplot(1,2,2);
imshow(g);
title('处理后的图像');
结果如图
光照变化较简单时使用该算法效果比较好
阈值为0.5333
光照复杂时Otsu算法得到的阈值不足以对图像进行全局阈值分割,复杂光照严重影响了Otsu算法对全局阈值的计算。
若先对图像进行分割,然后对每一个单独的小块即局部进行Otsu阈值分割,就可以减小全局光照变化对Otsu算法的影响(想法取自《冈萨雷斯 数字图像处理》)。
本文中使用一个模板对原图进行分块提取,对分块单独进行一次Otsu方法阈值分割,将所有分块处理完后拼接在一起形成最终结果,使用Matlab实现了该算法,实验结果如图。
可见得到了比较理想的二值化结果。
代码如下
f = imread('original image.jpg');
ff = f; %生成一个用来进行阈值分割的原图副本
size1 = size(ff); %原图的尺寸
%分块处理
blocknum = 4; %分块数量(默认长宽分块数量一样)
length = size1(1); %原图长度像素数
height = size1(2); %原图宽度像素数
lengthSide = floor(length/blocknum); %每个分块长度
heightSide = floor(height/blocknum); %每个分块宽度
%开始分块处理
for k = 1:blocknum
for n = 1:blocknum
%生成模板
block = zeros(size(ff)); %将模板初始化为0
lini = 1 + lengthSide * (n - 1);
hini = 1 + heightSide * (k - 1); %分块的第一个像素在原图中的坐标
x = lini:(lini + lengthSide - 1);
y = hini:(hini + heightSide - 1); %生成分块长、宽坐标序列
block(x, y) = 1; %将模板上需要进行分块的部分转换成1,用来提取该分块
%提取分块
ff = im2double(ff); %原图转换为double类型,保证和模板black同类型以做点乘
block = block .* ff; %将原图投影在模板上
block = block(x, y); %提取分块
%阈值分割处理
optval = graythresh(block); %得到Otsu最优阈值
g = im2bw(block,optval); %阈值分割
%拼接
ff(x, y) = g; %将阈值分割处理过的分块放回原图
end
end
subplot(2,2,1);
imshow(f);
title('光照不均的图像');
subplot(2,2,2);
imshow(ff);
title('处理后的图像');
文章取自本人大学课程《数字图像处理及应用》结课论文。