【数字图像处理】噪点检测、区域生长、算子边缘检测、单阈值分割(第四章-图像增强 实验:图像分割与边缘检测)

噪点检测

在图像中加入一个孤立噪声点,选择合适的算子将之检测出

%点检测
img=imread('flower.jpg');
img(60,60)=0;
figure,subplot(121),imshow(img),title('原图');

n=3;
[width,height]=size(img);
img_1=double(img);
img2=img_1;
for i=2:width-n+1
    for j=2:height-n+1
        x=img_1(i:i+n-1,j:j+n-1);
        xx=-sum(sum(x))+9*x(1+(n-1)/2,1+(n-1)/2);%孤立点检测,中间系数为8,其他系数都为-1 【先全部减一,再把中间点加9img2(i+(n-1)/2,j+(n-1)/2)=xx/8;
    end
end
    img3=abs(img2(2:height-1,2:width-1));%边缘不是梯度,所以去掉
   % figure,imshow(unit8(img3));
    T=max(max(img3));%求一次max是求得每一列的最大值
    img3(img3==T)=255;
    img3(img3<T)=0;
    img_end=unit8(img3);
subplot(122),imshow(img_end),title('点检测');

在这里插入图片描述

Prewitt算子进行边缘检测

//Prewitt水平、垂直算子

%Prewitt水平算子函数
function [img_end] = Prewitt(img,PrewittThreshold)
[m,n]=size(img);
img_end=img;
for i=2:m-1
    for j=2:n-1
        temp=abs((img(i-1,j-1)+img(i-1,j)+img(i-1,j+1))-(img(i+1,j-1)+img(i+1,j)+img(i+1,j+1)));%水平模板
        if(temp>PrewittThreshold)
            img_end(i,j)=255;
        else
            img_end(i,j)=0;
        end
    end
end
end
%Prewitt垂直算子函数
function [img_end] = PrewittChuizhi(img,PrewittThreshold)
[m,n]=size(img);
img_end=img;
for i=2:m-1
    for j=2:n-1
        temp=abs((img(i-1,j-1)+img(i,j-1)+img(i+1,j-1))-(img(i+1,j+1)+img(i+1,j)+img(i+1,j-1)));%垂直模板
        img2(i,j)=temp;
        if(temp>PrewittThreshold)
            img_end(i,j)=255;
        else
            img_end(i,j)=0;
        end
    end
end
end
%%自写函数实现边缘检测
img=imread('Cameraman.bmp');
PrewittThreshold=20;
img_end=Prewitt(img,PrewittThreshold);
figure,subplot(131), imshow(img_end),title('Prewitt水平');

PrewittThreshold=9;
img_end2=PrewittChuizhi(img,PrewittThreshold);
subplot(132), imshow(img_end2),title('Prewitt垂直');

//Prewitt综合算子

PrewittThreshold=100;
[m,n]=size(img);
img=double(img);
img_end3=img;
for i=2:m-1
    for j=2:n-1
        temp=abs((img(i-1,j-1)+img(i-1,j)+img(i-1,j+1))-(img(i+1,j-1)+img(i+1,j)+img(i+1,j+1))+(img(i-1,j-1)+img(i,j-1)+img(i+1,j-1))-(img(i+1,j+1)+img(i+1,j)+img(i+1,j-1)));
        img1(i,j)=temp;
        if(temp>PrewittThreshold)
            img_end3(i,j)=255;
        else
            img_end3(i,j)=0;
        end
    end
end

subplot(133), 
imshow(img_end3),title('Prewitt综合');

//Matlab自带函数

%%自带函数
img_end4=edge(img,'Prewitt',0.09,'horizontal');
figure,subplot(131),imshow(img_end4),title('Prewitt水平');
img_end5=edge(img,'Prewitt',0.09,'vertical');
subplot(132),imshow(img_end5),title('Prewitt垂直');
img_end6=edge(img,'Prewitt',0.09);
subplot(133),imshow(img_end6),title('Prewitt综合');

在这里插入图片描述

自动单阈值分割

利用直方图人工指定阈值对rice进行自动单阈值分割;

img = imread('rice.tif');
%img = double(img);
figure;
subplot(221),imshow(img),title('原图');
subplot(222),imhist(img,256),title('原图的频率直方图');
img1 = img;
[m,n] = size(img1);
for i = 1:m
    for j = 1:n
        if img1(i,j)>100 && img1(i,j)<255   
            img1(i,j)=1;
        else
            img1(i,j)=0;
        end
    end
end
subplot(223),imshow(double(img1)),title('分割后结果');

在这里插入图片描述

迭代法进行单阈值分割
img = imread('rice.gif');
figure;
subplot(121);
imshow(img);
title('原图')
T = mean2(img); 
flag = false;   
i = 0;
% while循环进行迭代
while ~flag
    r1 = find(img<=T);  %小于阈值的部分
    r2 = find(img>T);   %大于阈值的部分
    Tnew = (mean(img(r1)) + mean(img(r2))) / 2;  
    flag = abs(Tnew - T) < 1;     
    T = Tnew;      
    i = i+1;
end
img(r1) = 0;   %小于阈值=0
img(r2) = 1;   %大于阈值=1 
subplot(122);
imshow(img,[]);
title('迭代法')

