当前位置:   article > 正文

基于MATLAB的边缘检测算法实现

i(i + adds(2),j + adds(1))

MATLAB边缘检测

一、目的:

熟悉边缘检测原理,并运用matlab软件实现图像的canny边缘检测,体会canny边缘检测的优缺点。

二、内容:

编写matlab程序,实现对lena图像的边缘检测,输出程序运行结果。

三、原理或步骤:

首先回顾一下边缘检测的一般步骤:

边缘检测算法一般包含如下四个步骤:

1.滤波(去噪)。

2.增强(一般是通过计算梯度幅值)。

3.检测(在图像中有许多点的梯度幅值会比较大,而这些点并不都是边缘,所以应该用某种方法来确定边缘点,比如最简单的边缘检测判据:梯度幅值阈值)。

4.定位(有的应用场合要求确定边缘位置,可以在子像素水平上来估计,指出边缘的位置和方向)

Canny边缘检测的算法步骤:

  1.用高斯滤波器平滑图像(不同尺度的Canny检测子由高斯的不同标准差来表示)用一阶偏导的有限差分来计算梯度的幅值和方向。

  2.对高斯平滑后的图像进行sobel边缘检测。这里需要求横的竖的还有联合的,所以一共三个需要sobel边缘检测图像。

  3.对联合的sobel检测图像进行非极大值抑制(Non-Maxima Suppression, NMS)

  4.用双阈值算法检测和连接边缘,并进行滞后阈值处理。

  其中非极大值抑制细化了幅值图像中的屋脊带,只保留幅值局部变化最大的点。

  双阈值算法:用两个阈值得到两个阈值图像,然后把高阈值的图像中的边缘连接成轮廓,连接时到达轮廓的端点时,在低阈值图像上找可以连接的边缘。不断收集,直到所有的间隙连接起来为止。

四、运行结果和分析

每步运行效果:

Figure1原图:

v2-11dd2b4b88beacca5b73f11bc77205c7_b.jpg

Figure2 高斯模糊后:

v2-743a4f1b09404cb9634dffdb11100b87_b.jpg

Figure3 sobel边缘检测后:

v2-9c42798a4279821afc1117c035df0d80_b.jpg


Figure4 非极大抑制后:


v2-ca6b9d02427d0e08700e69165d53954f_b.jpg


Figure5 上阈值120,下阈值100检测结果:


v2-6455416468832f42cf5175b6eea79a2e_b.jpg

Canny算子的方向性使得它的边缘检测和定位优于其他算子,具有更好的边缘强度估计,能产生梯度方向和强度两个信息。

五、算法程序

Main.m

  1. clear all;
  2. close all;
  3. clc;
  4. img=imread('lena.bmp');
  5. imshow(img);
  6. [m n]=size(img);
  7. img=double(img);
  8. %%canny边缘检测的前两步相对不复杂,所以我就直接调用系统函数了
  9. %%高斯滤波
  10. w=fspecial('gaussian',[5 5]);
  11. img=imfilter(img,w,'replicate');
  12. figure;
  13. imshow(uint8(img))
  14. %%sobel边缘检测
  15. w=fspecial('sobel');
  16. img_w=imfilter(img,w,'replicate'); %求横边缘
  17. w=w';
  18. img_h=imfilter(img,w,'replicate'); %求竖边缘
  19. img=sqrt(img_w.^2+img_h.^2); %注意这里不是简单的求平均,而是平方和在开方。
  20. figure;
  21. imshow(uint8(img))
  22. %%下面是非极大抑制
  23. new_edge=zeros(m,n);
  24. for i=2:m-1
  25. for j=2:n-1
  26. Mx=img_w(i,j);
  27. My=img_h(i,j);
  28. if My~=0
  29. o=atan(Mx/My); %边缘的法线弧度
  30. elseif My==0 && Mx>0
  31. o=pi/2;
  32. else
  33. o=-pi/2;
  34. end
  35. %Mx处用My和img进行插值
  36. adds=get_coords(o); %边缘像素法线一侧求得的两点坐标,插值需要
  37. M1=My*img(i+adds(2),j+adds(1))+(Mx-My)*img(i+adds(4),j+adds(3)); %插值后得到的像素,用此像素和当前像素比较
  38. adds=get_coords(o+pi); %边缘法线另一侧求得的两点坐标,插值需要
  39. M2=My*img(i+adds(2),j+adds(1))+(Mx-My)*img(i+adds(4),j+adds(3)); %另一侧插值得到的像素,同样和当前像素比较
  40. isbigger=(Mx*img(i,j)>M1)*(Mx*img(i,j)>=M2)+(Mx*img(i,j)<M1)*(Mx*img(i,j)<=M2); %如果当前点比两边点都大置1
  41. if isbigger
  42. new_edge(i,j)=img(i,j);
  43. end
  44. end
  45. end
  46. figure;
  47. imshow(uint8(new_edge))
  48. %%下面是滞后阈值处理
  49. up=120; %上阈值
  50. low=100; %下阈值
  51. set(0,'RecursionLimit',10000); %设置最大递归深度
  52. for i=1:m
  53. for j=1:n
  54. if new_edge(i,j)>up &&new_edge(i,j)~=255 %判断上阈值
  55. new_edge(i,j)=255;
  56. new_edge=connect(new_edge,i,j,low);
  57. end
  58. end
  59. end
  60. figure;
  61. imshow(new_edge==255)

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家自动化/article/detail/846171
推荐阅读
相关标签
  

闽ICP备14008679号