[OpenCV] 数字图像处理 C++ 学习——13Canny边缘检测 附完整代码

本文主要是介绍[OpenCV] 数字图像处理 C++ 学习——13Canny边缘检测 附完整代码,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

  • 前言
  • 1.理论基础
    • (1)高斯模糊平滑图像(GaussianBlur)
    • (2)计算图像梯度(Sobel/Scharr)
    • (3)非极大值抑制 (Non-maximum Suppression)
    • (4)双阈值检测 (Double Threshold)
    • (5)边缘跟踪(通过滞后处理)
  • 2.代码实现
  • 3.完整代码

前言

Canny 边缘检测(高斯滤波、梯度计算、非极大值抑制、双阈值检测、边缘跟踪)是经典的边缘检测算法之一,本文将详细介绍 Canny 边缘检测的理论基础、实现方法,并提供完整的 C++ 代码示例。

1.理论基础

Canny 边缘检测算法是由 John F. Canny 于 1986 年提出的。Canny 算法提取图像的边缘时表现出了很高的性能。Canny 算法的主要步骤如下:

①使用高斯滤波器,平滑图像,滤除噪声。
②计算图像中每个像素点的梯度。
③非极大值(Non-Maximum Suppression)抑制,去除非边缘的像素点,减少边缘检测中的噪声响应。
④双阈值(Double-Threshold)检测来确定真实的和潜在的边缘。
⑤通过连接强边缘像素点和与之相邻的弱边缘像素点,得到完整的边缘图像。

(1)高斯模糊平滑图像(GaussianBlur)

高斯模糊是通过模糊图像来减少噪声和细节,防止这些无关信息在后续的边缘检测中被误检为边缘。

[OpenCV] 数字图像处理 C++ 学习——07图像模糊 附完整代码(小白入门篇)有讲到,有需要可以去看一下

(2)计算图像梯度(Sobel/Scharr)

使用 Sobel 算子计算图像在水平方向(x 方向)和垂直方向(y 方向)的梯度。梯度的大小和方向可以通过以下公式计算:

在这里插入图片描述

(3)非极大值抑制 (Non-maximum Suppression)

在图像梯度幅值图上,抑制非边缘的像素,即抑制不是局部最大值的像素。这一步骤是为了减少不必要的边缘响应,只保留真正的边缘像素。

在这里插入图片描述

图中将梯度方向划分为了 4 个主要区域,每个区域对应一定的角度范围。这些区域分别是:

  • 黄色区域 (0° 和 180°):梯度方向接近水平方向,具体来说,角度在(0° ,22.5° ) 或(157.5° ,180°) 之间。这个方向对应着水平边缘。
  • 绿色区域 (45°):梯度方向介于水平和垂直之间,对应的角度范围是(22.5° , 67.5°) 。这个方向通常表示斜向的边缘。
  • 蓝色区域 (90°):梯度方向接近垂直方向,角度在(67.5° ,112.5°) 之间。这个方向对应着垂直边缘。
  • 红色区域 (135°):梯度方向介于垂直和水平之间,对应的角度范围是 (112.5° , 157.5°)。这个方向也是斜向的,方向与绿色区域的方向相反。

非极大值抑制的处理步骤

  • 选择方向:根据每个像素点的梯度方向,将该方向归类到上述的四个主要方向之一。然后沿着这个主要方向进行非极大值抑制。
  • 比较相邻像素:对于每个像素点,沿着该点的梯度方向,比较其梯度幅值是否是局部最大值。如果当前像素的梯度幅值大于沿着梯度方向的前一个和后一个像素的梯度幅值,则保留该点为边缘点;否则,将该点的梯度幅值设为零,表示非边缘。

例如:

  • 如果梯度方向是接近水平的(黄色区域),则比较当前像素与左侧和右侧像素的梯度幅值。
  • 如果梯度方向是接近垂直的(蓝色区域),则比较当前像素与上方和下方像素的梯度幅值。

通过非极大值抑制,梯度幅值图像中的噪声点和不明确的边缘点会被抑制,只保留那些可能真实存在的边缘。

(4)双阈值检测 (Double Threshold)

应用两个阈值对检测到的边缘进行分类:强边缘(强于高阈值)、弱边缘(介于高阈值和低阈值之间)和非边缘(低于低阈值)。强边缘直接被保留,弱边缘如果连接到强边缘则保留,否则舍弃。

在这里插入图片描述

  • A 点的梯度值值大于 maxVal,因此 A 是强边缘。
  • B 和 C 点的梯度值介于 maxVal 和 minVal 之间,因此 B、C 是虚边缘。
    • B 点的梯度值介于 maxVal 和 minVal 之间,是虚边缘,但该点与强边缘不相连,故将其抛弃。
    • C 点的梯度值介于 maxVal 和 minVal 之间,是虚边缘,但该点与强边缘 A 相连,故将其保留。
  • D 点的梯度值小于 minVal,因此 D 被抑制(抛弃)。

(5)边缘跟踪(通过滞后处理)

通过连接强边缘像素点和与之相邻的弱边缘像素点,得到完整的边缘图像。

2.代码实现

cv::Canny() 使用了上述的步骤,自动进行图像平滑、梯度计算、非极大值抑制、双阈值检测和边缘跟踪。

	cv::Mat edges;double lowThreshold = 50;double highThreshold = 150;cv::Canny(blurredImage, edges, lowThreshold, highThreshold);cv::imshow("Canny Edges", edges);

