canny边缘检测及matlab实现
图像边缘检测各种算子MATLAB实现以及实际应用

《图像处理中的数学方法》实验报告学生姓名:赵芳舟教师姓名:曾理学院:数学与统计学院专业:信息与计算科学学号:联系方式:梯度和拉普拉斯算子在图像边缘检测中的应用一、数学方法边缘检测最通用的方法是检测灰度值的不连续性,这种不连续性用一阶和二阶导数来检测。
1.(1)一阶导数:一阶导数即为梯度,对于平面上的图像来说,我们只需用到二维函数的梯度,即:,该向量的幅值:,为简化计算,省略上式平方根,得到近似值;或通过取绝对值来近似,得到:。
(2)二阶导数:二阶导数通常用拉普拉斯算子来计算,由二阶微分构成:2.边缘检测的基本思想:(1)寻找灰度的一阶导数的幅度大于某个指定阈值的位置;(2)寻找灰度的二阶导数有零交叉的位置。
3.几种方法简介(1)Sobel边缘检测器:以差分来代替一阶导数。
Sobel边缘检测器使用一个3×3邻域的行和列之间的离散差来计算梯度,其中,每行或每列的中心像素用2来加权,以提供平滑效果。
-1-21000121-101-202-101(2)Prewitt边缘检测器:使用下图所示模板来数字化地近似一阶导数。
与Sobel检测器相比,计算上简单一些,但产生的结果中噪声可能会稍微大一些。
-1-1-1000111-101-101-101(3)Roberts边缘检测器:使用下图所示模板来数字化地将一阶导数近似为相邻像素之间的差,它与前述检测器相比功能有限(非对称,且不能检测多种45°倍数的边缘)。
-10010-110(4)Laplace边缘检测器:二维函数的拉普拉斯是一个二阶的微分定义:0101-41010(八邻域)(5)LoG边缘检测器由于噪声点(灰度与周围点相差很大的像素点)对边缘检测有一定的影响,所以效果更好的是LoG算子,即Laplacian-Guass算子。
引入高斯函数来平滑噪声:该函数的Laplace算子:它把Guass平滑滤波器和Laplace锐化滤波器结合起来,先平滑掉噪声,再进行边缘检测,所以效果比单用Laplace算子要更为平滑,效果更好。
canny边缘检测matlab代码

canny边缘检测matlab代码Canny边缘检测是一种常用的图像处理算法,它可以有效地检测图像中的边缘,并将其显示为白色线条。
在Matlab中,可以使用以下代码实现Canny边缘检测:1. 读取图像首先,需要读取待处理的图像。
可以使用imread函数来读取图片:```matlabimg = imread('image.jpg');```其中,image.jpg是待处理的图片文件名。
2. 灰度化Canny算法只能处理灰度图像,因此需要将彩色图像转换为灰度图像。
可以使用rgb2gray函数来实现:```matlabgray_img = rgb2gray(img);```3. 高斯滤波在进行边缘检测之前,需要对图像进行高斯滤波来消除噪声。
可以使用fspecial和imfilter函数来实现:```matlabgaussian_filter = fspecial('gaussian', [5 5], 1);blur_img = imfilter(gray_img, gaussian_filter, 'replicate');```其中,[5 5]表示高斯核的大小为5x5,1表示标准差。
4. 计算梯度幅值和方向接下来,需要计算每个像素点的梯度幅值和方向。
可以使用Sobel算子来计算梯度,并利用arctan函数计算方向角度:```matlabsobel_x = [-1 0 1; -2 0 2; -1 0 1];sobel_y = [-1 -2 -1; 0 0 0; 1 2 1];grad_x = imfilter(blur_img, sobel_x, 'replicate');grad_y = imfilter(blur_img, sobel_y, 'replicate');grad_mag = sqrt(grad_x.^2 + grad_y.^2);grad_dir = atan(grad_y ./ grad_x);```5. 非极大值抑制由于Sobel算子计算出的梯度幅值可能会有多个峰值,因此需要进行非极大值抑制来保留边缘。
基于Matlab的图像边缘检测算法的实现及应用汇总

