一、设计依据
在掌握数字图像处理基本算法的基础上,利用MATLAB、VC++、Python等编程语言设计具有指定功能的图形用户界面。
二、设计内容
1、设计一个实现图像边缘提取功能的界面
2、界面可以采用MATLAB等编程语言设计
3、要求界面能够读入并显示图片,通过各种控件选择并进行图像的边缘检测和提取操作,操作结果在对比窗口中显示
4、图像边缘检测和提取功能至少包括单方向一阶微分检测(水平/垂直方向)、无方向微分检测(Roberts算子、Sobel算子、Prewitt算子、Laplacian算子、LOG算子)等,每项功能可采用一个或多个算法实现
目 录
第一章 设计方案
1.1设计目的
本学期开设了数字图像处理的课程,在课上老师讲解了图像的基本知识,介绍了图像处理的一些算法,为了检验对于知识的掌握以及锻炼实用能力,使用相应编程语言实现对于一副图像的处理。
1.2设计要求
设计一个实现图像边缘提取功能的界面,编程实现对于图像的读入和显示,并通过各种控件对读入的图像进行处理,实现边缘检测和提取效果,图像边缘检测和提取功能至少包括单方向一阶微分检测(水平/垂直方向)、无方向微分检测(Roberts算子、Sobel算子、Prewitt算子、Laplacian算子、LoG算子)等,每项功能可采用一个或多个算法实现。
1.3设计方案
我们使用MATLAB进行设计实现,先在电脑上安装好MATLAB。然后通过GUI可视化界面设计出一个简单布局,添加各种控件,来实现相应功能。用到的控件有:按钮控件(用来实现添加图像和退出操作)、弹出式菜单控件(用来选择不同的图像处理方法)、坐标轴控件(用来展示图像)、面板控件(用来把一类控件放置在一起)。
首先要把外部的一幅图像读入到界面中并显示出来,这个是最基本的,然后对图像进行灰度化处理得到灰度图像,在灰度图像的基础上进行各种处理,我们按照要求设计了对图像的一阶微分检测和无方向检测,这两部分放在两个面板中。其中无方向检测我们添加了Sobel、Canny、LoG、Roberts、Prewitt这些算法来实现。在MATLAB工具箱中提供了用于边缘提取的edge()函数,由edge()函数可以实现各算子对图像边缘的提取。除此之外,我们还在界面当中添加了图像增强功能,分为均值滤波处理和伪彩色处理。最后在界面中加入了退出按钮,实现了退出操作。界面展示如图1-1所示:
图1-1 设计界面
第二章 原理介绍
2.1算法简介
得益于MATLAB这个软件提供了强大的功能,各种算法都已经集成在其库中,因此我们需要了解的是对于这些算法函数的调用。要对一幅彩色图像进行边缘提取,先对其进行灰度化处理比较好,为此我们使用到了rgb2gray()函数,rgb2gray()是MATLAB内部一种处理图像的函数,通过消除图像色调和饱和度信息同时保留亮度实现将RGB图像或彩色图转换为灰度图像,即灰度化处理的功能,调用这个功能的格式是:I = rgb2gray(RGB),意思是将真彩色图像RGB转换为灰度强度图像I。灰度化处理有多种处理方式:分量法、最大法、平均法、加权平均法,Matlab 中采用的是对R、G、B分量进行加权平均的算法:0.2989R+ 0.5870G + 0.1140B。
Sobel算子:该算子是像素图像边缘检测中最重要的算子之一,在机器学习、数字媒体、计算机视觉等信息科技领域起着举足轻重的作用。在技术上,它是一个离散的一阶差分算子,用来计算图像亮度函数的一阶梯度之近似值。在图像的任何一点使用此算子,将会产生该点对应的梯度矢量或是其法矢量。该算子包含两组3×3的矩阵,分别为横向及纵向,将之与图像作平面卷积,即可分别得出横向及纵向的亮度差分近似值。如果以A代表原始图像,Gx及Gy分别代表经横向及纵向边缘检测的图像,其公式如下:
图2-1 Sobel算子核心公式
Canny算子:该算子是一种多级边缘检测算子,步骤是降噪、寻找梯度、跟踪边缘。Canny算子适用于不同的场合,它的参数允许根据不同实现的特定要求进行调整以识别不同的边缘特性。
LoG算子:该算法首先对图像做高斯滤波,然后再求其拉普拉斯(Laplacian)二阶导数,即图像与 Laplacian of the Gaussian function 进行滤波运算,最后,通过检测滤波结果的零交叉(Zero crossings)可以获得图像或物体的边缘。常用的LoG算子是5×5的模板。
Roberts算子:是一种利用局部差分算子寻找边缘的算子。采用对角线方向相邻两象素之差近似梯度幅值检测边缘。检测垂直边缘的效果好于斜向边缘,定位精度高,对噪声敏感,无法抑制噪声的影响。Roberts边缘算子是一个2×2的模板。
Prewitt算子:是一种一阶微分算子的边缘检测,利用像素点上下、左右邻点的灰度差,在边缘处达到极值检测边缘,去掉部分伪边缘,对噪声具有平滑作用。其原理是在图像空间利用两个方向模板与图像进行邻域卷积来完成的,这两个方向模板一个检测水平边缘,一个检测垂直边缘。
图2-2 Prewitt算子
2.2控件设计
2.2.1按钮控件
利用版图编辑器在布局区添加按钮,双击控件调出属性编辑器,对其进行属性设计。String表示控件的显示信息,Tag表示控件的唯一标识符。右击button选择“Callback”选项可查看其回调函数。
2.2.2弹出式菜单控件
为了节约界面空间,我们考虑将同类算法放在一个列表框下面,需要采取某种算法提取,直接在下拉列表框中选择即可。在下拉列表框中将相应算法名称写入其中,在其回调函数中写上相关代码以调用不同算法函数。
第三章 功能实现
1、点击添加按钮,加入一幅彩色图像,如图3-1所示,后台程序自动将其灰度化。
第四章 设计结果与分析
4.1边缘提取
边缘提取,指在数字图像处理中,对于图片轮廓的一个处理。边缘定义为图像灰度变化率最大的地方或图像灰度值变化最剧烈的地方,在函数上表现为拐点,拐点是指函数发生凹凸性变化的点,是二阶导数为零的地方。
边缘提取的基本思想首先是利用边缘增强算子,突出图像中的局部边缘,然后定义象素的“边缘强度”,通过设置阈值的方法提取边缘点集。由于噪声和模糊的存在,检测到的边界可能会变宽或在某点处发生间断。因此,边界检测包括两个基本内容:(1)用边缘算子提取出反映灰度变化的边缘点集。(2)在边缘点集合中剔除某些边界点或填补边界间断点,并将这些边缘连接成完整的线。
4.2结果分析
边缘检测的算法有如下四个步骤:
(1)滤波:边缘检测算法主要是基于图像增强的一阶和二阶导数,但导数的计算对噪声很敏感,因此需要使用滤波器来改善与噪声有关的边缘检测器的性能。
(2)增强:增强边缘的基础是确定图像各点邻域强度的变化值。增强算法可以将邻域强度有显著变化的点突显出来。边缘增强一般都是通过计算梯度幅值来完成的。
(3)检测:在图像中有许多点的梯度幅值比较大,而这些点在特定的应用领域中并不都是边缘,所以应该用某种方法来确定哪些是边缘点。最简单的边缘检测判据是梯度幅值阈值判据。
(4)定位:如果某一应用场合要求确定边缘位置,则边缘的位置可在子像素分辨率上来估计,边缘的方位也可以被估计出来。
对提取结果的分析:根据各个提取图像的观察可大致看出,Roberts算子边缘定位精度较高,但容易丢失一部分边缘,同时图像没经过平滑处理,所以不具备抑制噪声的能力。该算子适用于具有陡峭边缘且含噪声少的图像;Sobel算子和Prewitt算子对噪声具有一定抑制能力,但不能完全排除虚假边缘。定位效果不错但容易产生多像素边缘;LoG算子抑制噪声时会将尖锐的边缘平滑掉而无法被检测到。当高斯滤波器宽度参数取值较小时,边缘定位精度高,但图像平滑作用较弱,增大取值时,又导致模板增大,使边缘位置偏移严重,且运动量增加;对于Canny算子,当弱边缘和强边缘相连时,才输出弱边缘,检测效果要比LoG算子好。由此可知,算子不同,结果存在明显差异,但是在灰度图像上边缘明显的部分都被有效的提取出来了。Roberts算子检测出的边缘线比较清晰,但噪声大多也同时提取出来了。对于模糊部分取差分间隔宽的Sobel算子和Prewitt算子似乎有效。Canny算子可以检测到弱边缘,但受阴影的影响较大。LoG算子易于强化噪声,更适用于点状物的检测和图像锐化。
总 结
本次设计,既是对于课堂所学知识的有效补充,也是对于我们实践能力的极大提升。数字图像处理是交叉学科,是未来技术向智能化发展的最富有前景,也是最富有挑战的领域,其研究的领域博大精深,应用范围十分广泛。人类获取的信息80%以上来自于视觉,因此对于图像和视频的分析与处理显得尤为重要,特别是近几年随着人工智能的发展,让机器更有效地去处理视频和图像成了人们最迫切的心愿,当前让机器去处理这些信息还有很大的局限,数字图像处理这门学科方兴未艾,在这门学科上辛勤耕耘一定会有光明前景。通过这次课程设计,我们简单实现了课上所学过的图像处理当中的边缘检测与提取,更加深刻得了解到了不同算法所带来的不同结果,同时也对创造出这些算法的科学家们感到深深的佩服。学海无涯、学无止境,我们应该树立终身学习的意识,并要勇于实践、大胆尝试,以应对这个知识迅速增长的时代。
参考文献
[1] Rafael C. Gonzalez,Richard E. Woods,Steven L. Eddins.Digital Image Processing Using MATLAB[M].Publishing House of Electronics Industry.
[2] 胡学龙.数字图像处理[M].电子工业出版社.
[3] Andreas Koschan,Mongi Abidi.Digital Color Image Processing[M].清华大学出版社.
[4] 孙正.数字图像处理技术及应用.机械工业出版社.
附 录
程序代码
function varargout = main_trans(varargin)
gui_Singleton = 1;
gui_State = struct('gui_Name', mfilename, ...
'gui_Singleton', gui_Singleton, ...
'gui_OpeningFcn', @main_trans_OpeningFcn, ...
'gui_OutputFcn', @main_trans_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
function main_trans_OpeningFcn(hObject, eventdata, handles, varargin)
handles.output = hObject;
guidata(hObject, handles);
function varargout = main_trans_OutputFcn(hObject, eventdata, handles)
varargout{1} = handles.output;
function popupmenu1_Callback(hObject, eventdata, handles)
function popupmenu1_CreateFcn(hObject, eventdata, handles)
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
set(hObject,'BackgroundColor','white');
end
function pushbutton1_Callback(hObject, eventdata, handles)
[filename,pathname] = uigetfile({'*.jpg;*.jpeg;*.bmp;*.gif;*.png'},'选择图片');
if isequal(filename,0)
disp('用户放弃选择')
else
disp(['选择图片:', filename])
end
img_filename = fullfile(pathname,filename);
ori_img=imread(img_filename);
% 转化为灰度图
if(size(ori_img,3)>1)
gray_img = rgb2gray(ori_img);
ori_img = imread(img_filename);
end
handles.ori_img=gray_img;
handles.filename=filename;
axes(handles.axes3)
guidata(hObject,handles);
imshow(ori_img)
title('原始图像')
guidata(hObject,handles);
function pushbutton4_Callback(hObject, eventdata, handles)
clc
function pushbutton5_Callback(hObject, eventdata, handles)
clc
if(isfield(handles,'ori_img')==0)
msgbox('请点击选择图片按钮!')
else
ori_img=handles.ori_img;
filename=handles.filename;
[M,N]=size(ori_img);
h=ones(3,3)/9;%均值滤波器
I=imfilter(ori_img,h);
axes(handles.axes2)
imshow(I)
title('均值滤波')
end
function popupmenu2_CreateFcn(hObject, eventdata, handles)
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
set(hObject,'BackgroundColor','white');
end
function popupmenu3_Callback(hObject, eventdata, handles)
function popupmenu3_CreateFcn(hObject, eventdata, handles)
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
set(hObject,'BackgroundColor','white');
end
function popupmenu4_Callback(hObject, eventdata, handles)
function popupmenu4_CreateFcn(hObject, eventdata, handles)
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
set(hObject,'BackgroundColor','white');
end
function pushbutton6_Callback(hObject, eventdata, handles)
close(main_trans)
function popupmenu5_Callback(hObject, eventdata, handles)
function popupmenu5_CreateFcn(hObject, eventdata, handles)
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
set(hObject,'BackgroundColor','white');
end
function pushbutton8_Callback(hObject, eventdata, handles)
clc
if(isfield(handles,'ori_img')==0)
msgbox('请点击选择图片按钮!')
else
ori_img=handles.ori_img;
[M,N]=size(ori_img);
a=[-1 -2 -1;0 0 0;1 2 1]/256;b=[-1 0 1;-2 0 2;-1 0 1]/256;
level=conv2(ori_img,a,'same');
axes(handles.axes2);
imshow(abs(level));
title('水平方向检测')
end
function axes2_CreateFcn(hObject, eventdata, handles)
function pushbutton10_Callback(hObject, eventdata, handles)
clc
if(isfield(handles,'ori_img')==0)
msgbox('请点击选择图片按钮!')
else
ori_img=handles.ori_img;
[M,N]=size(ori_img);
a=[-1 -2 -1;0 0 0;1 2 1]/256;b=[-1 0 1;-2 0 2;-1 0 1]/256;
perpendicular=conv2(ori_img,b,'same');
axes(handles.axes2);
imshow(abs(perpendicular));
title('垂直方向检测')
end
function pushbutton11_Callback(hObject, eventdata, handles)
clc
function togglebutton2_Callback(hObject, eventdata, handles)
function slider1_CreateFcn(hObject, eventdata, handles)
if isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
set(hObject,'BackgroundColor',[.9 .9 .9]);
end
function pushbutton12_Callback(hObject, eventdata, handles)
clc
if(isfield(handles,'ori_img')==0)
msgbox('请点击选择图片按钮!')
else
ori_img=handles.ori_img;
filename=handles.filename;
[M,N]=size(ori_img);
h=ones(8,8)/64;%均值滤波器
I=imfilter(ori_img,h);
axes(handles.axes2)
imshow(I)
title('均值滤波')
end
标签:提取,img,图像,hObject,边缘,handles,算子 From: https://blog.csdn.net/2401_86539719/article/details/141200884