边缘提取,大津算法

 

  1. 试编程实现提取图像Fig1006(a)(building).tif中的边缘.

 

解:采用Canny边缘检测器,代码如下:

 

function Canny()%自己写的Canny算法,陈焜

clc;

clear all;

close all;

img=imread('Fig1006(a)(building).tif');

figure(1);subplot(221);imshow(img);title('原图像');

figure(11);imshow(img);title('原图像');

 

img=double(img);

[m,n]=size(img);

 

%%高斯低通滤波,起平滑作用

img1=GLPF(img);%自己写的高斯低通滤波器程序 

figure(1);subplot(222);imshow(uint8(img1));title('高斯滤波');

figure(12);imshow(uint8(img1));title('高斯滤波后的图像');

 

%%计算梯度幅值

Sobelx=[-1,-2,-1;0,0,0;1,2,1];%x方向的Sobel模板

Sobely=[-1,0,1;-2,0,2;-1,0,1];%y方向的Sobel模板

gx=imfilter(img1,Sobelx,'replicate'); %求x方向梯度分量,replicate表示图像大小通过复制外边界来扩展

gy=imfilter(img1,Sobely,'replicate'); %求y方向梯度分量

Mg=sqrt(gx.^2+gy.^2); %梯度幅值

Ag=atan(gy./gx);     %梯度方向

 

 

%%非最大抑制

img2=ImaxInhibit(Mg,Ag);

figure(15);imshow(uint8(img2));title('非最大抑制');

figure(1);subplot(223);imshow(uint8(img2));title('非最大抑制');

 

 

%%双阈值(滞后阈值)处理

img3=DualThreshold(img2);

figure(20);imshow(img3);title('Canny处理图像');

figure(1);subplot(224);imshow(img3);title('Canny处理图像');

end

 

 

 

%----------------------------------------------------------------------

%以下为子函数

 

%高斯低通滤波子函数

function gauss=GLPF(I) 

[M, N]=size(I);

P=2*M;%填充图像为P*Q

Q=2*N;

F0=zeros(P,Q);

F0(1:M,1:N)=I; %填充图像

F1= fftshift(F0);%将频域原点移到图像中心;

F= fft2(F1); % 傅立叶变换

D0 = 400; % D0为截止频率

for u=1:P

    for v=1:Q

        D(u,v)= sqrt((u-P/2)^2+(v-Q/2)^2); %距离

        H(u,v)= 1-exp(-D(u,v)^2/(2*D0^2));  % Gauss滤波器函数

%        G(u,v) = H(u,v).*F(u,v);

    end

end

G = H.*F;%放在循环外,减少计算量

g = ifft2(G);% 傅立叶反变换

g1= real(g); %取实部

g2= ifftshift(g1);%将频域原点移到图像中心;

gauss=g2(1:M,1:N);%裁截图像

end

 

 

 

 

 

 

 

 

 

%%非最大抑制子函数

function Img=ImaxInhibit(Mg,Ag)

[M,N]=size(Mg);

Ag=Ag*180;

Img=Mg;

for i=2:M-1

    for j=2:N-1

       if Ag(i,j)>=-22.5&&Ag(i,j)<22.5||abs(Ag(i,j))>=157.5 %水平边缘

             if Mg(i,j)<Mg(i+1,j)||Mg(i,j)<Mg(i-1,j)

                Img(i,j)=0; %抑制

             end

        Else

If

Ag(i,j)>=-67.5&&Ag(i,j)<-22.5||Ag(i,j)>=112.5&&Ag(i,j)<157.5%+45°

                if Mg(i,j)<Mg(i+1,j-1)||Mg(i,j)<Mg(i-1,j+1)

                    Img(i,j)=0; %抑制

                end

        else 

if 

Ag(i,j)>=-112.5&&Ag(i,j)<-67.5||Ag(i,j)>=67.5&&Ag(i,j)<112.5%垂直

                if Mg(i,j)<Mg(i,j-1)||Mg(i,j)<Mg(i,j+1)

                        Img(i,j)=0; %抑制

                end

         else 

if 

Ag(i,j)>-157.5&&Ag(i,j)<-112.5||Ag(i,j)>=22.5&&Ag(i,j)<67.5 %—45°

                if Mg(i,j)<Mg(i-1,j-1)||Mg(i,j)<Mg(i+1,j+1)

                            Img(i,j)=0; %抑制

                end

          end

          end

          end

          end

    end

 end

end

 

 

 

 

 

 

 

 

%%双阈值(滞后阈值)处理子函数

