014 OpenCV canny边缘检测

一、环境

本文使用环境为:

  • Windows10
  • Python 3.9.17
  • opencv-python 4.8.0.74

二、canny原理

OpenCV中的Canny边缘检测算法是一种基于图像处理的计算机视觉技术,主要用于检测图像中的边缘。Canny边缘检测算法的原理是通过计算图像中像素点之间的梯度值来寻找边缘。这种方法可以有效地消除噪声,同时保留图像中的主要特征。本文将对Canny边缘检测算法的原理进行详细介绍。

2.1 基本原理

Canny边缘检测算法的基本原理是利用图像的梯度信息来寻找边缘。在图像中,边缘通常表现为颜色或亮度的突然变化。为了检测这些边缘,我们需要计算图像中每个像素点的梯度值。梯度是一个向量,表示图像在该点的方向和幅度的变化。梯度的大小和方向可以用来确定边缘的位置和方向。

Canny边缘检测算法主要包括以下几个步骤:

(1) 对图像进行平滑处理,以消除噪声。

(2) 计算图像中每个像素点的梯度值和方向。

(3) 对梯度值进行非极大值抑制,以得到细化的边缘。

2.2 平滑处理

在进行边缘检测之前,首先需要对图像进行平滑处理,以消除噪声。常用的平滑方法有高斯滤波、中值滤波等。高斯滤波是一种线性滤波方法,它可以有效地消除高斯噪声。中值滤波是一种非线性滤波方法,它可以有效地消除椒盐噪声。

在OpenCV中,可以使用cv2.GaussianBlur()函数进行高斯滤波,使用cv2.medianBlur()函数进行中值滤波。

2.3 计算梯度值和方向

为了计算图像中每个像素点的梯度值和方向,我们需要使用Sobel算子。Sobel算子是一种用于计算图像梯度的离散差分算子,它包括水平方向和垂直方向两个算子。通过分别计算水平和垂直方向的梯度值,我们可以得到每个像素点的梯度向量。梯度向量的方向表示边缘的方向,梯度向量的大小表示边缘的强度。

在OpenCV中,可以使用cv2.Sobel()函数计算图像的梯度值和方向。

2.4 非极大值抑制

非极大值抑制是一种用于细化边缘的方法,它可以有效地消除假边缘。非极大值抑制的基本思想是:在当前像素点的邻域内,如果存在一个梯度值更大的像素点,那么将当前像素点的梯度值设置为0。这样,我们就可以得到一个细化的边缘图。

2.5 双阈值法进行边缘连接

双阈值法是一种用于连接边缘的方法,它可以有效地消除孤立的边缘点。双阈值法的基本思想是:根据梯度值的大小设置两个阈值,将梯度值大于高阈值的像素点标记为强边缘,将梯度值小于低阈值的像素点标记为弱边缘。然后,只保留强边缘,将弱边缘连接到相邻的强边缘上。这样,我们就可以得到一个连续的边缘图。

在OpenCV中,可以使用cv2.threshold()函数进行双阈值处理。

三、完整代码

python 复制代码
from __future__ import print_function
import cv2 as cv
import argparse

max_lowThreshold = 100
window_name = 'Edge Map'
title_trackbar = 'Min Threshold:'
ratio = 3
kernel_size = 3

def CannyThreshold(val):
    low_threshold = val
    # 将图像使用3x3高斯核模糊平滑下
    img_blur = cv.blur(src_gray, (3,3))
    # canny边缘检测
    detected_edges = cv.Canny(img_blur, low_threshold, low_threshold*ratio, kernel_size)
    # detected_edges是边缘,二值图的形式
    mask = detected_edges != 0
    # 使用边缘二值图和原图相乘,目的是取出彩色的边缘
    dst = src * (mask[:,:,None].astype(src.dtype))
    cv.imshow(window_name, dst)

parser = argparse.ArgumentParser(description='Code for Canny Edge Detector tutorial.')
parser.add_argument('--input', help='Path to input image.', default='data/fruits.jpg')
args = parser.parse_args()
# 读取图片
src = cv.imread(cv.samples.findFile(args.input))
if src is None:
    print('Could not open or find the image: ', args.input)
    exit(0)
# 彩色图转灰度图
src_gray = cv.cvtColor(src, cv.COLOR_BGR2GRAY)
# 创建窗口
cv.namedWindow(window_name)
cv.createTrackbar(title_trackbar, window_name , 0, max_lowThreshold, CannyThreshold)

CannyThreshold(0)
cv.waitKey()
相关推荐
余弦的倒数13 分钟前
知识蒸馏和迁移学习的区别
人工智能·机器学习·迁移学习
Allen Bright13 分钟前
【机器学习-线性回归-2】理解线性回归中的连续值与离散值
人工智能·机器学习·线性回归
weixin_贾21 分钟前
最新AI-Python机器学习与深度学习技术在植被参数反演中的核心技术应用
python·机器学习·植被参数·遥感反演
张槊哲30 分钟前
函数的定义与使用(python)
开发语言·python
船长@Quant35 分钟前
文档构建:Sphinx全面使用指南 — 实战篇
python·markdown·sphinx·文档构建
青松@FasterAI1 小时前
【程序员 NLP 入门】词嵌入 - 上下文中的窗口大小是什么意思? (★小白必会版★)
人工智能·自然语言处理
AIGC大时代1 小时前
高效使用DeepSeek对“情境+ 对象 +问题“型课题进行开题!
数据库·人工智能·算法·aigc·智能写作·deepseek
硅谷秋水1 小时前
GAIA-2:用于自动驾驶的可控多视图生成世界模型
人工智能·机器学习·自动驾驶
偶尔微微一笑1 小时前
AI网络渗透kali应用(gptshell)
linux·人工智能·python·自然语言处理·编辑器
深度之眼2 小时前
2025时间序列都有哪些创新点可做——总结篇
人工智能·深度学习·机器学习·时间序列