OpenCV中使用Canny算法在图像中查找边缘

  • 操作系统:ubuntu22.04
  • OpenCV版本:OpenCV4.9
  • IDE:Visual Studio Code
  • 编程语言:C++11

算法描述

        Canny算法是一种广泛应用于计算机视觉和图像处理领域中的边缘检测算法。它由John F. Canny在1986年提出,旨在寻找给定噪声条件下的最佳边缘检测算法。Canny算法的主要特点和步骤包括:

  1. 应用高斯滤波:首先,使用高斯滤波器平滑图像,以去除噪声并减少细节,这有助于后续步骤中的边缘检测。
  2. 计算梯度强度和方向:接下来,通过对平滑后的图像应用Sobel算子,计算每个像素的梯度强度和方向。梯度强度指示了边缘的强度,而方向指示了边缘的方向。
  3. 非极大值抑制:在计算了梯度之后,执行非极大值抑制(Non-maximum suppression)。这一步骤涉及检查每个像素的梯度强度是否是局部最大值。如果不是,则认为该像素不是边缘的一部分,因此将其强度设置为零。
  4. 双阈值检测和边缘连接:最后,应用两个阈值:低阈值和高阈值。高于高阈值的边缘被确认为真正的边缘,而低于低阈值的边缘则被抛弃。介于两阈值之间的边缘仅在与高于高阈值的边缘相连时才被保留,这是为了防止断断续续的边缘。

        Canny算法因其在检测真实边缘的同时最大限度地减少错误检测和响应重复性方面的良好性能而受到推崇。在OpenCV中,可以通过调用Canny函数来应用Canny算法进行边缘检测

Canny函数

        该函数使用Canny算法在输入图像中查找边缘,并在输出映射edges中标记它们。在threshold1和threshold2之间,较小的值用于边缘连接,而较大的值用于寻找初始的强边缘段。更多信息请参考Canny边缘检测器的维基百科页面:http://en.wikipedia.org/wiki/Canny_edge_detector

函数原型1

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

参数1

  • 参数image 8位输入图像.通常应该是灰度图像
  • 参数 edges 输出的边缘图;单通道8位图像,其尺寸与image相同.这个输出图像将标记出检测到的边缘
  • 参数threshold1 滞后阈值程序的第一阈值,这是一个较低的阈值,用于确定哪些边缘应被进一步考虑。低于此阈值的像素会被视为非边缘
  • 参数threshold2 滞后阈值程序的第二阈值。这是一个较高的阈值,用于确定哪些边缘是强边缘。高于此阈值的像素将被确定为边缘
  • 参数apertureSize Sobel算子的孔径大小。Sobel算子用于计算图像中每个像素的梯度,孔径大小决定了Sobel算子的大小,这会影响边缘检测的精细程度。
  • 参数L2gradient 一个标志,指示是否应该使用更精确的 L 2 L_2 L2 n o r m = ( d I / d x ) 2 + ( d I / d y ) 2 norm=\sqrt{(dI/dx)^2 + (dI/dy)^2} norm=(dI/dx)2+(dI/dy)2 范数来计算图像的梯度大小(L2gradient=true),或者是否默认的 L 1 L_1 L1 n o r m = ∣ d I / d x ∣ + ∣ d I / d y ∣ norm=|dI/dx|+|dI/dy| norm=dI/dx+dI/dy 范数就足够(L2gradient=false)。L2范数是梯度向量的欧几里得长度,而L1范数是梯度分量的绝对值之和。

函数原型2

        这是一个重载成员函数,为了方便而提供。它与上述函数的不同之处仅在于它接受的参数。使用带有自定义图像梯度的Canny算法在图像中查找边缘

void cv::Canny	
(InputArray 	dx,InputArray 	dy,OutputArray 	edges,double 	threshold1,double 	threshold2,bool 	L2gradient = false 
)		

参数2

  • 参数dx 输入图像的16位x方向导数(类型为CV_16SC1或CV_16SC3)。这表示沿着x轴方向的图像梯度。
  • 参数dy 输入图像的16位y方向导数(与dx同类型)。这表示沿着y轴方向的图像梯度。
  • 参数 edges 输出的边缘图;单通道8位图像,其尺寸与image相同.这个输出图像将标记出检测到的边缘
  • 参数threshold1 滞后阈值程序的第一阈值,这是一个较低的阈值,用于确定哪些边缘应被进一步考虑。低于此阈值的像素会被视为非边缘
  • 参数threshold2 滞后阈值程序的第二阈值。这是一个较高的阈值,用于确定哪些边缘是强边缘。高于此阈值的像素将被确定为边缘
  • 参数apertureSize Sobel算子的孔径大小。Sobel算子用于计算图像中每个像素的梯度,孔径大小决定了Sobel算子的大小,这会影响边缘检测的精细程度。
  • 参数L2gradient 一个标志,指示是否应该使用更精确的 L 2 L_2 L2 n o r m = ( d I / d x ) 2 + ( d I / d y ) 2 norm=\sqrt{(dI/dx)^2 + (dI/dy)^2} norm=(dI/dx)2+(dI/dy)2 范数来计算图像的梯度大小(L2gradient=true),或者是否默认的 L 1 L_1 L1 n o r m = ∣ d I / d x ∣ + ∣ d I / d y ∣ norm=|dI/dx|+|dI/dy| norm=dI/dx+dI/dy 范数就足够(L2gradient=false)。L2范数是梯度向量的欧几里得长度,而L1范数是梯度分量的绝对值之和。