function G=DualThreshold(Gn)

[M,N]=size(Gn);

Gn=mat2gray(Gn);%归一化

 

Gnh=Gn;

Gnl=Gn;

Th=0.12;

Tl=0.04;%满足高阈值与低阈值之比为3:1或者2:1

for i=2:M-1

    for j=2:N-1

        if Gn(i,j)<Th

            Gnh(i,j)=0;%高阈值抑制

        end

        if Gn(i,j)<Tl

            Gnl(i,j)=0;%低阈值抑制

        end

    end

end

 

Gnl1=Gnl-Gnh;%从Gnl中删除所有来自Gnh的非零像素,参见教材P465 式(10.2-35)

 

B=[0,1,0;1,1,1;0,1,0];%用膨胀的方法进行连接

Gnl1=imdilate(Gnl1,B);

 

G=Gnh+Gnl1;%将Gnl1中的所有非零像素附加到Gnh中

G=Gnh;

 

figure(18);imshow(Gnl);title('Gnl');

figure(19);imshow(Gnh);title('Gnh');

figure(17);imshow(Gnl1);title('Gnl-Gnh');

end

 

 

 

 

 

 

 

 

 

 

 

 

运行结果如下:

 

 

 

 

 

 

 

 

 

  1. 试编程实现图像最优全局阈值分割方法(即global optimal segmentation,大津算法),并将其应用于分割出图像Fig1013(a)(scanned-text-grayscale).tif中的文字,并求出最优全局阈值(global optimal threshold).

 

解:大津算法,代码如下:

 

function Otsu()%自己写的大津算法,ck

clc;

clear all;

close all;

Img=imread('Fig1013(a)(scanned-text-grayscale).tif'); %读入图片

Img=rgb2gray(Img);%因为原图是3维的,故需要转换

figure(1),imshow(Img);title('原图像')

 

p=zeros(1,256);%存放各灰度级的比率

Img=double(Img);%双精度化

[M,N]=size(Img);

%计算图像直方图   

for k=0:255

    p(k+1)=length(find(Img==k))/(M*N); %计算每级灰度出现的概率(数组下标从1开始)

end           

k=1:1:256;

figure(2); bar(k,p); title('原图像直方图');

 

for i=2:256

        if p(i)~=0

            minT=i+1;%寻找比率不为0的最小灰度值

            break

        end

end

 

for i=256:-1:1

        if p(i)~=0;

            maxT=i-1;%找出比率不为0的最大灰度值

            break

        end

end

 

Mg=0;%Mg为全局均值

for i=1:255

  Mg=Mg+i*p(i);

end

 

Var=zeros(1,(maxT-minT));%类间方差

Var1=0;%最大类间方差

for k=minT:maxT

     P1=0;%被分到C1的概率

     m=0;%被分到C1的像素的平均灰度值

    for i=1:k

        P1=P1+p(i);%求被分到C1的概率, 参照教材P481 式(10.3-4)

        m=m+i*p(i);%求被分到C1的像素的平均灰度值, 参照教材P481 式(10.3-8)       

    end

    Var(k)=(Mg*P1-m)^2/(P1*(1-P1));%求类间方差, 参照教材P481 式(10.3-15)

    

    if(Var(k)>=Var1)

       Var1=Var(k);%取得最大类间方差

    end

end

 

%如果有多个k使类间方差取得最大值,则取多个k的平均值作为最佳阈值,参照教材P481

K=zeros(1,(maxT-minT));%最佳阈值

j=0;%统计取得最大类间方差的阈值个数

for k=minT:maxT

    if(Var(k)==Var1)

       j=j+1;

       K(j)=k;%取得最大类间方差的阈

    end

end

K1=sum(K)/j %取多个k的平均值作为最佳阈值

 

%用Ostu方法的最佳阈值处理

for i=1:M

        for j=1:N

            if (Img(i,j)>K1)

               Img1(i,j)=255;

            else

               Img1(i,j)=0;

            end

        end

End

 

figure(3);imhist(Img1);title('Otsu直方图');

figure(4);imshow(Img1);title('Otsu最佳阈值处理图像');

text('Position',[400,480],'String','Otsu最佳阈值:','color','r')%标注最佳阈值

text('Position',[510,480],'String',num2str(K1),'color','r')

 

运行结果如下:

 

 

 

 

 

 

 

 

 

 

最优全局阈值:102

 

 

 

 

posted @ 2014-12-09 17:08  辰空  阅读(775)  评论(0编辑  收藏  举报