Canny边缘检测算法

作为对比,先看一下Sobel的原理:

Sobel的原理:

索贝尔算子(Sobeloperator)是图像处理中的算子之一,主要用作边缘检测。在技术上,它是一离散性差分算子,用来运算图像亮度函数的梯度之近似值。在图像的任何一点使用此算子,将会产生对应的梯度矢量或是其法矢量.

该算子包含两组3x3的矩阵,分别为横向及纵向,将之与图像作平面卷积,即可分别得出横向及纵向的亮度差分近似值。如果以A代表原始图像,Gx及Gy分别代表经横向及纵向边缘检测的图像

Canny边缘检测算子的matlab实现

在以上例子中,如果以上的角度Θ等于零,即代表图像该处拥有纵向边缘,左方较右方暗。

在边沿检测中,常用的一种模板是Sobel 算子。Sobel 算子有两个,一个是检测水平边沿的 ;另一个是检测垂直平边沿的。与 和 相比,Sobel算子对于象素的位置的影响做了加权,因此效果更好。

Sobel算子另一种形式是各向同性Sobel(IsotropicSobel)算子,也有两个,一个是检测水平边沿的 ,另一个是检测垂直平边沿的 。各向同性Sobel算子和普通Sobel算子相比,它的位置加权系数更为准确,在检测不同方向的边沿时梯度的幅度一致。由于建筑物图像的特殊性,我们可以发现,处理该类型图像轮廓时,并不需要对梯度方向进行运算,所以程序并没有给出各向同性Sobel算子的处理方法。

由于Sobel算子是滤波算子的形式,用于提取边缘,可以利用快速卷积函数, 简单有效,因此应用广泛。美中不足的是,Sobel算子并没有将图像的主体与背景严格地区分开来,换言之就是Sobel算子没有基于图像灰度进行处理,由于Sobel算子没有严格地模拟人的视觉生理特征,所以提取的图像轮廓有时并不能令人满意。在观测一幅图像的时候,我们往往首先注意的是图像与背景不同的部分,正是这个部分将主体突出显示,基于该理论,我们给出了下面阈值化轮廓提取算法,该算法已在数学上证明当像素点满足正态分布时所求解是最优的

=================黑丽丽的分割线啊,开始Canny吧=======

Canny的原理:

(1)图象边缘检测必须满足两个条件:一能有效地抑制噪声;二必须尽量精确确定边缘的位置。

(2)根据对信噪比与定位乘积进行测度,得到最优化逼近算子。这就是Canny边缘检测算子。

(3)类似与Marr(LoG)边缘检测方法,也属于先平滑后求导数的方法

step1:用高斯滤波器平滑图象;

step2:用一阶偏导的有限差分来计算梯度的幅值和方向;

step3:对梯度幅值进行非极大值抑制

step4:用双阈值算法检测和连接边缘

<span style="color:#6600cc;"><strong>I=rgb2gray(imread('9.jpg'));
subplot(121);imshow(I);title('原图');
BW=edge(I,'canny');
subplot(122);imshow(BW);title('canny边缘处理');</strong></span>

<strong><span style="font-size:18px;"><span style="color:#6600cc;">clear all;
close all;
clc;

img=rgb2gray(imread('9.jpg'));
subplot(241);imshow(img);title('原图')
[m n]=size(img);
img=double(img);

%%canny边缘检测的前两步相对不复杂,所以我就直接调用系统函数了
%%高斯滤波
w=fspecial('gaussian',[5 5]);
img=imfilter(img,w,'replicate');
subplot(242);imshow(uint8(img));title('高斯滤波')

%%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);        %注意这里不是简单的求平均,而是平方和在开方。我曾经好长一段时间都搞错了
subplot(243);imshow(uint8(img));title('sobel边缘检测')

%%下面是非极大抑制
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
subplot(244);imshow(uint8(new_edge));title('非极大抑制')

%%下面是滞后阈值处理
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

subplot(245);imshow(new_edge==255);title('滞后阈值处理')

</span></span></strong><pre name="code" class="plain"><span style="color:#009900;">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</span>
<span style="color:#3333ff;">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</span>

时间: 2024-10-08 06:59:45

Canny边缘检测算法的相关文章

Canny边缘检测算法原理及其VC实现详解(一)

转自:http://blog.csdn.net/likezhaobin/article/details/6892176 图象的边缘是指图象局部区域亮度变化显著的部分,该区域的灰度剖面一般可以看作是一个阶跃,既从一个灰度值在很小的缓冲区域内急剧变化到另一个灰度相差较大的灰度值.图象的边缘部分集中了图象的大部分信息,图象边缘的确定与提取对于整个图象场景的识别与理解是非常重要的,同时也是图象分割所依赖的重要特征,边缘检测主要是图象的灰度变化的度量.检测和定位,自从1959提出边缘检测以来,经过五十多年