目录摘要 (1)引言 (2)第一章绪论 (3)1.1 课程设计选题的背景及意义 (3)1.2 图像边缘检测的发展现状 (4)第二章边缘检测的基本原理 (5)2.1 基于一阶导数的边缘检测 (8)2.2 基于二阶导的边缘检测 (9)第三章边缘检测算子 (10)3.1 Canny算子 (10)3.2 Roberts梯度算子 (11)3.3 Prewitt算子 (12)3.4 Sobel算子 (13)3.5 Log算子 (14)第四章MATLAB简介 (15)4.1 基本功能 (15)4.2 应用领域 (16)第五章编程和调试 (17)5.1 edge函数 (17)5.2 边缘检测的编程实现 (17)第六章总结与体会 (20)参考文献 (21)摘要边缘是图像最基本的特征,包含图像中用于识别的有用信息,边缘检测是数字图像处理中基础而又重要的内容。
该课程设计具体考察了5种经典常用的边缘检测算子,并运用Matlab进行图像处理结果比较。
梯度算子简单有效,LOG 算法和Canny 边缘检测器能产生较细的边缘。
边缘检测的目的是标识数字图像中灰度变化明显的点,而导函数正好能反映图像灰度变化的显著程度,因而许多方法利用导数来检测边缘。
在分析其算法思想和流程的基础上,利用MATLAB对这5种算法进行了仿真实验,分析了各自的性能和算法特点,比较边缘检测效果并给出了各自的适用范围。
关键词:边缘检测;图像处理;MATLAB仿真引言边缘检测在图像处理系统中占有重要的作用,其效果直接影响着后续图像处理效果的好坏。
许多数字图像处理直接或间接地依靠边缘检测算法的性能,并且在模式识别、机器人视觉、图像分割、特征提取、图像压缩等方面都把边缘检测作为最基本的工具。
但实际图像中的边缘往往是各种类型的边缘以及它们模糊化后结果的组合,并且在实际图像中存在着不同程度的噪声,各种类型的图像边缘检测算法不断涌现。
早在1965 年就有人提出边缘检测算子,边缘检测的传统方法包括Kirsch,Prewitt,Sobel,Roberts,Robins,Mar-Hildreth 边缘检测方法以及Laplacian-Gaussian(LOG)算子方法和Canny 最优算子方法等。
Matlab在边缘检测与边界提取中的应用

Matlab在边缘检测与边界提取中的应用在计算机视觉领域中,边缘检测与边界提取是非常重要的任务。
边缘是图像中物体不同区域之间的分界线,边界提取则是通过检测图像中的边缘,从而凸显物体的轮廓。
边缘检测与边界提取在许多应用中都发挥着重要作用,如图像分割、目标识别和机器视觉等。
Matlab是一种功能强大且流行的科学计算软件,它提供了许多用于边缘检测和边界提取的工具和函数。
下面将介绍一些常用的Matlab函数和技术,它们在边缘检测与边界提取中的应用。
一、基于梯度的边缘检测梯度是表示图像中变化的指标,边缘通常是图像灰度值变化剧烈的区域。
Matlab中的Sobel、Prewitt和Roberts等函数可以方便地计算图像的梯度,从而实现边缘检测。
例如,使用Sobel算子可以对图像进行边缘检测:```I = imread('image.jpg');gray = rgb2gray(I);sobel_x = edge(gray, 'sobel', 'horizontal');sobel_y = edge(gray, 'sobel', 'vertical');imshowpair(sobel_x, sobel_y, 'montage');```上述代码首先加载并灰度化图像,然后使用Sobel算子分别计算水平和垂直方向上的梯度。
最后,使用imshowpair函数将水平和垂直边缘结果以并排的方式展示出来。
二、基于Canny算法的边缘检测Canny算法是一种广泛应用于边缘检测的算法,它通过多步骤的处理来准确地检测边缘。
在Matlab中,可以使用edge函数以及一些参数来实现Canny算法。
下面是一个使用Canny算法进行边缘检测的示例:```I = imread('image.jpg');gray = rgb2gray(I);canny = edge(gray, 'canny');imshow(canny);```上述代码中,首先加载并灰度化图像,然后使用edge函数采用Canny算法进行边缘检测。
matlab 边缘检测函数

