OpenCV-C++ Canny算法介绍

注意:文章原理还很不完善,仅供本人学习使用;

Canny理论原理

Canny边缘检测器是由John F. Canny在1986年提出,Canny被称为最优检测器,其目标满足以下三个主要标准:

  • 低错误率:对已有的边界能够有很好的检测;
  • 良好的定位:即检测到的边缘像素和实际边缘像素之间的距离必须最小化;
  • 最小响应:即每边只有一个响应;

Canny算法主要包含以下五个步骤:

过滤噪声

使用高斯滤波器去噪,高斯核如下图所示:

计算图像梯度

首先,在图像利用Sobel算子计算x, y两个方向的梯度:

其次,计算梯度的强度和方向:

其中,梯度的方向被四舍五入到[0, 45, 90, 135]这几个角度;

非最大值抑制算子(NMS)

抑制那些梯度不够大的像素点,只保留最大的像素点,从而达到瘦边的目的;

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

经过NMS算法后,设置两个阈值\(T_1, T_2\),通常\(T_1\)\(T_2\)\(1/2\)或者\(1/3\);

  • 梯度值大于\(T_2\)的像素点称为强边缘,保留作为图像边缘;
  • 梯度值小于\(T_1\)的像素点不是边缘,舍弃;
  • 针对梯度值大于\(T_1\),小于\(T_2\)的像素点,称为弱边缘;

针对弱边缘,需要进一步判定其是否的真正的边缘像素点;判别的方法就是,当弱边缘像素点周围8个领域内存在强边缘像素时,则该弱边缘变成强边缘点,否则不是边缘点;

OpenCV Canny使用

CannyAPI的介绍:

void Canny( InputArray image, OutputArray edges,
           double threshold1, double threshold2,
           int apertureSize = 3, bool L2gradient = false );
  • src输入图像,必须是8-bits;
  • edges输出的图像边缘
  • threshold1, threshold2对应于上述的\(T_1, T_2\);
  • apertureSizeSobel算子的大小;
  • L2gradient表示计算梯度值时是否使用\(L2\)(就是默认的计算方式);

如果设置L2gradient=True,则梯度值的计算方式为:

\[G = |G_x| + |G_y| \]

使用方式:

#include <iostream>
#include <opencv2/opencv.hpp>

using namespace std;
using namespace cv;

/**
 * 边缘处理
*/

Mat src, srcBlur, srcGray;
const int MAX_THRESHOLD = 255;
int t1_value = 50;
char output_wind[] = "output";

void Canny_Demo(int, void*);

int main(){
    // 读取图像
    src = imread("/home/chen/dataset/lena.jpg");
    if (src.empty()){
        cout << "could not load image." << endl;
        return -1;
    }
    namedWindow("src", WINDOW_AUTOSIZE);
    imshow("src", src); 

    GaussianBlur(src, srcBlur, Size(3, 3), 0, 0);
    cvtColor(srcBlur, srcGray, COLOR_BGR2GRAY);

    namedWindow(output_wind, WINDOW_AUTOSIZE);
    createTrackbar("Threshold: ", output_wind, &t1_value, MAX_THRESHOLD, Canny_Demo);
    Canny_Demo(0, 0);

    waitKey(0); 
    return 0;
}

void Canny_Demo(int, void*){
    Mat edgeOutput;
    Canny(srcGray, edgeOutput, t1_value, t1_value*2, 3, false);
    imshow(output_wind, edgeOutput);
}

Reference:

posted @ 2021-04-22 16:58  chenzhen0530  阅读(2638)  评论(1编辑  收藏  举报