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

news2024/9/26 3:30:02
  • 操作系统: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.coloradmin.cn/o/1914648.html

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

相关文章

storybook中剔除chakra-ui的影响,或者剔除其他ui包的影响

介绍 经过一系列初始化完成后&#xff0c;storybook项目启动出来发现多余了一个ui框架的内容。如下图 因为项目中仅仅使用chakraUI的一些功能&#xff0c;并没有使用整体组件功能&#xff0c;所以说完全没必要把它留着这里。经过排查可以使用storybook中的refs功能剔除掉不需要…

1996-2023年各省农业总产值数据(无缺失)

1996-2023年各省农业总产值数据&#xff08;无缺失&#xff09; 1、时间&#xff1a;1996-2023年 2、来源&#xff1a;国家统计局、各省年鉴 3、指标&#xff1a;农业总产值 4、范围&#xff1a;31省 5、缺失情况&#xff1a;无缺失 6、指标解释&#xff1a;农业总产值是…

多协议网关设计架构与实现,支持 RS485/232、CAN、M-Bus、MQTT、TCP 等工业协议接入(附代码示例)

一、项目概述 1.1 背景 随着物联网技术的快速发展&#xff0c;越来越多的设备需要接入网络进行数据交互。然而&#xff0c;不同设备往往采用不同的通信协议&#xff0c;例如工业现场常用的Modbus、CAN、电力载波等&#xff0c;以及物联网领域常用的MQTT、TCP/IP等&#xff0c…

推荐一款功能强大的 GPT 学术优化开源项目GPT Academic:学术研究的智能助手

今天&#xff0c;我将向大家介绍一个强大的开源项目—GPT Academic&#xff0c;它或许正是你一直在寻找的理想工具。 已一跃成为 60.4k Star 的热门项目 GPT Academic 目前在 GitHub 上已经揽获了 60.4k 的 Star&#xff0c;这不仅反映了它的受欢迎程度&#xff0c;更证明了它…

什么是光储充一体化? 光储充一体化有什么优势?

大部分省份划定配储的比例不低于10% “光储充一体化”政策文件:国家层面政策名称 政策要点 发布时间 发布单位 结合实际建设光伏发电、储能、充换电一体化的充电基础设施。中央财政将安排奖励资金支持试点县开展试点工作&#xff0c;示范期内&#xff0c;每年均达到最高目标的试…

(pyqt5)弹窗-Token验证

前言 为了保护自己的工作成果,控制在合理的范围内使用,设计一个用于Token验证的弹窗. 代码 class TokenDialog(QDialog):def __init__(self, parentNone, login_userNone, mac_addrNone, funcNone):super(TokenDialog, self).__init__(parent)self.login_user login_userself…

2024年网络监控软件排名|10大网络监控软件是哪些

网络安全&#xff0c;小到关系到企业的生死存亡&#xff0c;大到关系到国家的生死存亡。 因此网络安全刻不容缓&#xff0c;在这里推荐网络监控软件。 2024年这10款软件火爆监控市场。 1.安企神软件&#xff1a; 7天免费试用https://work.weixin.qq.com/ca/cawcde06a33907e6…

d3dcompiler_43.dll文件是什么?如何快速有效的解决d3dcompiler_43.dll文件丢失问题

dcompiler_43.dll 是一个Windows系统中的系统文件&#xff0c;属于DirectX软件的一部分。这个dcompiler_43.dll&#xff08;动态链接库&#xff09;文件主要用于处理与3D图形编程有关的任务&#xff0c;是运行许多游戏和高级图形程序必需的组件之一。那么如果电脑丢失d3dcompil…

新手如何配置运行yolov5环境

&#x1f4da;博客主页&#xff1a;knighthood2001 ✨公众号&#xff1a;认知up吧 &#xff08;目前正在带领大家一起提升认知&#xff0c;感兴趣可以来围观一下&#xff09; &#x1f383;知识星球&#xff1a;【认知up吧|成长|副业】介绍 ❤️如遇文章付费&#xff0c;可先看…

