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('分割后的图');
输出结果
结果分析
阈值法对元素简单的图比较友好;
区域生长法计算较为简单,但需要人工获得种子像素点,且计算过程较为缓慢;
区域生长法对噪声比较敏感,会产生空洞或断裂;
质心生长法减弱了对种子点的过分依赖的缺陷,分割效果会好一些。
写在结尾
感谢阅读,代码博主亲测可用,如有问题可以联系博主,一起交流成长。
文章材料部分来自互联网,如有侵权请联系博主删除!