在这里插入图片描述

OSTU算法
img=imread('rice.gif');
 figure;
subplot(121);
imshow(img);
title('原图')
 omiga_o=mean(mean(img));
 elem=tabulate(img(:));
 [m,n]=size(img);
 for i=1:size(elem,1)
     pa=sum(elem(1:i,2));
     pb=m*n-pa;
     omiga_a=sum(elem(1:i,1).*(elem(1:i,2)/pa));
     omiga_b=sum(elem(i+1:end,1).*(elem(i+1:end,2)/pb));
     temp=(pa*power(omiga_a-omiga_o,2)+pb*power(omiga_b-omiga_o,2))/(m*n);
     delta(i)=temp;
 end
 [Y,U]=max(delta);
 img(img<U)=0;img(img>U)=255;
 subplot(122);
imshow(img);

在这里插入图片描述

区域生长算法

利用区域生长算法对money.jpg进行分割。

BW=imread('money.jpg');
figure,imshow(BW);
I = im2double(BW);% 做成从0-255变成01之间 变成double类型好计算
%x=450; y=450;
[y1,x1]=getpts;%内部取种子点
x=round(x1);            %横坐标取整
y=round(y1);            %纵坐标取整

%J = regiongrowing(I,x1,y1,0.17); 
%%%%%%%%%%%%%%%regiongrowing算法%%%%%%%%%%%%%%%%%%%
%一边分割一边生长,连续区域均值
reg_maxdist=0.17;%设定生长准则

J = zeros(size(I)); % Output,要分割的图像 0矩阵,跟原图像一样大
%J=0,J=1,入栈,纳入候选点 J=2 可分割
Isizes = size(I); % Dimensions of input image

reg_mean = I(x,y); % 被分割出来的区域灰度均值 目前只有一个点,则就是这个点的 The mean of the segmented region 
reg_size = 1; % 被分割出来的区域所包含像素点的个数 Number of pixels in region
neg_free = 10000;%neg_free 栈可存点的个数
neg_pos=0;% neg_free 栈下标
neg_list = zeros(neg_free,3); %栈 存生长点的候选点 存进去的是横纵坐标和灰度值

%当前只有一个
pixdist=0; %灰度差 放在候选区域里面的 即栈里的 ,跟分割好的区域的灰度均值的灰度差,若灰度差是最小的那一个,则可生长 Distance of the region newest pixel to the regio mean

% Neighbor locations (footprint)
neigb=[-1 0; 1 0; 0 -1;0 1];%四邻域

%终止条件:被分割出来的像素点的个数>总像素数 或 灰度差大于生长准则
while(pixdist<reg_maxdist&&reg_size<numel(I))

    % Add new neighbors pixels
    for j=1:4,
        % Calculate the neighbour coordinate
        xn = x +neigb(j,1); yn = y +neigb(j,2);
        
        % Check if neighbour is inside or outside the image
        %%判断是否越界 要在图像内部
        ins=(xn>=1)&&(yn>=1)&&(xn<=Isizes(1))&&(yn<=Isizes(2));
        
        % Add neighbor if inside and not already part of the segmented area
        %若没有越界且还没有对此点进行生长
        if(ins&&(J(xn,yn)==0)) 
                %将此点存入栈
                neg_pos = neg_pos+1;%开始坐标从1开始
                neg_list(neg_pos,:) = [xn yn I(xn,yn)];%追加到栈的尾部
                J(xn,yn)=1;%(xn,yn)进栈
        end
    end

    % Add a new block of free memory
    %检查一下栈是不是被占满了,若被占满,则扩容
    if(neg_pos+10>neg_free), neg_free=neg_free+10000; neg_list((neg_pos+1):neg_free,:)=0; end
    
    % Add pixel with intensity nearest to the mean of the region, to the region
    %找出满足生长条件的点
    dist = abs(neg_list(1:neg_pos,3)-reg_mean);%返回【栈里(1-neg_pos)的像素灰度值】与【被分割出来的区域均灰度值】的差的绝对值 数组
   %min用两个变量来承接,则返回的是[值,索引]
    [pixdist, index] = min(dist);%找到最小的那一个
    J(x,y)=2;%找出被分割的点,赋2
    reg_size=reg_size+1;%被分割出来的像素点个数加一
    
    % Calculate the new mean of the region
    reg_mean= (reg_mean*reg_size + neg_list(index,3))/(reg_size+1);%更新reg_mean
    
    % Save the x and y coordinates of the pixel (for the neighbour add proccess)
    %种子点重新换了 把刚被分割出来的点作为种子点
    x = neg_list(index,1); 
    y = neg_list(index,2);
    
    % Remove the pixel from the neighbour (check) list
    %清除
    neg_list(index,:)=neg_list(neg_pos,:); %将栈顶元素赋值给种子点位置 (种子点已经是种子点了,就可以出栈了)
    neg_pos=neg_pos-1;
end
J=J>1;%逻辑运算 把已经分割出来的点变为真,其他变为假

figure, imshow(I+J);

[n,m]=size(BW);
img=zeros(size(BW));
for i=1:n
    for j=1:m
        if(J(i,j))
            img(i,j)=I(i,j);
        end
    end
end
figure,imshow(img);

在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值