Opencv(C++)笔记–Canny边缘检测算法

目录

1--算法原理

2--Opencv API

3--代码实例


1--算法原理

具体原理讲解可参考博客1 和 博客2,算法主要步骤如下:

        ① 使用高斯模糊(高斯滤波)去除噪声;

        ② 进行灰度转换,转换为灰度图;

        ③ 计算梯度,首先使用 Sobel 算子 Gx 和 Gy 分别计算 Grad_x 和 Grad_y,接着计算梯度Grad_xy 及 梯度方向 θ;

        ④ 进行非最大信号抑制,保留一定范围内(例如3×3邻域)像素值最大的像素点,其余像素点的像素值置0;

        ⑤ 设置高低阈值,输出二值图像;抑制(去除)梯度值小于低阈值的像素点;梯度值大于高阈值的像素点保留为强边缘点;梯度值介于低阈值和高阈值之间的像素点,保留为弱边缘,需要进行进一步的处理;

        ⑥ 弱边缘抑制,对第 ⑤ 步的弱边缘点进行进一步的处理,如果弱边缘点在规定邻域内(例如3×3邻域)存在强边缘点邻居,则正式保留为真实边缘点,否则进行抑制(剔除);

需要强调的是非最大信号(非极大值)抑制的原理:

        非极大抑制(Non-Maximum Suppression,NMS)指的是遍历图像中的所有像素点,判断当前像素点是否是周围像素点中的最大值(具有相同方向梯度);如果当前像素点的梯度最大,则保留像素点,否则就抑制(剔除,像素值置0),这一步的目的往往是将模糊的边界变得清晰;

2--Opencv API

需要说明的是,高阈值(API中的 threshold2)通常设置为低阈值(API中的 threshold1)的2~3倍;

3--代码实例

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

cv::Mat gray_src;
int thresh = 50; // 初始阈值
int max_value = 255; // 最大阈值

void Canny_Demo(int, void*){
    cv::Mat edge;
    cv::blur(gray_src, gray_src, cv::Size(3, 3), cv::Point(-1, -1), cv::BORDER_DEFAULT); // 先进行简单滤波去除噪声
    cv::Canny(gray_src, edge, thresh, thresh*2, 3, false); // 调用 API 实现边缘检测
    cv::imshow("output", edge);
}

int main(int argc, char** argv){
    cv::Mat src;
    src = cv::imread("C:/Users/Liujinfu/Desktop/opencv_bilibili/test1.jpg");
    if (src.empty()){
        printf("could not load image..n");
        return -1;
    }
    cv::imshow("input", src);
    
    cv::cvtColor(src, gray_src, cv::COLOR_BGR2GRAY); // 灰度化

    cv::namedWindow("output");
    cv::createTrackbar("low_Thresh: ", "output", &thresh, max_value, Canny_Demo); 
    Canny_Demo(0, 0);
    
    cv::waitKey(0);
    return 0;
}

 

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
THE END
分享
二维码
< <上一篇
下一篇>>