最大类间方差法(Otsu阈值分割算法)和形态学后处理

最大类间方差

% 最大类间方差法
% 输入:
%       灰度图像        in
% 输出:
%       二值图像        out
function [ out ] = myOtsu( in )
    in = double(in);
    % 1.计算输入图像的归一化直方图
    histogram = zeros(1,256);
    [row,column] = size(in);
    s = row*column;
    in = in(:);
    for i=1:s
        histogram(in(i)+1) = histogram(in(i)+1)+1;
    end
    histogram = histogram/s;
    % 4.计算全局灰度均值
    global_gray_mean = mean(in);
    % 2.对于所有灰度级k=0,1,…,L-1,
    % 计算被分类到C1类中像素的累计概率
    % 3.对于所有灰度级k=0,1,…,L-1,
    % 计算被分类到C1类中像素的累计灰度均值
    cumulative_probability = zeros(1,256);
    cumulative_gray_mean = zeros(1,256);
    % 类间方差矩阵
    inter_class_variance = zeros(1,256);
    % 下标索引必须为正整数类型或逻辑类型[1:256]->[0:255]
    for k=1:256
        % 累计概率
        cumulative_probability(k) = sum(histogram(1:k));
        % 累计灰度均值
        cumulative_gray_mean(k) = sum((0:k-1).*histogram(1:k));
        % 5.计算类间方差
        inter_class_variance(k) = (global_gray_mean*cumulative_probability(k)-cumulative_gray_mean(k))^2/(cumulative_probability(k)*(1-(cumulative_probability(k)))+eps);
    end
    % 6.搜索使得类间方差最大的k值,即为Otsu分割阈值;
    % 若分割阈值不唯一,则取所有最大值的平均值
    index = find(inter_class_variance==max(inter_class_variance))-1;% 因为之前定义[1,256],这里减一,得到范围是[0,255]
    % 最佳阈值
    threshold = mean(index);
    in(in=threshold) = 255;
in = 255-in;
    out = uint8(reshape(in,row,column));
end
 

% myOtsu测试代码
in = imread('1.tif');
out = myOtsu( in );
figure;
subplot(121);
imshow(in);
title('原图');
subplot(122);
imshow(out);
title('最大类间方差处理后图');
结果

最大类间方差法(Otsu阈值分割算法)和形态学后处理_第1张图片
形态学后处理

% 腐蚀
% 输入:二值图像           in
%       结构元素                   struct
%       结构元素的中点坐标         pos
% 输出:经过腐蚀后的的二值图像     out
function [ out ] = myImageErode( in, struct, pos )
    in = double(in);
    in = in/255;
    % 结构元素的中点坐标
    a = pos(1);
    b = pos(2);
    % 有关尺寸
    [r c] = size(in);
    [m n] = size(struct);
    % 计算上下左右边界各需添加多少
    top = a-1;
    bottom = m-a;
    left = b-1;
    right = n-b;
    % 扩充边界
    rr = r+top+bottom;
    cc = c+left+right;
    out = zeros(rr,cc);
    t = zeros(rr,cc);
    t(a:rr-bottom,b:cc-right) = in;
    % 遍历与匹配
    for i=a:rr-bottom
       for j=b:cc-right
           % 结构元素对应区域
           temp = t(i-top:i+bottom,j-left:j+right);
           if isequal(temp,struct)
               out(i,j)=255;
           else
               out(i,j)=0;
           end
       end
    end
    % 去除边界
    out = out(a:rr-bottom,b:cc-right);
    out = uint8(out);
end
 

% 测试myImageErode
in = imread('1.tif');
figure;
subplot(121);
imshow(in);
title('原图');
in = myOtsu( in );
struct = ones(5,5);
pos = [3,3];
out = myImageErode( in, struct, pos );
subplot(122);
imshow(out);
title('最大类间方差+形态学后处理图');
结果

最大类间方差法(Otsu阈值分割算法)和形态学后处理_第2张图片

你可能感兴趣的:(Matlab)