Matlab(2):图像分割笔记

写在开头

这是博主的图像作业之一
本着熟悉知识+经验分享的精神而作,如果有任何疑问可以联系博主,相互学习。
文章材料部分(图像)来自互联网,如有侵权请联系博主删除!
WX公众号:小杂货铺9527,给你更多惊喜!

图像分割

总体目的

按照一定规律将图像或景物划分为多个子集
定位目标在图中的位置和范围

基本策略

本文主要介绍基于灰度的分割方法,依据不同区域灰度值的不连续性进行分割,其实就可以二分类或多分类方法进行处理了。

主要算法

基于阈值的分割方法
基于边缘的分割方法
基于区域的分割方法
基于数学形态学的分割方法
基于特定理论的分割方法
(聚类分析、小波变换、模糊集理论、基因编码)

阈值方法—直方图法

基本思想

通过建立图像的灰度直方图,选择两峰之间的谷底对应的灰度值作为阈值,可以处理背景颜色单一的图片,对复杂图片无能为力。
也就是这样
在这里插入图片描述

数学表达式

g ( x , y ) = { 255 , f ( x , y ) ≥ T 0 , f ( x , y ) < T g(x,y)=\begin{cases} 255,\quad f(x,y)\ge T \\ 0,\qquad f(x,y)\lt T \end{cases} g(x,y)={255,f(x,y)T0,f(x,y)<T

实验用图

在这里插入图片描述

Matlab代码

clc;
clear;

data1 = imread('cs0001.jpg');  %记得用自己的图片名
data = data1;
gdata1 = (0.299*data1(:,:,1)+0.587*data1(:,:,2)+0.114*data1(:,:,3));
gdata = gdata1;
[width,height ] = size(gdata1);

elements = zeros(1,255);
for i = 1:width
    for j = 1:height
        elements(1,round(gdata1(i,j))+1) = elements(1,round(gdata1(i,j))+1) + 1;
    end
end
x = 1:255;
y = elements;
plot(x,y)

gdata2 = zeros(size(gdata1));
for i = 1:width
    for j = 1:height
        if gdata1(i,j)>=120
            gdata2(i,j)=gdata1(i,j);
        else
            gdata2(i,j)=0;
        end
    end
end
figure(2);
subplot(1,2,1);imshow(gdata1);title('灰度图');
subplot(1,2,2);imshow(gdata2);title('分割后的图');

输出结果

直方图

在这里插入图片描述
大概在两个峰之间选一个值,这儿选的是120

分割结果

在这里插入图片描述

区域方法—区域生长法

基本思想

确定种子像素,域相邻像素比较,如果相似就加到生长区域中
重复上述过程,直到没有像素加入为止

简单生长法(依赖种子点)

种 子 点 f ( s , t ) , 邻 域 点 f ( m , n ) 若 ∣ f ( m , n ) − f ( s , t ) ∣ < T , 就 把 该 点 加 入 生 长 区 域 种子点f(s,t),邻域点f(m,n)\\ 若\lvert f(m,n)-f(s,t)\rvert \lt T, 就把该点加入生长区域 f(s,t),f(m,n)f(m,n)f(s,t)<T

质心生长法(增强抗干扰性)

种 子 点 f ( s , t ) , 邻 域 点 f ( m , n ) , 已 生 长 区 域 灰 度 均 值 f ( s , t ) ‾ 若 ∣ f ( m , n ) − f ( s , t ) ‾ ∣ < T , 就 把 该 点 加 入 生 长 区 域 种子点f(s,t),邻域点f(m,n),已生长区域灰度均值 \overline{f(s,t)}\\ 若\lvert f(m,n)-\overline{f(s,t)}\rvert \lt T, 就把该点加入生长区域 f(s,t),f(m,n)f(s,t)f(m,n)f(s,t)<T

实验用图(CT图)

在这里插入图片描述

Matlab代码

clc;
clear;

data1 = imread('2_5.jpg');   %记得改图片名
data = data1;
gdata1 = (0.299*data1(:,:,1)+0.587*data1(:,:,2)+0.114*data1(:,:,3));
gdata = gdata1;
imshow(gdata1);title('灰度图');
labelflag = zeros(size(gdata1));   %标记信号
[width,height ] = size(gdata1);
yuzhi = 40;  %阈值为40


%% 鼠标交互选择初始点
%右击初始点,回车;或者直接左键初始点
if( exist('x','var') == 0 && exist('y','var') == 0)
    imshow(gdata1);title('灰度图');
    gdata1 = double(gdata1);
    [y,x] = getpts;%鼠标取点  回车确定
    x1 = round(x(1));%选择种子点
    y1 = round(y(1));
end


% 区域生长——简单生长法
gdata2 = zeros(size(gdata));
gdata2(:,:) = 255;
array_x = x1;
array_y = y1;
[h,l] = size(array_x);
labelflag(x1,y1) = 1;
while l ~= 0 && h ~= 0     %当所有被标记点被涂色后停止
    array_x
    x = array_x(1); y = array_y(1);
    gdata2(x,y) = 0;
    figure(2)         
    imshow(gdata2);title('分割后的图');
    for u = -1:1
        for v = -1:1
            if x+u>0 && x+u <=width && y+v <=height && y+v>0
                if abs(gdata1(x1,y1) - gdata1(x + u,y + v)) < yuzhi...
                                && labelflag(x + u,y + v) == 0
                    labelflag(x + u,y + v) = 1;
                    array_x = [array_x,x + u];  
                    array_y = [array_y,y + v]; 
                end
            end
        end
    end
    array_x(1) = [];array_y(1) = [];   %把已经涂过的点去掉
    [h,l] = size(array_x);
end
figure(2)         
imshow(gdata2);title('分割后的图');


% %% 质心生长法
% %把上面那段注释掉再运行这一段或者自己改一下
% gdata2 = zeros(size(gdata));
% gdata2(:,:) = 255;
% array_x = x1;
% array_y = y1;
% [h,l] = size(array_x);
% labelflag(x1,y1) = 1;
% array_all = gdata1(x1,y1);
% while l ~= 0 && h ~= 0
%     array_x
%     x = array_x(1); y = array_y(1);
%     gdata2(x,y) = 0;
%     figure(2)         
%     imshow(gdata2);title('分割后的图');
%     for u = -1:1
%         for v = -1:1
%             if x+u>0 && x+u <=width && y+v <=height && y+v>0
%                 if (abs(mean(array_all) - gdata1(x + u,y + v)) < yuzhi...
%                                 && labelflag(x + u,y + v) == 0)
%                             
%                     array_all = [gdata1(x1,y1),gdata(x+u,y+v)];
%                     labelflag(x + u,y + v) = 1;  
%                     array_x = [array_x,x + u];  
%                     array_y = [array_y,y + v]; 
%                 end
%             end
%         end
%     end
%     array_x(1) = [];array_y(1) = [];   %把已经涂过的点去掉
%     [h,l] = size(array_x);
% end
% figure(2)         
% imshow(gdata2);title('分割后的图');

输出结果

在这里插入图片描述

结果分析

阈值法对元素简单的图比较友好;
区域生长法计算较为简单,但需要人工获得种子像素点,且计算过程较为缓慢;
区域生长法对噪声比较敏感,会产生空洞或断裂;
质心生长法减弱了对种子点的过分依赖的缺陷,分割效果会好一些。

写在结尾

感谢阅读,代码博主亲测可用,如有问题可以联系博主,一起交流成长。
文章材料部分来自互联网,如有侵权请联系博主删除!

  • 8
    点赞
  • 45
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
Matlab写的区域生长图像分割程序。 %区域生长算法:region function LabelImage=region(image,seed,Threshold,maxv) %image:输入图像 %seed:种子点坐标堆栈 %threshold:用邻域近似生长规则的阈值 %maxv:所有生长的像素的范围小于maxv % LabelImage:输出的标记图像,其中每个像素所述区域标记为rn [seedNum,tem]=size(seed);%seedNum为种子个数 [Width,Height]=size(image); LabelImage=zeros(Width,Height); rn=0;%区域标记号码 for i=1:seedNum %从没有被标记的种子点开始进行生长 if LabelImage(seed(i,1),seed(i,2))==0 rn=rn+1;% %对当前生长区域赋标号值 LabelImage(seed(i,1),seed(i,2))=rn; % end stack(1,1)=seed(i,1);%将种子点压入堆栈(堆栈用来在生长过程中的数据坐标) stack(1,2)=seed(i,2); Start=1;%定义堆栈起点和终点 End=1; while(Start<=End) %当前种子点坐标 CurrX=stack(Start,1); CurrY=stack(Start,2); %对当前点的8邻域进行遍历 for m=-1:1 for n=-1:1 % %判断像素(CurrX,CurrY)是否在图像内部 % rule1=(CurrX+m)=1&(CurrY+n)=1; % %判断像素(CurrX,CurrY)是否已经处理过 % rule2=LabelImage(CurrX+m,CurrY+n)==0; % %判断生长条件是否满足 % rule3=abs(double(image(CurrX,CurrY))-double(image(CurrX+m,CurrY+n)))<Threshold; % %条件组合 % rules=rule1&rule2&rule3; if (CurrX+m)=1&(CurrY+n)=1&LabelImage(CurrX+m,CurrY+n)==0&abs(double(image(CurrX,CurrY))-double(image(CurrX+m,CurrY+n)))<=Threshold&image(CurrX+m,CurrY+n)0 %堆栈的尾部指针后移一位 End=End+1; %像素(CurrX+m,CurrY+n)压入堆栈 stack(End,1)=CurrX+m; stack(End,2)=CurrY+n; %把像素(CurrX,CurrY)设置成逻辑1 LabelImage(CurrX+m,CurrY+n)=rn; end end end %堆栈的尾部指针后移一位 Start=Start+1; end end end
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值