一些关于Canny边缘检测算法的改进

传统的Canny边缘检测算法是一种有效而又相对简单的算法,可以得到很好的结果(可以参考上一篇Canny边缘检测算法的实现).但是Canny算法本身也有一些缺陷,可以有改进的地方. 1. Canny边缘检测第一步用高斯模糊来去掉噪声,但是同时也会平滑边缘,使得边缘信息减弱,有可能使得在后面的步骤中漏掉一些需要的边缘,特别是弱边缘和孤立的边缘,可能在双阀值和联通计算中被剔除.很自然地可以预见,如果加大高斯模糊的半径,对噪声的平滑力度加大,但也会使得最后得到的边缘图中的边缘明显减少.这里依然用Lena

Canny边缘检测算法原理及其VC实现详解(二)

转自:http://blog.csdn.net/likezhaobin/article/details/6892629 3.  Canny算法的实现流程 由于本文主要目的在于学习和实现算法,而对于图像读取.视频获取等内容不进行阐述.因此选用OpenCV算法库作为其他功能的实现途径(关于OpenCV的使用,作者将另文表述).首先展现本文将要处理的彩色图片. 图2 待处理的图像 3.1 图像读取和灰度化 编程时采用上文所描述的第二种方法来实现图像的灰度化.其中ptr数组中保存的灰度化后的图像数据.具

Canny边缘检测算法原理及C语言实现详解(原创码字)

Canny算子是John Canny在1986年提出的,那年老大爷才28岁,该文章发表在PAMI顶级期刊上的(1986. A computational approach to edge detection. IEEE Transactions on Pattern Analysis and Machine Intelligence, vol. 8, 1986, pp. 679-698).老大爷目前在加州伯克利做machine learning,80-90年代视觉都是图像处理,现在做视觉都是机器

哈夫变换和Canny边缘检测算法

图象的边缘是指图象局部区域亮度变化显著的部分,该区域的灰度剖面一般可以看作是一个阶跃,既从一个灰度值在很小的缓冲区域内急剧变化到另一个灰度相差较大的灰度值.图象的边缘部分集中了图象的大部分信息,图象边缘的确定与提取对于整个图象场景的识别与理解是非常重要的,同时也是图象分割所依赖的重要特征,边缘检测主要是图象的灰度变化的度量.检测和定位,自从1959提出边缘检测以来,经过五十多年的发展,已有许多中不同的边缘检测方法.在我们常用的几种用于边缘检测的算子中Laplace算子常常会产生双边界:而其他一些

【数字图像分析】基于Python实现 Canny Edge Detection(Canny 边缘检测算法)

import numpy as np import cv2 import argparse from Computer_Vision.Canny_Edge_Detection.sobel import sobel_edge_detection from Computer_Vision.Canny_Edge_Detection.gaussian_smoothing import gaussian_blur import matplotlib.pyplot as plt def non_max_su

图像处理之Canny边缘检测

http://blog.csdn.net/jia20003/article/details/41173767 图像处理之Canny 边缘检测 一:历史 Canny边缘检测算法是1986年有John F. Canny开发出来一种基于图像梯度计算的边缘 检测算法,同时Canny本人对计算图像边缘提取学科的发展也是做出了很多的贡献.尽 管至今已经许多年过去,但是该算法仍然是图像边缘检测方法经典算法之一. 二:Canny边缘检测算法 经典的Canny边缘检测算法通常都是从高斯模糊开始,到基于双阈值实现边

Canny边缘检测原理及C#程序实现

http://blog.csdn.net/yjz_uestc/article/details/6664937 Canny边缘检测是被公认的检测效果最好的边缘检测方法,是由John F. Canny于1986年提出,算法目标是找出一个最优的边缘检测的方法,所谓最优即:1.好的检测:算法能够尽可能的标识出图像的边缘:2.好的定位:标识出的边缘要尽可能的与实际边缘相接近:3.最小响应:图像中的边缘只能标识一次,并且不能把噪声标识成边缘.同时我们也要满足3个准则:信噪比准则.定位精度准则.单边缘响应准则

18.Canny边缘检测

Canny边缘检测算法以Canny的名字命名,其中Canny的目标是找到一个最优的边缘检测算法,其有三种衡量标准: 低错误率:标识出尽可能多的实际边缘,同时尽可能的减少噪声产生的误报 高定位性:标识出的边缘要与图像中的图像中的实际边缘尽可能接近 最小响应:图像中的边缘只能标识一次,并且可能存在的图像噪声不应标识为边缘 //Canny int g_nCannySize; int g_nCannyThresHoldValue; int g_nSobelValue; Mat g_srcImage,g_