代码示例


#include <opencv2/opencv.hpp>
#include <iostream>int main(int argc, char** argv)
{// 读取图像cv::Mat image = cv::imread("/media/dingxin/data/study/OpenCV/sources/images/fruit_small.jpg", cv::IMREAD_COLOR);if (!image.data){std::cout << "Error: Could not open or find the image." << std::endl;return -1;}// 转换为灰度图像cv::Mat grayImage;cv::cvtColor(image, grayImage, cv::COLOR_BGR2GRAY);// 使用Canny算法检测边缘cv::Mat edges;int lowThreshold = 50;int highThreshold = 150;cv::Canny(grayImage, edges, lowThreshold, highThreshold);// 显示原始图像和边缘图像cv::namedWindow("Original Image", cv::WINDOW_NORMAL);cv::imshow("Original Image", image);cv::namedWindow("Edges", cv::WINDOW_NORMAL);cv::imshow("Edges", edges);// 等待按键后关闭窗口cv::waitKey(0);return 0;
}

运行结果

原图:
在这里插入图片描述
边缘计算之后的图:
在这里插入图片描述
你可以调整lowThreshold和highThreshold的值再运行后观察边缘图像的变化,便于理解函数的使用。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/46187.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Python+wxauto=微信自动化?

Pythonwxauto微信自动化&#xff1f; 一、wxauto库简介 1.什么是wxauto库 wxauto是一个基于UIAutomation的开源Python微信自动化库。它旨在帮助用户通过编写Python脚本&#xff0c;轻松实现对微信客户端的自动化操作&#xff0c;从而提升效率并满足个性化需求。这一工具的出现&…

详细分析Sql Server中的declare基本知识

目录 前言1. 基本知识2. Demo3. 拓展Mysql4. 彩蛋 前言 实战探讨主要来源于触发器的Demo 1. 基本知识 DECLARE 语句用于声明变量 声明的变量可以用于存储临时数据&#xff0c;并在 SQL 查询中多次引用 声明变量&#xff1a;使用 DECLARE 语句声明一个或多个变量变量命名&a…

SpringBoot整合JAX-RS接口

目录 二、创建RESTful资源 三、注册JAX-RS资源 四、修改配置等信息 五、启动SpringBoot程序、访问服务 六、遇到的问题 七、与feign进行配合使用 1、接口定义 2、接口实现 3、注册资源 4、调用方web服务实现&#xff0c;跟注入普通服务一样 5、启动两个服务&#xff…

html5——表单

目录 表单基本结构 表单标签 常用表单元素 文本框 密码框 邮箱 单选按钮 复选框 文件域 隐藏域 列表框 多行文本域 lable标签 表单按钮 常用表单属性 只读与禁用 placeholder required pattern autofocus autocomplete 用于指定表单是否有自动完…

NoSQL之redis的配置与优化

