资源描述
图像校正及分割处理软件设计与实现
《图像分析与模式识别》课程期末大作业报告
课程名称: 图像分析与模式识别
学 院: 信息工程与自动化学院
专 业: 计算机技术
年 级: 2014级
学生姓名: 樊祥锰
学生学号: 2014704101
指导教师: 刘 辉 2015-01-01
昆明理工大学信息工程与自动化学院
目录
图像校正及分割处理软件设计与实现 1
1 软件需求 1
1.1 操作界面需求分析 1
1.2 图像几何校正需求分析 1
1.2 ISODATA聚类算法的图像分割需求分析 2
2 算法原理及流程图 2
2.1 Hough变换 2
2.1.1 Hough变换原理 2
2.1.2 图像几何校正流程 3
2.2 ISODATA算法原理 3
2.2.1 ISODATA算法原理步骤 3
2.2.1 ISODATA算法流程图 5
3 程序设计框图 6
4 实验结果及分析 7
4.1 图像几何 7
4.1.1 支票图像几何校正结果 7
4.1.1 支票图像几何校正结果分析 8
4.2 图像分割 8
4.2.1图像分割结果 8
4.2.1图像分割结果分析 10
附录: 11
附录一:图像几何校正代码 11
附录一:ISODATA聚类算法图像分割代码 11
附录一:MATLAB的GUI操作界面代码 17
《图像分析与模式识别》课程 期末大作业报告 姓名:赵世瑜 学号:2013204067
图像校正及分割处理软件设计与实现
摘要:设计一种图像几何校正及图像分割处理软件,实现对倾斜支票图像校正为水平,及对已给的图像进行分割。图像几何校正主要通过边缘检测、Hough变换、求倾斜角、图像旋转等算法实现;图像分割采用ISODATA聚类算法实现。实验结果表明,实现了对倾斜支票图像几何校正和对图像的分割功能。
关键词:边沿检测;Hough变换、图像旋转、ISODATA算法;图像分割;
1 软件需求
需求分析是指对要解决的问题进行详细的分析,弄清楚问题的要求,包括整个系统所要实现的功能。
根据题目,设计需要编写带有操作界面的图像处理软件,功能包含图像几何校和基于ISODATA聚类算法的图像分割。开发工具使用MATLAB。根据MATLAB的特点及需要实现的软件功能,软件需求分析如下:
1.1 操作界面需求分析
软件实现的功能是图像处理,因此操作界面中需要一个按钮,用于选择待处理的图像,称为“图像选择”按钮;选择的原始图像需要在操作界面中显示,因此需要一个用于显示原始图像的坐标控件;由于软件需要实现多功能,需要一个下拉框实现功能的选择;一个开始功能处理的按钮,称为“开始处理”按钮;一个用于显示图像处理结果的坐标控件。最后需要一个退出操作界面的按钮,称为“退出”按钮。
1.2 图像几何校正需求分析
原始图像在拍照时出现了倾斜,需要将图像校正,消除倾斜。通过对图像的观察,图像是一张支票,支票上存在表格。因此想法是通过检测支票表格边框线的倾斜角,就是整张图像的倾斜程度,然后根据这个倾斜角旋转,便可得到校正的水平图像。要检测支票图像表格边框直线。需要对图像的边缘进行检测,图像的边缘检测方法很多,如:sobel算子边缘检测,prewitt算子边缘检测,roberts算子边缘检测,log算子边缘检测,canny算子边缘检测等,由于原图的噪声并不是很严重,因此上面这些边缘检测办法都能胜任,这里使用log算子进行边缘检测,为了适应其它边缘检测方法,本设计需要尽量在改变边缘检测方法时尽可能少地修改代码。边缘检测后,采用Hough变换提取直线,然后在提取的直线上找两个点,计算出直线的倾斜角度。最后根据这个倾斜角度对图像进行旋转。
1.2 ISODATA聚类算法的图像分割需求分析
ISODATA聚类算法的图像分割功能,ISODATA比较复杂,因此主要是ISODATA算法的实现。设计的处理过程是,在操作界面选择了待处理的图像后,选择图像分割功能,点击开始处理按钮后,弹出图像,通过鼠标左键选择聚类中心点,然后按回车键或者单击鼠标右键确认后,调用ISODATA对图像进行分割。
2 算法原理及流程图
设计的功能有图像几何和基于ISODATA聚类算法的图像分割。图像几何校正功能中,采用Hough变换对支票表格边框直线进行检测;ISODATA聚类算法的图像分割功能和核心是ISODATA聚类算法。对其原理及实现的流程图分析如下。
2.1 Hough变换
哈夫变换是利用图像全局特性而直接检测目标轮廓,就可将边缘像素连接起来组成区域封闭边界的一种方法。在预先知道区域形状的条件下,利用哈夫变换可以方便地得到边界曲线而将不连续的边缘像素点连接起来。
2.1.1 Hough变换原理
哈夫变换的基本思想是点-线对偶性。图像变换前在图像空间,变换后在参数空间。在图像空间XY里,所有过点(x, y)的直线都满足方程:
y=px+q
写成:
q=-px+y (1)
可以认为代表参数空间PQ中过点(p,q)的一条直线。
图1 图像空间 图2 参数空间
图像空间的点(xi, yi)和(xj, yj)对应参数空间两条直线,它们的交点(p’, q’)对应图像空间XY中过(xi, yi)和(xj, yj)的直线,这样,图像空间XY中过(xi, yi)和(xj,yj)的直线上的所有点都对应参数空间PQ里的一条直线,这些直线相交于点(p’, q’) 。
在图像空间中共线的点对应在参数空间中相交的线,反过来,在参数空间中交于同一个点的所有直线在图像空间中都有共线的点相对应,这就是点-线对偶性。根据点-线对偶性,当给定图像空间的一些边缘点,就可以通过哈夫变换确定连接这些点的直线方程,哈夫变换把图像空间中的直线检测问题转换到参数空间里点检测的问题。
2.1.2 图像几何校正流程
图像几何校正中使用的Hough变换算法采用MATLAB已经封装好的hough函数,这里不要详细阐述其流程,整个图像几何校正的流程如图3所示:
图3 图像几何校正流程图
2.2 ISODATA算法原理
ISODATA算法的思想是,在每轮迭代过程中,样本重新调整类别之后计算类内及类间有关参数,并和设定的门限比较,确定是两类合并为一类还是一类分裂为两类,不断地“自组织”,以达到在各参数满足设计要求条件下,使各模式到其类心的距离平方和最小。
2.2.1 ISODATA算法原理步骤
⑴ 预置
① 设定聚类分析控制参数:
=预期的类数,
=初始聚类中心个数(可以不等于c),
137
=每一类中允许的最少模式数目,
=类内各分量分布的距离标准差上界,(分裂用)
=两类中心间的最小距离下界,(合并用)
=在每次迭代中可以合并的类的最多对数,
=允许的最多迭代次数。
② 将待分类的模式特征矢量读入;
③
④ 选定初试聚类中心,可从待分类的模式特征矢量集中任选Nc个模式特征矢量作为初始聚类中心;
(2)按最小距离原则将模式集中每一个模式分到某一类中;
(3)依据每一类中允许的最少模式数目判断合并;
(4)计算分类后的参数:分类中心,;类平均距离及中体平均距离;
① 计算各类的中心
(2)
② 计算各类中模式到类心的平均距离
(3)
③ 计算各个模式到其类内中心的总体平均距离
(4)
(5)依据Ip, Nc判断停止、分类或合并;
(6)计算各类类内距离的标准差矢量;
(5)
(7)对每一次聚类,求出类内距离标准差矢量中的最大分量;
(8)在(7)所得结果中对任一最大值大于类内各分量分布的距离标准差上界则分裂;
(9)计算各对聚类中心间的距离;
(10)依据两类中心间的最小距离下界判断合并;
(11)如果迭代次数Ip已达I次或过程收敛,则结束,否则,Ip=Ip+1,若需要调整参数,则转(1),若不改变参数则转(2);
2.2.1 ISODATA算法流程图
图4 ISODATA聚类算法流程图
3 程序设计框图
根据需求分析,对整个操作界面及其中的函数调用等,对整个程序进行分析。操作界面运行后,单击选择图像按钮选择待处理的图像。然后选择要对图形进行处理的功能,单击开始处理按钮,调用相应的处理方法进行处理,整个程序的设计框图如图5所示:
图5 程序设计框图
设计好的操作界面如下图所示:
图6 操作界面设计结果
4 实验结果及分析
4.1 图像几何
4.1.1 支票图像几何校正结果
图像几何校正功能中,对支票图像的校正如下图所示:
图7 图像结合校正处理中
图8 图像结合校正处理中
4.1.1 支票图像几何校正结果分析
通过支票图像几何校正结果可知,设计达到了预计的结果。通过MATLAB运行提取计算斜率的坐标为 (1200,522)和(1540, 511)。直线的斜率为slope = -0.0324,通过次斜率计算出的倾斜角度为angle = -1.8530。根据人眼观测结果显示支票的请倾斜角也比较小,而且根据校正后的支票图像结果显示已经水平。即达到了实验设计目的。
4.2 图像分割
4.2.1图像分割结果
在运行图像分割功能时,需要通过鼠标选择预期聚类,其中选择之一如图9所示:
图9 选择预期的聚类中心
图10 图像分割处理中
最终对图像的分割结果如下图所示:
图11 图像分割结果(a)
图11 图像分割结果(b)
图13 图像分割结果(c)
图14 图像分割结果(d)
4.2.1图像分割结果分析
通过多次选择不同的预期聚类中心的实验结果表明,设计基本完成了所需的功能。同时也证明了设计的合理性,以及ISODATA聚类算法在图像分割中的运用。结果显示,把鸭子的眼睛分成了一类,把鸭子的嘴分成了一类,把鸭子的身体分成了一类,虽然有时分类结果不是非常好。但选择预期聚类中心时有一定的影响。总体来看,仍然达到了图像分割的目的。
本学期在《图像分析与模式识别》课程中学到很多,学到的不仅仅是课程相关的知识。更重要的是学到了许多处理和解决问题的思想,相信对今后的学习会有很大的帮助。这都是刘辉老师教导的结果,在此对刘辉老师表示衷心感谢!
附录:
附录一:图像几何校正代码
function jiaozheng = jiaozheng(cheque)
BW_laplace = edge(cheque,'log');% log算子边缘检测
BW2 = bwmorph(BW_laplace, 'thin',Inf);%细化
[H,T,R] = hough(BW2); %Hough变换
P = houghpeaks(H,5); %提取Hough变换后参数平面上的峰值点
lines = houghlines(BW2,T,R,P); %提取直线
for k = 1:length(lines)
xy = [lines(k).point1; lines(k).point2]; %提取坐标
end
slope=(xy(2,2)- xy(1,2))/(xy(2,1)-xy(1,1)); %求斜率
radian=atan(slope);%求角度
angle=radian*180/pi; %转化成角度
jiaozheng=imrotate(cheque,angle); %图像校正
imshow(jiaozheng);
close ;
附录一:ISODATA聚类算法图像分割代码
function isodata=isodata_zsy(I)
%%%%%%%%%%%%%%%%%1..样本点为所有的像素点%%%%%%%%%%
%%%%%%%%%%%%%%% 2...聚类中心点的确定%%%%%%%%%%%%%%
figure(1);
imshow(I,[]),title('请选取预期聚类的中心点,完成后请按回车键或单击鼠标右键');
[m,n]=size(I);
k=4; % k 用来记录预期聚类的数目这里假定为4
c=k; % c来记录实际分类时的数目
hold on;
[p,q]=getpts; %获取聚类中心,返回去类中心的坐标,p存放第一个坐标点,q存放第二个坐标点(数对)
J=zeros(1,3*c); %?
for i=1:c
f=round(q(i)); %分为c类 J来记录各类的中心像素值...(坐标和像素值)
d=round(p(i));
J(i)=I(f,d);
end
%disp(J);
%%%%%%%%%%%%%%%%%3...将样本点分到各个聚类中心去%%%%%%%%%%%%%
max_gen=10; %max_gen最大迭代次数
w=1;
%while w<max_gen
A=zeros(m,n);
for i=1:m
for j=1:n
dis=[0,0,0,0]; %用来记录样本点与每个聚类中心的距离
for x=1:4
dis(1,x)=(I(i,j)-J(x))*(I(i,j)-J(x));
end
%disp(dis);
[min1,temp]=min(dis);
A(i,j)=J(temp);
end
end
%disp(A);
%%%%%%%%%%%4....依据一个类中的最小聚类数判断是否舍去聚类点%%%%%%%%%%
sN=6; %sN一个聚类中至少含有的样本数目
count=zeros(1,3*c); %count数组用来记录每个聚类中含有的样本数目
for i=1:m
for j=1:n
for x=1:c
if A(i,j)==J(x)
count(x)=count(x)+1;
end
end
end
end
for x=1:c-1
if count(x)<sN
J(x)=J(x+1);
count(x)=count(x+1); %类的数目减少一个
c=c-1;
end
end
if count(x)<sN
count(x)=0;
c=c-1;
end
%%%%%%%%%%%5...更新聚类中心%%%%%%%%%%%%%%%%%%%%%%%%%%%
for x=1:c
sum=0;
for i=1:m
for j=1:n
if A(i,j)==J(x)
sum=sum+I(i,j);
end
end
end
J(x)=round(1.0/count(x)*sum*1.0); %更新中心
end
%%%%%%%%%%%%%%%6....各类的样本离开中心的平均距离%%%%%%%%%%%%
meandis=zeros(1,c);
for x=1:c
sum=0;
for i=1:m
for j=1:n
if A(i,j)==J(x)
sum=sum+abs(I(i,j)-J(x));
end
end
end
meandis(x)=1.0/count(x)*sum;
end
%%%%%%%%%%7...所有样本离开其相应的聚类中心的平均距离%%%%%%%%
g_meandis=0; %g_meandis记录平均距离
N=m*n;
for x=1:c
g_meandis=g_meandis+count(x)* meandis(x); %
end
g_meandis=g_meandis/N;
%%%%%%%%%%%%8....决定是走向合并还是分裂%%%%%%%%%%%%
sC=1.5; %sC为合并参数
if w==max_gen-1 %如果这是最后一次迭代置合并参数为0
sC=0;
end
disp(g_meandis);
if c<k/2+1|mod(w,2)==1 %继续做步骤8
%%%%%%%%%%%%9...实际聚类中心数跟预期数相比太小要进行分裂%%%%%%%%%%%%
%%%%%%%%%%%%对各个聚类求标准偏差%%%%%%%%%%%%%%%%%%%%%%%%
std_err=zeros(1,c);
for x=1:c
sum1=zeros(1,c);
for i=1:m
for j=1:n
if A(i,j)==J(x)
sum1(x)=sum1(x)+((I(i,j)-J(x))*(I(i,j)-J(x)));
end
end
end
std_err(x)=sqrt(1/count(x)*sum1(x)*1.0);
end
%%%%%%%%%%%%%10..求最大标准差分量..灰度图特征分量为1%%%%%%%%%%%%
%%%%%%%%%%11..决定是否分裂%%%%%%%%%%%%%%%%%%%%
t=0.6 ; % t为(0,1]之间的数保证样本仍在两个集合中
r=zeros(1,c);
J_rec=J;
for x=1:c
if std_err(x)> g_meandis&count(x)>2*(sN+1)
r(x)=t*meandis(x);
c=c+1; %实际类的数目加1
J_rec(x)=J(x); %记录原中心点的灰度值
J(x)=J(x)+r(x);
J(c)=J(x)-r(x);
for i=1:m %将分裂之后的像素重新安排所归属的类中心
for j=1:n
if A(i,j)==J_rec(x)
if abs(I(i,j)-J(c))<abs(I(i,j)-J(x))
A(i,j)=J(c);
count(c)=count(c)+1; %记录新增的类含样本的个数
else
A(i,j)=J(x);
end
end
end
end
count(x)=count(x)-count(c); %count(x)含样本的个数
end
end
%%%%%%%%%%%%%%%%12...计算所有的聚类中心两两距离%%%%%%%%%%%
else
betwen_dis=zeros(c,c);
for i=1:c
for j=1:i
betwen_dis(i,j)=abs(J(i)-J(j));
betwen_dis(j,i)=betwen_dis(i,j); % 这个矩阵为一对称矩阵
end
end
%%%%%%%%%%%%%%%%%13..将小于最小合并参数的 betwen_dis(i,j)%%%%%%%%
sL=2; %每次迭代允许的最大聚类对的数目
line=zeros(1,c*c)-1;
s=1;
for i=1:c
for j=1:i
if betwen_dis(i,j)<sC
line(s)=betwen_dis(i,j);
s=s+1;
end
end
end
if s>1
for i=1:s-1
temp1=i;
for j=i+1:s
if line(j)<line(temp1) %选择排序法对line进行排序
temp1=j;
end
if temp1~=i
temp2=line(temp1);
line(temp1)=line(i);
line(i)=temp2;
end
end
end
end
if s>sL % 当s超过最大合并对数时将s的值变为允许的最大聚类对的数目
s=sL;
end
%%%%%%%%%%%%%%14...从最小的进行合并%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%
temp_c=c;
for x=1:s
for i=1:temp_c
for j=1:temp_c
J_temp=J;
if betwen_dis(i,j)==line(x)&i>j %矩阵为一对称矩阵.....只看下三角
c=c-1;
J(j)=round(1.0/(count(i)+count(j)))*(count(i)*J(i)+count(j)*J(j));
count(j)=count(i)+count(j); %合并后聚类中新含有新样本的个数
for g=1:m %将合并之后的像素重新安排所归属的类中心
for h=1:n
if A(g,h)==J_temp(i)|A(g,h)==J_temp(j)
A(g,h)=J(j);
end
end
end
if i==temp_c
count(i)=0;
else
for g=i:c-1
J(g)=J(g+1); %将记录后面类中心像素值前移
count(g)=count(g+1);
end
end
end
end
end
end
%%%%%%%%%%%%%%%%%15....计数器加1进行迭代直到结束
end
w=w+1; %进行下一次迭代
A=round(A);
isodata=mat2gray(A);
close;
附录一:MATLAB的GUI操作界面代码
function varargout = sztxfx_mssb_zsy(varargin)
gui_Singleton = 1;
gui_State = struct('gui_Name', mfilename, ...
'gui_Singleton', gui_Singleton, ...
'gui_OpeningFcn', @sztxfx_mssb_zsy_OpeningFcn, ...
'gui_OutputFcn', @sztxfx_mssb_zsy_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 sztxfx_mssb_zsy is made visible.
function sztxfx_mssb_zsy_OpeningFcn(hObject, eventdata, handles, varargin)
% Choose default command line output for sztxfx_mssb_zsy
handles.output = hObject;
% Update handles structure
guidata(hObject, handles);
% --- Outputs from this function are returned to the command line.
function varargout = sztxfx_mssb_zsy_OutputFcn(hObject, eventdata, handles)
varargout{1} = handles.output;
% --- Executes during object creation, after setting all properties.
function axes1_CreateFcn(hObject, eventdata, handles)
set(hObject,'xTick',[]);
set(hObject,'ytick',[]);
set(hObject,'box','on');
% Hint: place code in OpeningFcn to populate axes1
% --- Executes during object creation, after setting all properties.
function axes2_CreateFcn(hObject, eventdata, handles)
set(hObject,'xTick',[]);
set(hObject,'ytick',[]);
set(hObject,'box','on');
% Hint: place code in OpeningFcn to populate axes2
% --- Executes on button press in togglebutton1.
function togglebutton1_Callback(hObject, eventdata, handles)
global imgage
% global info
[filename,pathname]=uigetfile({'*.bmp';'*.tif';'*.jpg';'*.gif';'*.*'},'选择图片');
if pathname == 0
return;
end
str=[pathname filename];
% info=imfinfo(str);
imgage=imread(str);
axes(handles.axes1);
imshow(imgage);
% Hint: get(hObject,'Value') returns toggle state of togglebutton1
% --- Executes on selection change in popupmenu1.
function popupmenu1_Callback(hObject, eventdata, handles)
global value
value = get(hObject,'Value');
switch value
case 1
cla;
end
% --- Executes during object creation, after setting all properties.
function popupmenu1_CreateFcn(hObject, eventdata, handles)
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
set(hObject,'BackgroundColor','white');
end
% --- Executes on button press in togglebutton2.
function togglebutton2_Callback(hObject, eventdata, handles)
global imgage
global value
[m n]=size(imgage);
axes(handles.axes2);
switch value
case 1
cla;
case 2
h = waitbar(0.1,'正在处理,请稍候...');
IMG=jia
展开阅读全文