crazybird

OpenCV中的边缘检测

0
阅读(2331)

边缘检测一般的步骤:

(1)滤波

边缘检测的算法主要是基于图像强度的一阶和二阶导数,但导数通常对噪声很敏感,因此必须采用滤波器来改善与噪声相关的边缘检测器的性能。

(2)增强

增强边缘的基础是确定图像各点邻域强度的变化值。增强算法可以将图像灰度点邻域强度值有显著变化的点凸显出来。

(3)检测

经过增强的图像,邻域中往往有很多点的梯度值比较大,而在特定的应用中,这些点并不是要找的边缘点,所以要采用某种方法对这些点进行取舍。实际工程中,经常通过阈值化的方法来检测。


下面介绍几种边缘检测的算子:

1、Canny边缘检测

(1)canny算子

        Canny边缘检测算子是一个多级边缘检测算法,被很多人推崇为当今最优的边缘检测算法。一个最优边缘检测的三个主要评价标准:

      <1>低错误率:标识出尽可能多的实际边缘,同时尽可能地减少噪声产生的误报。

      <2>高定位性:标识出的边缘要与图像中的实际边缘尽可能接近。

      <3>最小响应:图像中的边缘只能标识一次,并且可能存在的图像噪声不应标识为边缘。

(2)canny边缘检测的步骤

        <1>消除噪声

              通常使用高斯平滑滤波器卷积降噪。

        <2>计算梯度幅值和方向

              梯度方向一般取0°、45°、90°、135°这四个可能的角度之一。

        <3>非极大值抑制

              排除非边缘像素,仅仅保留了一些细线条(候选边缘)。

        <4>滞后阈值

              滞后阈值有高阈值和低阈值两个阈值:若某一像素位置的幅值超过高阈值,该像素被保留为边缘像素;若某一像素位置的幅值小于低阈值,该像素被排除;若某一像素位置的幅值在两个阈值之间,该像素仅仅在连接到一个高于高阈值的像素时被保留。

(3)Canny边缘检测:Canny()函数

void Canny(InputArray image,OutputArray edges,double threshold1,double threshold2,int apertureSize=3,bool L2gradient=false)

<1>单通道8位图像输入。

<2>输出的边缘图。

<3>第一个滞后性阈值。

<4>第二个滞后性阈值。

<5>表示应用Sobel算子的孔径大小,默认值为3。

<6>计算图像梯度幅值的标识,默认值false。

这个函数阈值1和阈值2两者中较小的值用于边缘连续,而较大的值用来控制边缘的初始段,推荐的高低阈值在2:1到3:1之间。

(4)Canny边缘检测OpenCV实现

#include<opencv2\opencv.hpp>
#include<iostream>
using namespace cv;
using namespace std;
int main()
{
    //  图片读取与显示
    Mat srcImage = imread("flower.jpg");        //  载入图片
    if(!srcImage.data)
    {
        cout << "图片加载失败!!!" << endl;
        system("pause");
        return 1;
    }
    imshow("【原始图】canny边缘检测",srcImage);  //  显示原始图
    //  将原图转换成灰度图
    Mat grayImage;
    cvtColor(srcImage,grayImage,COLOR_BGR2GRAY);
    //  对灰度图进行滤波
    Mat blurImage;
    blur(grayImage,blurImage,Size(3,3));
    //  Canny边缘检测
    Mat dstImage;
    Canny(blurImage,dstImage,3,9,3);
    //  效果图显示
    imshow("【效果图】Canny边缘检测",dstImage);
    waitKey(0);
    return 0;
}

原始图.png

效果图.png