lowThreshold = 50和highThreshold = 150结果

在这里插入图片描述

lowThreshold = 50和highThreshold = 100结果
在这里插入图片描述

具体的结果需要根据实际图像的特性来调节双阈值,以达到最佳边缘检测效果。

3.完整代码

#include<opencv2/opencv.hpp>
#include<highgui.hpp>
#include<iostream>
#include<math.h>using namespace cv;
using namespace std;void Canny_edge_detection()
{cv::Mat image;image = imread("lena.png", IMREAD_GRAYSCALE);if (image.empty()) {printf("could not find the image...\n");return;}namedWindow("input image", cv::WINDOW_AUTOSIZE);cv::imshow("input image", image);// 使用高斯滤波器平滑图像cv::Mat blurredImage;GaussianBlur(image, blurredImage, Size(5, 5), 1.5);// 执行 Canny 边缘检测cv::Mat edges;double lowThreshold = 50;double highThreshold = 100;cv::Canny(blurredImage, edges, lowThreshold, highThreshold);cv::imshow("Canny Edges", edges);waitKey(0);}
int main() 
{Canny_edge_detection();return 0;
}

这篇关于[OpenCV] 数字图像处理 C++ 学习——13Canny边缘检测 附完整代码的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1135074

相关文章

基于 HTML5 Canvas 实现图片旋转与下载功能(完整代码展示)

《基于HTML5Canvas实现图片旋转与下载功能(完整代码展示)》本文将深入剖析一段基于HTML5Canvas的代码,该代码实现了图片的旋转(90度和180度)以及旋转后图片的下载... 目录一、引言二、html 结构分析三、css 样式分析四、JavaScript 功能实现一、引言在 Web 开发中,

Python如何去除图片干扰代码示例

《Python如何去除图片干扰代码示例》图片降噪是一个广泛应用于图像处理的技术,可以提高图像质量和相关应用的效果,:本文主要介绍Python如何去除图片干扰的相关资料,文中通过代码介绍的非常详细,... 目录一、噪声去除1. 高斯噪声(像素值正态分布扰动)2. 椒盐噪声(随机黑白像素点)3. 复杂噪声(如伪

Java Spring ApplicationEvent 代码示例解析

《JavaSpringApplicationEvent代码示例解析》本文解析了Spring事件机制,涵盖核心概念(发布-订阅/观察者模式)、代码实现(事件定义、发布、监听)及高级应用(异步处理、... 目录一、Spring 事件机制核心概念1. 事件驱动架构模型2. 核心组件二、代码示例解析1. 事件定义

使用Python和OpenCV库实现实时颜色识别系统

《使用Python和OpenCV库实现实时颜色识别系统》:本文主要介绍使用Python和OpenCV库实现的实时颜色识别系统,这个系统能够通过摄像头捕捉视频流,并在视频中指定区域内识别主要颜色(红... 目录一、引言二、系统概述三、代码解析1. 导入库2. 颜色识别函数3. 主程序循环四、HSV色彩空间详解

Windows下C++使用SQLitede的操作过程

《Windows下C++使用SQLitede的操作过程》本文介绍了Windows下C++使用SQLite的安装配置、CppSQLite库封装优势、核心功能(如数据库连接、事务管理)、跨平台支持及性能优... 目录Windows下C++使用SQLite1、安装2、代码示例CppSQLite:C++轻松操作SQ

C++中RAII资源获取即初始化

《C++中RAII资源获取即初始化》RAII通过构造/析构自动管理资源生命周期,确保安全释放,本文就来介绍一下C++中的RAII技术及其应用,具有一定的参考价值,感兴趣的可以了解一下... 目录一、核心原理与机制二、标准库中的RAII实现三、自定义RAII类设计原则四、常见应用场景1. 内存管理2. 文件操

C++中零拷贝的多种实现方式

《C++中零拷贝的多种实现方式》本文主要介绍了C++中零拷贝的实现示例,旨在在减少数据在内存中的不必要复制,从而提高程序性能、降低内存使用并减少CPU消耗,零拷贝技术通过多种方式实现,下面就来了解一下... 目录一、C++中零拷贝技术的核心概念二、std::string_view 简介三、std::stri

C++高效内存池实现减少动态分配开销的解决方案

《C++高效内存池实现减少动态分配开销的解决方案》C++动态内存分配存在系统调用开销、碎片化和锁竞争等性能问题,内存池通过预分配、分块管理和缓存复用解决这些问题,下面就来了解一下... 目录一、C++内存分配的性能挑战二、内存池技术的核心原理三、主流内存池实现:TCMalloc与Jemalloc1. TCM

OpenCV实现实时颜色检测的示例

《OpenCV实现实时颜色检测的示例》本文主要介绍了OpenCV实现实时颜色检测的示例,通过HSV色彩空间转换和色调范围判断实现红黄绿蓝颜色检测,包含视频捕捉、区域标记、颜色分析等功能,具有一定的参考... 目录一、引言二、系统概述三、代码解析1. 导入库2. 颜色识别函数3. 主程序循环四、HSV色彩空间

Python实例题之pygame开发打飞机游戏实例代码

《Python实例题之pygame开发打飞机游戏实例代码》对于python的学习者,能够写出一个飞机大战的程序代码,是不是感觉到非常的开心,:本文主要介绍Python实例题之pygame开发打飞机... 目录题目pygame-aircraft-game使用 Pygame 开发的打飞机游戏脚本代码解释初始化部