matlab 边缘检测函数MATLAB是一款强大的计算机软件,用于科学计算、工程设计、图像处理等多个领域。
其中,边缘检测是图像处理中最常用的任务之一,它可以帮助我们从复杂的图像中提取出所需的信息。
MATLAB提供了多种边缘检测函数,本文将围绕这些函数进行阐述。
Step1:读取图像首先,我们需要读取一张图像,以便进行后续的处理。
MATLAB提供了imread()函数,用于读取图像。
例如,我们可以读取名为“lena.jpg”的图像,代码如下:```matlabI = imread('lena.jpg');```Step2:边缘检测在MATLAB中,可以使用多种函数进行边缘检测,其中包括Sobel、Prewitt、Canny等。
这些函数的使用方法类似,只是参数不同。
以下是几种常用的边缘检测函数:- sobel()函数:该函数基于Sobel算子进行边缘检测,返回的结果为边缘的强度值,代码如下:```matlabI_sobel = edge(I,'sobel');```- prewitt()函数:该函数基于Prewitt算子进行边缘检测,返回的结果为边缘的强度值,代码如下:```matlabI_prewitt = edge(I,'prewitt');```- canny()函数:该函数基于Canny算法进行边缘检测,返回的结果为二值图像,代码如下:```matlabI_canny = edge(I,'canny');```除了以上几种边缘检测函数以外,MATLAB还提供了其他的函数供用户选择,如Roberts、Log、zerocross等。
Step3:显示结果边缘检测的结果需要进行可视化,以便于用户判断是否得到了想要的效果。
为此,我们可以使用imshow()函数将原始图像和边缘检测结果进行显示,例如:```matlabsubplot(1,3,1);imshow(I);title('Original Image');subplot(1,3,2);imshow(I_sobel);title('Sobel Edge Detection'); subplot(1,3,3);imshow(I_canny);title('Canny Edge Detection'); ```以上代码将原始图像和Sobel、Canny两种边缘检测结果进行横向排列,以便于比较。
Matlab中的图像分割与边缘检测方法

Matlab中的图像分割与边缘检测方法引言图像处理是一门研究如何对数字图像进行处理、分析、改进和理解的学科。
图像分割与边缘检测在图像处理中占据着重要的地位。
图像分割是将图像划分为多个具有语义意义的区域或对象的过程,而边缘检测则是找到图像中不连续的区域边界。
Matlab作为一种强大的软件工具,提供了丰富的图像处理函数和工具箱,本文将探讨在Matlab中应用的图像分割与边缘检测方法。
一、图像分割方法1. 基于阈值的分割基于阈值的分割是一种简单但有效的方法。
该方法将图像像素的灰度值与预设的阈值进行比较,根据比较结果将像素分配到不同的区域。
在Matlab中,可以使用imbinarize和graythresh函数来实现基于阈值的分割。
2. 区域增长法区域增长法基于像素之间的相似性来进行分割。
该方法从种子像素开始,通过判断邻域像素与种子像素的相似度来不断扩展区域。
在Matlab中,可以使用imsegf和regiongrowing函数来实现区域增长法。
3. 聚类方法聚类方法将图像像素分为多个类别,每个类别代表一个区域。
该方法通常使用聚类算法,比如k-means算法或者模糊c-均值算法。
在Matlab中,可以使用kmeans和fcm函数来实现聚类方法。
4. 模型驱动法模型驱动法基于数学模型来描述图像中的区域。
该方法通过定义一个能够衡量图像中区域特征的能量函数,并通过优化算法来最小化能量函数,从而得到分割结果。
在Matlab中,可以使用activecontour和chanvese函数来实现模型驱动法。
二、边缘检测方法1. Sobel算子Sobel算子是一种经典的边缘检测算子。
其基本思想是通过计算像素与其周围像素之间的差异来检测边缘。
在Matlab中,可以使用imgradient和imgradientxy函数来实现Sobel算子。
2. Canny算子Canny算子是一种广泛使用的边缘检测算子。
它利用高斯平滑、梯度计算、非极大值抑制和双阈值法来检测边缘。
Matlab多种图像边缘检测方法

