Matlab实现通过图像分块的可变阈值处理,使用Otsu方法进行二值化

**

基于图像分块的可变阈值处理

**

全局阈值处理在光照不均的图像方面效果很好,但是在光照变化较剧烈的情况下单独使用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('处理后的图像');

结果如图
Matlab实现通过图像分块的可变阈值处理,使用Otsu方法进行二值化_第1张图片
光照变化较简单时使用该算法效果比较好

Matlab实现通过图像分块的可变阈值处理,使用Otsu方法进行二值化_第2张图片
阈值为0.5333
光照复杂时Otsu算法得到的阈值不足以对图像进行全局阈值分割,复杂光照严重影响了Otsu算法对全局阈值的计算。

若先对图像进行分割,然后对每一个单独的小块即局部进行Otsu阈值分割,就可以减小全局光照变化对Otsu算法的影响(想法取自《冈萨雷斯 数字图像处理》)。
本文中使用一个模板对原图进行分块提取,对分块单独进行一次Otsu方法阈值分割,将所有分块处理完后拼接在一起形成最终结果,使用Matlab实现了该算法,实验结果如图。
Matlab实现通过图像分块的可变阈值处理,使用Otsu方法进行二值化_第3张图片
可见得到了比较理想的二值化结果。

代码如下

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('处理后的图像');

文章取自本人大学课程《数字图像处理及应用》结课论文。

你可能感兴趣的:(QR二维码,图像处理)