图像分割——采用梯度算法改善全局阈值设定

clc;
clear all;
close all;
%用边缘信息改善全局阈值设定
%Using Edges to Improve Global Thresholding

%%
%====================采用梯度算法改善全局阈值设定==========================
I=imread('D:\Gray Files\10-41.tif');
[M,N]=size(I);
%是否统计灰度值为0的像素点
g_gradient=SobelFilter(im2double(I));
% 梯度阈值
th=0.997;
g_T=zeros(M,N);
g_T=uint8(g_T);
ind=find(g_gradient>th);
g_T(ind)=1;
% imshow(g_T)
%将梯度二值图像与原图相乘
g_edge=I.*g_T;
% imshow(g_edge)
%通过Otsu算法寻找门限
L_start=1;
T=Otsu_FindThreshold(g_edge,L_start);
g=zeros(M,N);
ind=find(I>T);
g(ind)=1;
g=uint8(g).*I;
imshow(g)

Sobel滤波函数,SobelFilter如下:

%利用梯度来增强图像的边缘算子,一阶导数,锐化图像
function g=SobelFilter(f)
len=1;
%对原始图像进行扩展,此处采用了镜像扩展,目的是解决边缘计算的问题
f_pad=padarray(f,[len,len]);
[M,N]=size(f_pad);
%sobel算子
Lx=[-1 -2 -1;
    0 0 0;
    1 2 1];
Ly=[-1 0 1;
     -2 0 2;
     -1 0 1];     
%M(x,y)=sqrt(gx^2+gy^2)
for i=1+len:M-len
    for j=1+len:N-len
        %从扩展图像中,取出局部图像
        Block=f_pad(i-len:i+len,j-len:j+len);
        gx=sum(sum(Block.*Lx));
        gy=sum(sum(Block.*Ly));
        %取这组数的中值,赋值给输出图像        
%         g(i-len,j-len)=f(i-len,j-len)+ sqrt(gx^2+gy^2);
        g(i-len,j-len)=sqrt(gx^2+gy^2);
    end
end

Otsu函数,Otsu_FindThreshold如下:

%%%%%%%灰度图像二值分割门限
%I为输入灰度图像
function T=Otsu_FindThreshold(I,L_start)
    if isempty(find(I>1))
        Display('Please input image with integer type!');
        T=0;
        return;
    end
    %统计直方图
    [Pi,Pk]=Histeq_My(I,L_start);
    L=L_start:255;
    %计算全局的灰度平均值
    m_G=sum(L.*Pi);
    k_optimum=0;
    delta_max=0;
    %保存多个最大值
    ks=[];
    for k=L_start:255
        %计算第k平均值
        i=L_start:k;    
        Pi_k=Pi(1,1:k+1-L_start);
        m_k=sum(i.*Pi_k);
        %如果被除数为0或1,其值直接为0。详细请参见公式
        if Pk(k+1-L_start)==0 ||Pk(k+1-L_start)==1
            delta=0;
        else
           delta=(m_G*Pk(k+1-L_start)-m_k)^2/((Pk(k+1-L_start))*(1-Pk(k+1-L_start)));
        end   
        %寻找最大值
        if delta>delta_max
            delta_max=delta;
            k_optimum=k;
            ks=[];            
        elseif delta==delta_max %如果有多个最大值,将其记录
            ks=cat(2,ks,k);
        end
        %求多个最大值下标的平均值
        if ~isempty(ks)
            k_optimum=mean(ks);
        end
    end
   T=k_optimum;
end

Histeq_My函数如下:

%%%直方图计算
%L_start取值为0和1
function [Pi,Pk]=Histeq_My(I,L_start)
    [M,N]=size(I);
    if L_start
        hist_I=zeros(1,255);
        %遍历图像,对每一个灰度分量进行数量统计
        for i=1:M*N
            if I(i)~=0
                hist_I(I(i))=hist_I(I(i))+1;
            end
        end      
        %找出图像中的非零元素的个数
        c=length(find(I>0));
        Pi=hist_I/c;
        Pk=zeros(1,255);
        for k=1:255
            Pi_k=Pi(1:k);
            Pk(k)=sum(Pi_k);
        end            
    else
        hist_I=zeros(1,256);
        %每一个值加1,消除零值,以与矩阵的下标对应
        I=I+1;
        %遍历图像,对每一个灰度分量进行数量统计
        for i=1:M*N
            hist_I(I(i))=hist_I(I(i))+1;
        end
        Pi=hist_I/(M*N);
        Pk=zeros(1,256);
        for k=1:256
            Pi_k=Pi(1:k);
            Pk(k)=sum(Pi_k);
        end
    end
    %显示直方图统计信息
%     for x=L_start:255
%         x_ps=[x,x];
%         y_ps=[Pi(x+1-L_start),0];
%         plot(x_ps,y_ps);
%         hold on
%     end
%     hold off    
end

 

  • 0
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值