篇首语:本文由编程笔记#小编为大家整理,主要介绍了图像分割基于阙值+边缘检测+区域法图像分割matlab源码含GUI相关的知识,希望对你有一定的参考价值。
是一种最常用的并行区域技术,它是图像分割中应用数量最多的一类。阈值分割方法实际上是输入图像f到输出图像g的如下变换:
其中,T为阈值,对于物体的图像元素g(i,j)=l,对于背景的图像元素g(i,j)=0。
由此可见,阈值分割算法的关键是确定阈值,如果能确定一个合适的阈值就可准确地将图像分割开来。如果阈值选取过高,则过多的目标区域将被划分为背景,相反如果阈值选取过低,则过多的背景将被划分到目标区[7]。阈值确定后,将阈值与像素点的灰度值比较和像素分割可对各像素并行地进行,分割的结果直接给出图像区域。
阈值分割必须满足一个假设条件:图像的直方图具有较明显的双峰或多峰,并在谷底选择闭值。因此这种方法对目标和背景反差较大的图像进行分割的效果十分明显,而且总能用封闭、连通的边界定义不交叠的区域。
阈值分割法主要分为全局和局部两种,目前应用的闭值分割方法都是在此基础上发展起来的,比如最小误差法、最大相关法、最大嫡法、矩量保持法、Otsu最大类间方差法等,而应用最广泛的是Otsu最大类间方差法。
人们发展了各种各样的阈值处理技术,包括全局阈值、自适应阈值、最佳阈值等等。 全局阈值是指整幅图像使用同一个阈值做分割处理,适用于背景和前景有明显对比的图像。它是根据整幅图像确定的:T=T(f)。但是这种方法只考虑像素本身的灰度值,一般不考虑空间特征,因而对噪声很敏感。常用的全局阈值选取方法有利用图像灰度直方图的峰谷法、最小误差法、最大类间方差法、最大熵自动阈值法以及其它一些方法。在许多情况下,物体和背景的对比度在图像中的各处不是一样的,这时很难用一个统一的阈值将物体与背景分开。这时可以根据图像的局部特征分别采用不同的阈值进行分割。实际处理时,需要按照具体问题将图像分成若干子区域分别选择阈值,或者动态地根据一定的邻域范围选择每点处的阈值,进行图像分割。这时的阈值为自适应阈值。阈值的选择需要根据具体问题来确定,一般通过实验来确定。对于给定的图像,可以通过分析直方图的方法确定最佳的阈值,例如当直方图明显呈现双峰情况时,可以选择两个峰值的中点作为最佳阈值。
阈值分割的优点是计算简单、运算效率较高、速度快,在算法上容易实现,在重视运算效率的应用场合(如用于硬件实现),它得到了广泛应用。它对目标和背景对比度反差较大图像这种分割很有效, 而且总能用封闭、连通的边界定义不交叠的区域。但它不适用于多通道图像和特征值相关不大的图像,对图像中不存在明显灰度差异或各物体的灰度值范围有较大重叠的图像分割问题难以得到准确结果。另外由于阈值确定主要依赖于灰度直方图, 而很少考虑图像中像素的空间位置关系,因此当背景复杂,特别在是同一背景上重叠出现若干个研究目标时,或图像中噪声信号较多时,目标的灰度值与背景相差无几等情形下,容易丧失部分边界信息,按照固定的阈值进行分割所得到的结果就不准确,造成分割不完整,需要进一步的精确定位。
区域生长和分裂合并法是两种典型的串行区域技术,其分割过程后续步骤的处理要根据前面步骤的结果进行判断而确定。
(1)区域生长
区域生长的基本思想是将具有相似性质的像素集合起来构成区域。具体先对每个需要分割的区域找一个种子像素作为生长的起点,然后将种子像素周围邻域中与种子像素有相同或相似性质的像素(根据某种事先确定的生长或相似准则来判定)合并到种子像素所在的区域中。将这些新像素当作新的种子像素继续进行上面的过程,直到再没有满足条件的像素可被包括进来。
区域生长需要选择一组能正确代表所需区域的种子像素,确定在生长过程中的相似性准则,制定让生长停止的条件或准则。相似性准则可以是灰度级、彩色、纹理、梯度等特性。选取的种子像素可以是单个像素,也可以是包含若干个像素的小区域。大部分区域生长准则使用图像的局部性质。生长准则可根据不同原则制定,而使用不同的生长准则会影响区域生长的过程。
区域生长法的优点是计算简单,对于较均匀的连通目标有较好的分割效果,对有复杂物体定义的复杂场景的分割或者对自然景物的分割等类似先验知识不足的图像分割, 效果均较理想,Wu H S等提出利用肺部癌细胞图像的均值、标准偏差构成的矢量作为细胞分割的特征, 提出的区域增长分割算法分割肺部癌细胞纹理图像, 取得较好结果[10]。它的缺点是需要人为确定种子点,虽然其抗噪性能优于边缘分割和直方图分割,但仍对噪声敏感,可能导致区域内有空洞;另外,它是一种串行算法,当目标较大时,分割速度较慢,因此在设计算法时,要尽量提高效率;而且在计算过程中引入的预定误差值选取不当时,还会引入误判,易受分析目标内部组织之间的重叠干扰影响。因此,基于区域生长的分割方法一般适合于边缘光滑、无重叠的细胞图象的分割。
(2)区域分裂合并
区域生长是从某个或者某些像素点出发,最后得到整个区域,进而实现目标提取。分裂合并差不多是区域生长的逆过程:从整个图像出发,不断分裂得到各个子区域,然后再把前景区域合并,实现目标提取。分裂合并的假设是对于一幅图像,前景区域由一些相互连通的像素组成的,因此,如果把一幅图像分裂到像素级,那么就可以判定该像素是否为前景像素。当所有像素点或者子区域完成判断以后,把前景区域或者像素合并就可得到前景目标。在这类方法中,最常用的方法是四叉树分解法。设R代表整个正方形图像区域,P代表逻辑谓词。基本分裂合并算法步骤如下:
① 对任一个区域,如果H(Ri)=FALSE就将其分裂成不重叠的四等份;
② 对相邻的两个区域Ri和Rj,它们也可以大小不同(即不在同一层),如果条件H(Ri∪Rj)=TRUE满足,就将它们合并起来。
③ 如果进一步的分裂或合并都不可能,则结束。
分裂合并法的关键是分裂合并准则的设计。这种方法对复杂图像的分割效果较好,但算法较复杂,计算量大,分裂还可能破坏区域的边界。
图像分割的一种重要途径是通过边缘检测,即检测灰度级或者结构具有突变的地方,表明一个区域的终结,也是另一个区域开始的地方。这种不连续性称为边缘。不同的图像灰度不同,边界处一般有明显的边缘,利用此特征可以分割图像。图像中边缘处像素的灰度值不连续,这种不连续性可通过求导数来检测到。对于阶跃状边缘,其位置对应一阶导数的极值点,对应二阶导数的过零点(零交叉点)。因此常用微分算子进行边缘检测[11]。
常用的一阶微分算子有Roberts算子、Prewitt算子和Sobel算子,二阶微分算子有Laplace算子和Kirsh算子等。在实际中各种微分算子常用小区域模板来表示,微分运算是利用模板和图像卷积来实现。这些算子对噪声敏感,只适合于噪声较小不太复杂的图像。由于边缘和噪声都是灰度不连续点,在频域均为高频分量,直接采用微分运算难以克服噪声的影响。因此用微分算子检测边缘前要对图像进行平滑滤波。
Roberts算子有利于对具有陡峭边缘的低噪声图像的分割;laplacian算子具有各向同性的特点;Roberts算子和laplacian算子在实施过程中大大增强了噪声,恶化了信噪比。Prewitt算子、Sobel算子等有利于对具有较多噪声且灰度渐变图像的分割。Log算子和Canny算子是具有平滑功能的二阶和一阶微分算子,边缘检测效果较好。其中Log算子是采用Laplacian算子求高斯函数的二阶导数,Canny算子是高斯函数的一阶导数,它在噪声抑制和边缘检测之间取得了较好的平衡。Marr算法对有较多噪声的图像具有平滑作用,且其边缘检测效果优于以上几种算子,但Marr算法在平滑的同时导致图像对比度下降[7]。Kirch算法利用对梯度图像适当的阈值进行二值化, 使得目标和背景像素点低于阈值, 而大多数边缘点高于阀值, 同时为了提高性能, 在该类算法中可引入分水岭算法以进行准确分割[1]。
Hough变换法利用图像全局特性而直接检测目标轮廓,将边缘像素连接起来组成区域封闭边界的一种常见方法。在预先知道区域形状的条件下,利用哈夫变换可以方便地得到边界曲线而将不连续的边界像素点连接起来。它的主要优点是受噪声和曲线间断的影响较小。
对于灰度变化复杂和细节较丰富图象,边缘检测算子均很难完全检测出边缘,而且一旦有噪声干扰时,上述算子直接处理效果更不理想。这一方法用来分割显微图象的例子不多,因为显微图象中的许多纹理或颗粒会掩盖真正的边缘,虽然可以通过有关算法改进,但效果并不太好。
拟合算子( 即参数模型匹配算法)原理:用边缘的参数模型对图像的局部灰度值进行拟合, 再在拟合的参数模型上进行边缘检测。优缺点:此类算子在检测边缘的同时, 还平滑了噪声, 对有较大噪声和高纹理细胞图像处理效果较好, 但由于参数模型记录着更多的边缘结构信息, 计算开销很大, 算法复杂, 而且对边缘类型要求较高。
以上三种方法中,基于边缘分割的最常见的问题是在没有边界的地方出现了边缘以及在实际存在边界的地方没有出现边界, 这是由图像噪声或图像中的不适合的信息造成的[24]。基于区域增长方法分割后的图像, 时常是由于参数的设置非最优性造成, 不是含有太多的区域就是含有过少的区域。阈值化是最简单的分割处理, 计算代价小, 速度快, 用一个亮度常量即阈值来分割物体和背景。
function varargout = Segimage(varargin)
gui_Singleton = 1;
gui_State = struct('gui_Name', mfilename, ...
'gui_Singleton', gui_Singleton, ...
'gui_OpeningFcn', @Segimage_OpeningFcn, ...
'gui_OutputFcn', @Segimage_OutputFcn, ...
'gui_LayoutFcn', [] , ...
'gui_Callback', []);
if nargin && ischar(varargin{1})
gui_State.gui_Callback = str2func(varargin{1});
end
if nargout
[varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:});
else
gui_mainfcn(gui_State, varargin{:});
end
% End initialization code - DO NOT EDIT
% --- Executes just before Segimage is made visible.
function Segimage_OpeningFcn(hObject, eventdata, handles, varargin)
handles.output = hObject;
guidata(hObject, handles);
% --- Outputs from this function are returned to the command line.
function varargout = Segimage_OutputFcn(hObject, eventdata, handles)
varargout{1} = handles.output;
% -----载入图像
function inputimage_Callback(hObject, eventdata, handles)
[filename, pathname] = uigetfile( ...
{'*.bmp;*.jpg;*.png;*.tif;*.jpeg?s=#39;, 'Image Files (*.bmp;*.jpg;*.png;*.tif;*.jpeg)'; ...
'*.*', 'All Files (*.*)'}, ...
'Pick an Image');
axes(handles.axes_src);
fpath=[pathname filename];
img_src=imread(fpath);
global S
S=img_src;
imshow(img_src);
% -----绘制灰度直方图
function imhist_Callback(hObject, eventdata, handles)
global S
figure,imhist(S)
% --------------------------------------------------------------------
function Thresholdmethod_Callback(hObject, eventdata, handles)
% hObject handle to Thresholdmethod (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
% --------------------------------------------------------------------
function Edgedet_Callback(hObject, eventdata, handles)
% hObject handle to Edgedet (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
% --------------------------------------------------------------------
function Areamethod_Callback(hObject, eventdata, handles)
% hObject handle to Areamethod (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
% ----迭代式阀值
function diedai_Callback(hObject, eventdata, handles)
axes(handles.axes_dst);
global S
tic ; %计时器
[x,y]=size(S); % 求出图象大小
b=double(S);
zd=double(max(max(S))); % 求出图象中最大的灰度
zx=double(min(min(S))) ; % 最小的灰度
T=double((zd+zx))/2; % T赋初值,为最大值和最小值的平均值
count=double(0); % 记录几次循环
while 1 % 迭代最佳阈值分割算法
count=count+1;
S0=0.0; n0=0.0; %为计算灰度大于阈值的元素的灰度总值、个数赋值
S1=0.0; n1=0.0; %为计算灰度小于阈值的元素的灰度总值、个数赋值
for i=1:x
for j=1:y
if double(S(i,j))>=T
S1=S1+double(S(i,j)); %大于阈域值图像点灰度值累加
n1=n1+1; %大于阈域值图像点个数累加
else
S0=S0+double(S(i,j)); %小于阈域值图像点灰度值累加
n0=n0+1; %小于阀域值图像点个数累加
end
end
end
T0=S0/n0; %求小于阀域值均值
T1=S1/n1; %求大于阀域值均值
if abs(T-((T0&#43;T1)/2))<0.1 %迭代至 前后两次阀域值相差几乎为0时停止
break;
else
T&#61;(T0&#43;T1)/2; %在阈值T下&#xff0c;迭代阈值的计算过程
end
end
count ; %显示运行次数
disp(&#39;迭代法最佳阀值&#xff1a;&#39;)
T %显示最佳阈值 算出T
toc ; %显示运算时间
i1&#61;im2bw(S,T/255); % 图像在最佳阈值下二值化
imshow(i1);
title(&#39;迭代阀值分割结果&#39;);
% -------Otsu阀值法
function otsu_Callback(hObject, eventdata, handles)
axes(handles.axes_dst);
global S
T&#61;graythresh(S);
g&#61;im2bw(S,T);
imshow(g);
title(&#39;otsu阀值分割结果&#39;);
% ------分水岭法
function watershed_Callback(hObject, eventdata, handles)
global S
f&#61;S;
%计算梯度图
f&#61;double(f);
hv&#61;fspecial(&#39;prewitt&#39;);
hh&#61;hv.&#39;;
gv&#61;abs(imfilter(f,hv,&#39;replicate&#39;));
gh&#61;abs(imfilter(f,hh,&#39;replicate&#39;));
g&#61;sqrt(gv.^2&#43;gh.^2);
%计算距离函数
df&#61;bwdist(f);
%计算外部约束
L&#61;watershed(df);
em&#61;L&#61;&#61;0;
%计算内部约束
im&#61;imextendedmax(f,20);
%重构梯度图
g2&#61;imimposemin(g,im|em);
%watershed算法分割
L2&#61;watershed(g2);
axes(handles.axes_dst);
imshow(uint8(f));
title(&#39;分水岭法分割结果&#39;);
% --------------------------------------------------------------------
function roberts_Callback(hObject, eventdata, handles)
% hObject handle to roberts (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
axes(handles.axes_dst);
global S
[g,t]&#61;edge(S,&#39;roberts&#39;,[],&#39;both&#39;);
imshow(g);
title(&#39;Roberts算子分割结果&#39;);
% --------------------------------------------------------------------
function sobel_Callback(hObject, eventdata, handles)
% hObject handle to sobel (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
axes(handles.axes_dst);
global S
[g,t]&#61;edge(S,&#39;sobel&#39;,[],&#39;both&#39;);
imshow(g);
title(&#39;Sobel算子分割结果&#39;);
% --------------------------------------------------------------------
function prewitt_Callback(hObject, eventdata, handles)
% hObject handle to prewitt (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
axes(handles.axes_dst);
global S
[g,t]&#61;edge(S,&#39;prewitt&#39;,[],&#39;both&#39;);
imshow(g);
title(&#39;Prewitt算子分割结果&#39;);
% --------------------------------------------------------------------
function log_Callback(hObject, eventdata, handles)
% hObject handle to log (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
axes(handles.axes_dst);
global S
[g,t]&#61;edge(S,&#39;log&#39;);
imshow(g);
title(&#39;Log算子分割结果&#39;);
% --------------------------------------------------------------------
function canny_Callback(hObject, eventdata, handles)
% hObject handle to canny (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
global S
imshow(g);
title(&#39;Canny算子分割结果&#39;);
% -------区域生长法
function grow_Callback(hObject, eventdata, handles)
global S
image&#61;S;
else
I&#61;image;
end
完整代码或仿真咨询QQ1575304183