一、redis数据库的基础介绍与对比 Redis(RemoteDictionaryServer&#xff0c;远程字典型)是一个开源的、使用C语言编写的NoSQL数据库。Redis 基于内存运行并支持持久化&#xff0c;采用 key-value(键值对)的存储形式&#xff0c;是目前分布式架构中不可或缺的一环。 1.非关系…

百日筑基第二十天-一头扎进消息队列3-RabbitMQ

百日筑基第二十天-一头扎进消息队列3-RabbitMQ 如上图所示&#xff0c;RabbitMQ 由 Producer、Broker、Consumer 三个大模块组成。生产者将数据发送到 Broker&#xff0c;Broker 接收到数据后&#xff0c;将数据存储到对应的 Queue 里面&#xff0c;消费者从不同的 Queue 消费数…

我的智能辅助大师-办公小浣熊

一、基本介绍 随着2022年ChatGPT为代表的AI工具对互联网领域进行第一次冲击后&#xff0c;作为一名对编程领域涉足不算特别深的一名程序员&#xff0c;对AI大模型的接触也真的不能算少了&#xff0c;这是时代的必然趋势。在此之前也曾接触过很多的AI工具&#xff0c;他们都能在…

【Vscode】显示多个文件 打开多个文件时实现标签栏多行显示

Vscode显示多个文件&VSCode打开多个文件时实现标签栏多行显示 写在最前面一、解决打开文件的时候只显示一个tab的办法解决办法如下&#xff1a; 二、文件标签栏多行显示设置步骤&#xff1a; &#x1f308;你好呀&#xff01;我是 是Yu欸 &#x1f30c; 2024每日百字篆刻时…

电脑维护全攻略:让你的“战友”焕发新生

目录 电脑维护全攻略&#xff1a;让你的“战友”焕发新生 引言 方向一&#xff1a;了解你的“战友” 1.1 电脑品牌与型号的选择 1.2 电脑硬件配置的重要性 1.3 电脑软件配置的重要性 方向二&#xff1a;日常维护措施 2.1 定期清理与优化 2.2 保持良好的上网习惯 2.3 …

微服务-注册中心

一. 分布式系统架构与微服务 分布式系统架构和微服务是现代软件开发中常见的两种概念&#xff0c;它们通常结合使用来构建灵活、可扩展和高效的应用程序。 分布式系统架构&#xff1a; 分布式系统架构是指将一个单一的应用程序或服务拆分成多个独立的部分&#xff0c;这些部分…

邮箱表单系统源码

邮箱表单简介 我们的邮箱表单系统是一个简洁高效的工具&#xff0c;旨在为用户提供一种便捷的方式来提交他们的邮箱地址。该系统可以用于订阅新闻通讯、注册活动、获取用户反馈等多种场景。 功能特点&#xff1a; 用户友好的界面&#xff1a; 表单设计简洁直观&#xff0c;用…

t-SNE降维可视化并生成excel文件使用其他画图软件美化

t-sne t-SNE&#xff08;t-分布随机邻域嵌入&#xff0c;t-distributed Stochastic Neighbor Embedding&#xff09;是由 Laurens van der Maaten 和 Geoffrey Hinton 于 2008 年提出的一种非线性降维技术。它特别适合用于高维数据的可视化。t-SNE 的主要目标是将高维数据映射…

修改vscode的字体为等宽字符

在文件——首选项——设置 中 搜索 Editor: Font Family 将内容改为下面的 Consolas, Courier New, monospace 之后重启Vscode就行了

初步探究Rust生态与图形界面编程

引言 Rust作为一种现代的、安全的系统编程语言&#xff0c;自2010年问世以来&#xff0c;逐渐在开发社区中崭露头角。它的内存安全保证、并发处理能力、以及无需垃圾回收机制的高性能特性&#xff0c;使得它成为了开发系统工具、网络服务、以及嵌入式系统的热门选择。然而&…

(五十三)第 8 章 动态存储管理(伙伴系统)

1. 背景说明 2. 示例代码 buddySystem.h // 伙伴系统实现头文件#ifndef BUDDY_SYSTEM_H #define BUDDY_SYSTEM_H#include "errorRecord.h"#define POWER_TIME 10 // 可利用空间总容量的 2 的幂次,子表的个数为 POWER_TIME + 1 #define MAX_USED_BLOCK_NUM 100 //…

我的 Java 面试“打怪升级”之路01

前言 在当今的科技行业&#xff0c;Java 作为一门广泛应用的编程语言&#xff0c;其相关的岗位竞争可谓十分激烈。作为一名求职者&#xff0c;经历 Java 面试就如同一场充满挑战的“打怪升级”游戏。在这里&#xff0c;我想和大家分享一下我在 Java 面试中的一些经历和感悟。 …

SwiftUI 截图(snapshot)视频画面的极简方法

功能需求 在 万物皆可截图:SwiftUI 中任意视图(包括List和ScrollView)截图的通用实现 这篇博文中,我们实现了在 SwiftUI 中截图几乎任何视图的功能,不幸的是它对视频截图却无能为力。不过别着急,我们还有妙招。 在上面的演示图片中,我们在 SwiftUI 中可以随心所欲的截图…

前端Vue组件化实践:打造灵活可维护的地址管理组件

随着前端技术的不断演进&#xff0c;复杂度和开发难度也随之上升。传统的一体化开发模式使得每次小小的修改或功能增加都可能牵一发而动全身&#xff0c;严重影响了开发效率和维护成本。组件化开发作为一种解决方案&#xff0c;通过模块化、独立化的开发方式&#xff0c;实现了…

【java算法专场】滑动窗口(下)

目录 水果成篮 算法分析 算法步骤 示例 算法代码 找到字符串中所有字母异位词 算法分析 算法步骤 示例 算法代码 优化 算法代码 串联所有单词的子串 算法分析 算法步骤 示例 算法代码 最小覆盖子串 算法分析 算法步骤 示例 算法代码 算法分析 这道题其实…

AI绘画Stable Diffusion 自制素材工具: layerdiffusion插件—透明背景生成工具

大家好&#xff0c;我是设计师阿威 今天给大家分享一款AI绘画的神级插件—LayerDiffusion。 Layerdiffusion是一个用于stable-diffusion-webui 的透明背景生成&#xff08;不是生成图再工具扣图&#xff0c;是直接生成透明背景透明图像&#xff09;插件扩展&#xff0c;它可以…