OpenCV+python:Canny边缘检测算法

本文介绍了Canny边缘检测算法,包括边缘处理原理、Canny算法的三大准则以及详细的处理流程:灰度转换、高斯滤波、梯度计算、非极大值抑制、双阈值检测和抑制孤立低阈值点。通过OpenCV库实现Canny算法,旨在提高边缘检测的精度和抗噪声能力。
摘要由CSDN通过智能技术生成

1,边缘处理
图像边缘信息主要集中在高频段,通常说图像锐化或检测边缘,实质就是高频滤波。我们知道微分运算是求信号的变化率,具有加强高频分量的作用。
在空域运算中来说,对图像的锐化就是计算微分。由于数字图像的离散信号,微分运算就变成计算差分或梯度。
图像处理中有多种边缘检测(梯度)算子,常用的包括普通一阶差分,Robert算子(交叉差分),Sobel算子等等,是基于寻找梯度强度。拉普拉斯算子(二阶差分)是基于过零点检测。通过计算梯度,设置阀值,得到边缘图像。
2,Canny边缘检测算法简介
Canny边缘检测算子是一种多级检测算法。1986年由John F. Canny提出,同时提出了边缘检测的三大准则:
(1) 低错误率的边缘检测:检测算法应该精确地找到图像中的尽可能多的边缘,尽可能的减少漏检和误检。
(2) 最优定位:检测的边缘点应该精确地定位于边缘的中心。
(3)图像中的任意边缘应该只被标记一次,同时图像噪声不应产生伪边缘。
为了满足这些要求,Canny使用了变分法。Canny检测器中的最优函数使用四个指数项的和来描述,它可以由高斯函数的一阶导数来近似。
3,Canny边缘检测算法的处理流程

(1)灰度转换:

该部分是按照Canny算法通常处理的图像为灰度图,如果获取的彩色图像,那首先就得进行灰度化。以RGB格式的彩图为例,通常灰度化采用的公式是:
Gray=0.299R+0.587G+0.114B
在OpenCV中也提供相关的API(cvtColor)
源代码:

///第一步:灰度化 
 2     IplImage * ColorImage=cvLoadImage("c:\\photo.bmp",1);
 3     if (ColorImage==NULL)
 4     {
 5         printf("image read error");
 6         return 0;
 7     }
 8     cvNamedWindow("Sourceimg",0);  
 9     cvShowImage("Sourceimg",ColorImage);               // 
10     IplImage * OpenCvGrayImage;
11     OpenCvGrayImage=cvCreateImage(cvGetSize(ColorImage),ColorImage->depth,1);
12     float data1,data2,data3;
13     for (int i=0;i<ColorImage->height;i++)
14     {
15         for (int j=0;j<ColorImage->width;j++)
16         {
17             data1=(uchar)(ColorImage->imageData[i*ColorImage->widthStep+j*3+0]);
18             data2=(uchar)(ColorImage->imageData[i*ColorImage->widthStep+j*3+1]);
19             data3=(uchar)(ColorImage->imageData[i*ColorImage->widthStep+j*3+2]);
20             OpenCvGrayImage->imageData[i*OpenCvGrayImage->widthStep+j]=(uchar)(0.07*data1 + 0.71*data2 + 0.21*data3);
21         }
22     }
23     cvNamedWindow("GrayImage",0);  
24     cvShowImage("GrayImage",OpenCvGrayImage);               //显示灰度图  
25     cvWaitKey(0);  
26     cvDestroyWindow("GrayImage"); 

(2) 使用高斯滤波器,以平滑图像,滤除噪声(高斯模糊):

了尽可能减少噪声对边缘检测结果的影响,所以必须滤除噪声以防止由噪声引起的错误检测。为了平滑图像,使用高斯滤波器与图像进行卷积,该步骤将平滑图像,以减少边缘检测器上明显的噪声影响。大小为(2k+1)x(2k+1)的高斯滤波器核的生成方程式由下式给出:
在这里插入图片描述下面是一个sigma = 1.4,尺寸为3x3的高斯卷积核的例子(需要注意归一化):

在这里插入图片描述
若图像中一个3x3的窗口为A,要滤波的像素点为e,则经过高斯滤波之后,像素点e的亮度值为:
在这里插入图片描述其中*为卷积符号,sum表示矩阵中所有元素相加求和。重要的是需要理解,高斯卷积核大小的选择将影响Canny检测器的性能。尺寸越大,检测器对噪声的敏感度越低,但是边缘检测的定位误差也将略有增加。一般5x5是一个比较不错的trade off。
源代码:

///第二步:高斯滤波 
///
    double nSigma=0.2;
    int nWindowSize=1+2*ceil(3*nSigma);//通过sigma得到窗口大小
    int nCenter=nWindowSize/2;
    int nWidth=OpenCvGrayImage->width;
    int nHeight=OpenCvGrayImage->height;
    IplImage * pCanny;
    pCanny=cvCreateImage(cvGetSize(ColorImage),ColorImage->depth,1);
    //生成二维滤波核
    double *pKernel_2=new double[nWindowSize*nWindowSize];
    double d_sum=0.0;
    for(int i=0;i<nWindowSize;i++)
    {
        for (int j=0;j<nWindowSize;j++)
        {
            double n_Disx=i-nCenter;//水平方向距离中心像素距离
            double n_Disy=j-nCenter;
            pKernel_2[j*nWindowSize+i]=exp(-0.5*(n_Disx*n_Disx+n_Disy*n_Disy)/(nSigma*nSigma))/(2.0*3.1415926)*nSigma*nSigma; 
            d_sum=d_sum+pKernel_2[j*nWindowSize+i];
        }
    }
    for(int i=0;i<nWindowSize;i++)//归一化处理
    {
        for (int j=0;j<nWindowSize;j++)
        {
          pKernel_2[j*nWindo
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值