部署Harbor仓库

本章内容&#xff1a; 安装docker-ce部署harbor仓库上传和拉取 1.安装docker 1&#xff09;拉取源码 yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo 2&#xff09;安装docker-ce yum -y install docker-ce 3&#…

Java 8革新:现代编程的全新标准与挑战

文章目录 一、方法引用二、接口默认方法三、接口静态方法四、集合遍历forEach()方法 一、方法引用 方法引用是Java 8中一种简化Lambda表达式的方式&#xff0c;通过直接引用现有方法来代替Lambda表达式。 方法引用使得代码更加简洁和易读&#xff0c;特别是在处理函数式接口时&…

数学建模国赛入门指南

文章目录 认识数学建模及国赛认识数学建模什么是数学建模&#xff1f;数学建模比赛 国赛参赛规则、评奖原则如何评省、国奖评奖规则如何才能获奖 国赛赛题分类及选题技巧国赛赛题特点赛题分类 国赛历年题型及优秀论文数学建模分工技巧数模必备软件数模资料文献数据收集资料收集…

NeRF++论文理解

今天想起这篇论文&#xff0c;于是将之前做得笔记复制过来以后方便查看

机器学习与深度学习:区别与联系(含工作站硬件推荐)

一、机器学习与深度学习区别 机器学习&#xff08;ML&#xff1a;Machine Learning&#xff09;与深度学习&#xff08;DL&#xff1a;Deep Learning&#xff09;是人工智能&#xff08;AI&#xff09;领域内两个重要但不同的技术。它们在定义、数据依赖性以及硬件依赖性等方面…

网页报错err_connection_timed_out 怎么办?教你快速修复错误代码

遇到网页错误提示“ERR_CONNECTION_TIMED_OUT”时&#xff0c;通常表示你的网络浏览器无法在规定时间内从服务器获取数据。这种错误不仅会阻碍你访问特定网站&#xff0c;而且可能会引起一些疑惑和不便。首先&#xff0c;这个问题可能是由于网络连接问题、服务器响应延迟或配置…

华为浏览器,Chrome的平替,插件无缝连接

文章目录 背景插件书签 背景 不知道各位小伙伴有没有这样的痛点&#xff0c;办公电脑、家里的电脑还有手机、平板等&#xff0c;收藏了一个网址或者在手机上浏览了某个网页&#xff0c;保存起来&#xff0c;可是一换平台或者换个电脑&#xff0c;在想要浏览之前收藏的东西&…

剪画小程序:父辈的照片模糊不清晰,怎么变清晰!

在我们的记忆深处&#xff0c;父辈和爷爷辈的影像总是伴随着一些模糊不清晰的老照片。这些照片或许没有现代摄影技术的高清与细腻&#xff0c;但它们却承载着无比厚重的岁月痕迹和情感温度。 每一张模糊的老照片&#xff0c;都是时光的切片。它们可能是父辈年轻时的纯真笑容&am…

Linux -- 认识 make/makefile

目录 前言&#xff1a; 什么是 make/makefile&#xff1f; 怎么使用 make/makefile&#xff1f; 依赖关系和依赖方法&#xff1a; 清理&#xff1a; 怎么使用 make&#xff1f; 如何编写多文件的 makefile&#xff1f; 什么是PHNOY&#xff1f; ACM时间 什么是AC…

maven项目读取文件错误

开发工具&#xff1a;idea 一个简单的maven项目&#xff0c;程序读取不到src/main/resources目录下的文件 寻找了一些原因后&#xff0c;还是没解决&#xff0c;最后灵机一动改了设置居然好了。 然后就解决了

LAZYNVIM学习使用笔记

文章目录 1. 前言VIM的模式快捷键参考 1. 前言 习惯使用vscode进行代码编辑&#xff0c;无意中刷到lazynvim&#xff0c;感觉功能强大&#xff0c;于是下载、安装&#xff0c;学习使用一下&#xff0c;本篇主要记录学习使用lazynvim的一些要点&#xff0c;防止遗忘。 持续更新…