Matlab多种图像边缘检测方法1、用Prewitt算子检测图像的边缘I = imread('bacteria.BMP');BW1 = edge(I,'prewitt',0.04); % 0.04为梯度阈值figure(1);imshow(I);figure(2);imshow(BW1);2、用不同σ值的LoG算子检测图像的边缘I = imread('bacteria.BMP');BW1 = edge(I,'log',0.003); % σ=2imshow(BW1);title('σ=2')BW1 = edge(I,'log',0.003,3); % σ=3figure, imshow(BW1);title('σ=3')3、用Canny算子检测图像的边缘I = imread('bacteria.BMP');imshow(I);BW1 = edge(I,'canny',0.2);figure,imshow(BW1);4、图像的阈值分割I=imread('blood1.tif');imhist(I); % 观察灰度直方图,灰度140处有谷,确定阈值T=140I1=im2bw(I,140/255); % im2bw函数需要将灰度值转换到[0,1]范围内figure,imshow(I1);5、用水线阈值法分割图像afm = imread('afmsurf.tif');figure, imshow(afm);se = strel('disk', 15);Itop = imtophat(afm, se); % 高帽变换Ibot = imbothat(afm, se); % 低帽变换figure, imshow(Itop, []); % 高帽变换,体现原始图像的灰度峰值figure, imshow(Ibot, []); % 低帽变换,体现原始图像的灰度谷值Ienhance = imsubtract(imadd(Itop, afm), Ibot);% 高帽图像与低帽图像相减,增强图像figure, imshow(Ienhance);Iec = imcomplement(Ienhance); % 进一步增强图像Iemin = imextendedmin(Iec, 20); figure,imshow(Iemin) % 搜索Iec中的谷值Iimpose = imimposemin(Iec, Iemin);wat = watershed(Iimpose); % 分水岭分割rgb = label2rgb(wat); figure, imshow(rgb); % 用不同的颜色表示分割出的不同区域6、对矩阵进行四叉树分解I = [ 1 1 1 1 2 3 6 61 12 1 4 5 6 81 1 1 1 10 15 7 71 1 1 1 20 25 7 720 22 20 22 1 2 3 420 22 22 20 5 6 7 820 22 20 20 9 10 11 1222 22 20 20 13 14 15 16];S = qtdecomp(I,5);full(S)7、将图像分为文字和非文字的两个类别I=imread('4-11.jpg');I1=I(:,:,1);I2=I(:,:,2);I3=I(:,:,3);[y,x,z]=size(I);d1=zeros(y,x);d2=d1;myI=double(I);I0=zeros(y,x);for i=1:xfor j=1:y%欧式聚类d1(j,i)=sqrt((myI(j,i,1)-180)^2+(myI(j,i,2)-180)^2+(myI(j,i,3)-180)^2);d2(j,i)=sqrt((myI(j,i,1)-200)^2+(myI(j,i,2)-200)^2+(myI(j,i,3)-200)^2);if (d1(j,i)>=d2(j,i))I0(j,i)=1;endendendfigure(1);imshow(I);% 显示RGB空间的灰度直方图,确定两个聚类中心(180,180,180)和(200,200,200) figure(2);subplot(1,3,1);imhist(I1);subplot(1,3,2);imhist(I2);subplot(1,3,3);imhist(I3);figure(4);imshow(I0);8、形态学梯度检测二值图像的边缘I=imread('wrod213.bmp');imshow(I);I=~I; % 腐蚀运算对灰度值为1的进行figure, imshow(I);SE=strel('square',3); % 定义3×3腐蚀结构元素J=imerode(~I,SE);BW=(~I)-J; % 检测边缘figure,imshow(BW);9、形态学实例——从PCB图像中删除所有电流线,仅保留芯片对象I=imread('circbw.tif');imshow(I);SE=strel('rectangle',[40 30]); % 结构定义J=imopen(I,SE); % 开启运算figure,imshow(。
Matlab实现:图像边缘提取

Matlab实现:图像边缘提取1、边缘提取算法⽅法⼀:⼀阶微分算⼦Sobel算⼦Sobel算⼦检测⽅法对灰度渐变和噪声较多的图像处理效果较好,Sobel算⼦对边缘定位不是很准确,图像的边缘不⽌⼀个像素。
Roberts算⼦Roberts算⼦检测⽅法对具有陡峭的低噪声的图像处理效果较好,但是利⽤roberts算⼦提取边缘的结果是边缘⽐较粗,因此边缘的定位不是很准确。
Prewitt算⼦Prewitt算⼦检测⽅法对灰度渐变和噪声较多的图像处理效果较好。
但边缘较宽,⽽且间断点多。
Canny算⼦Canny算⼦是⽬前边缘检测最常⽤的算法,效果也是最理想的。
Canny⽅法不容易受噪声⼲扰,能够检测到真正的弱边缘。
优点在于,使⽤两种不同的阈值分别检测强边缘和弱边缘,并且当弱边缘和强边缘相连时,才将弱边缘包含在输出图像中。
⽅法⼆:⼆阶微分算⼦Laplacian算⼦Laplacian算⼦法对噪声⽐较敏感,所以很少⽤该算⼦检测边缘,⽽是⽤来判断边缘像素视为与图像的明区还是暗区。
2、实验结果分析⼀、边缘提取:Sobel算⼦检测⽅法对灰度渐变和噪声较多的图像处理效果较好,sobel算⼦对边缘定位不是很准确,图像的边缘不⽌⼀个像素;Roberts算⼦检测⽅法对具有陡峭的低噪声的图像处理效果较好,但是利⽤roberts算⼦提取边缘的结果是边缘⽐较粗,因此边缘的定位不是很准确;Prewitt算⼦检测⽅法对灰度渐变和噪声较多的图像处理效果较好。
但边缘较宽,⽽且间断点多;Laplacian算⼦法对噪声⽐较敏感,所以很少⽤该算⼦检测边缘,⽽是⽤来判断边缘像素视为与图像的明区还是暗区;Canny⽅法不容易受噪声⼲扰,能够检测到真正的弱边缘。
优点在于,使⽤两种不同的阈值分别检测强边缘和弱边缘,并且当弱边缘和强边缘相连时,才将弱边缘包含在输出图像中。
⼆、边缘复合增强Sobel、Robert、Prewitt算⼦的增强效果并不是很明显,尤其是Robert算⼦,因为它提取的边缘点过于稀疏和离散;Laplacian算⼦和canny算⼦的增强效果都⽐较理想,将边缘叠加上去后,整个⼿的轮廓和边缘都很清晰,直观上看,canny算⼦实现的效果⽐Laplacian算⼦好,最明显的地⽅就是⼿指尖的边缘。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
北京工业大学
研究生课程考试答题纸
课程类别:学位课选修课
研究生学号:
研究生姓名:
学生类别:博士硕士
工程硕士进修生
考试时间:年月日
一、实验目的:
熟悉边缘检测原理,并运用matlab软件实现图像的canny边缘检测,体会canny 边缘检测的优缺点。
二、实验内容:
编写matlab程序,实现对lena图像的边缘检测,输出程序运行结果。
三、实验原理或步骤:
首先回顾一下边缘检测的一般步骤:
边缘检测算法一般包含如下四个步骤:
1.滤波(去噪)。
2.增强(一般是通过计算梯度幅值)。
3.检测(在图像中有许多点的梯度幅值会比较大,而这些点并不都是边缘,所以应该用某种方法来确定边缘点,比如最简单的边缘检测判据:梯度幅值阈值)。
4.定位(有的应用场合要求确定边缘位置,可以在子像素水平上来估计,指出边缘的位置和方向)
Canny边缘检测的算法步骤:
1.用高斯滤波器平滑图像(不同尺度的Canny检测子由高斯的不同标准差来表示)用一阶偏导的有限差分来计算梯度的幅值和方向。
2.对高斯平滑后的图像进行sobel边缘检测。
这里需要求横的竖的还有联合的,所以一共三个需要sobel边缘检测图像。
3.对联合的sobel检测图像进行非极大值抑制(Non-Maxima Suppression, NMS)
4.用双阈值算法检测和连接边缘,并进行滞后阈值处理。
其中非极大值抑制细化了幅值图像中的屋脊带,只保留幅值局部变化最大的点。
双阈值算法:用两个阈值得到两个阈值图像,然后把高阈值的图像中的边缘连接成轮廓,连接时到达轮廓的端点时,在低阈值图像上找可以连接的边缘。
不断收集,直到所有的间隙连接起来为止。
四、运行结果和分析
每步运行效果:
Figure1原图:
Figure2 高斯模糊后:
Figure3 sobel边缘检测后:
Figure4 非极大抑制后:
Figure5 上阈值120,下阈值100检测结果:
Canny算子的方向性使得它的边缘检测和定位优于其他算子,具有更好的边缘强度估计,能产生梯度方向和强度两个信息。
五、算法程序
Main.m
clear all;
close all;
clc;
img=imread('lena.bmp');
imshow(img);
[m n]=size(img);
img=double(img);
%%canny边缘检测的前两步相对不复杂,所以我就直接调用系统函数了
%%高斯滤波
w=fspecial('gaussian',[5 5]);
img=imfilter(img,w,'replicate');
figure;
imshow(uint8(img))
%%sobel边缘检测
w=fspecial('sobel');
img_w=imfilter(img,w,'replicate'); %求横边缘
w=w';
img_h=imfilter(img,w,'replicate'); %求竖边缘
img=sqrt(img_w.^2+img_h.^2); %注意这里不是简单的求平均,而是平方和在开方。
figure;
imshow(uint8(img))
%%下面是非极大抑制
new_edge=zeros(m,n);
for i=2:m-1
for j=2:n-1
Mx=img_w(i,j);
My=img_h(i,j);
if My~=0
o=atan(Mx/My); %边缘的法线弧度
elseif My==0 && Mx>0
o=pi/2;
else
o=-pi/2;
end
%Mx处用My和img进行插值
adds=get_coords(o); %边缘像素法线一侧求得的两点坐标,插值需要
M1=My*img(i+adds(2),j+adds(1))+(Mx-My)*img(i+adds(4),j+adds(3)); %插值后得到的像素,用此像素和当前像素比较
adds=get_coords(o+pi); %边缘法线另一侧求得的两点坐标,插值需要
M2=My*img(i+adds(2),j+adds(1))+(Mx-My)*img(i+adds(4),j+adds(3)); %另一侧插值得到的像素,同样和当前像素比较
isbigger=(Mx*img(i,j)>M1)*(Mx*img(i,j)>=M2)+(Mx*img(i,j)<M1)*(Mx*img(i,j)<=M2); %如果当前点比两边点都大置1
if isbigger
new_edge(i,j)=img(i,j);
end
end
end
figure;
imshow(uint8(new_edge))
%%下面是滞后阈值处理
up=120; %上阈值
low=100; %下阈值
set(0,'RecursionLimit',10000); %设置最大递归深度
for i=1:m
for j=1:n
if new_edge(i,j)>up &&new_edge(i,j)~=255 %判断上阈值
new_edge(i,j)=255;
new_edge=connect(new_edge,i,j,low);
end
end
end
figure;
imshow(new_edge==255)
get_coords.m
function re=get_coords(angle) %angle是边缘法线角度,返回法线前后两点sigma=0.000000001;
x1=ceil(cos(angle+pi/8)*sqrt(2)-0.5-sigma);
y1=ceil(-sin(angle-pi/8)*sqrt(2)-0.5-sigma);
x2=ceil(cos(angle-pi/8)*sqrt(2)-0.5-sigma);
y2=ceil(-sin(angle-pi/8)*sqrt(2)-0.5-sigma);
re=[x1 y1 x2 y2];
end
connect.m
function nedge=connect(nedge,y,x,low) %种子定位后的连通分析neighbour=[-1 -1;-1 0;-1 1;0 -1;0 1;1 -1;1 0;1 1]; %八连通搜寻
[m n]=size(nedge);
for k=1:8
yy=y+neighbour(k,1);
xx=x+neighbour(k,2);
if yy>=1 &&yy<=m &&xx>=1 && xx<=n
if nedge(yy,xx)>=low && nedge(yy,xx)~=255 %判断下阈值
nedge(yy,xx)=255;
nedge=connect(nedge,yy,xx,low);
end
end
end
end。