Canny算子与霍夫变换检测圆与直线

article/2025/9/23 19:16:18

目录

引言

一、canny算子

二、canny算子代码

 三、霍夫变换检测直线

四、霍夫变换检测直线代码

五、霍夫变换检测直线效果

六、霍夫变换检测圆

七、霍夫变换检测圆代码

八、霍夫变换检测圆效果


引言

canny算子是计算机视觉最常用的一种算子,是目前一种非常流行的算法,是John Canny在1986年提出的。它是一个多阶段的算法,即由多个步骤构成。虽然Canny算法年代久远,但可以说它是边缘检测的一种标准算法,而且仍在研究中广泛使用。霍夫变换是一种在图像中寻找直线、圆形以及其他简单形状的方法。霍夫变换采用类似于投票的方式来获取当前图像内的形状集合,该变换由Paul Hough(霍夫)于1962年首次提出。本文将介绍canny算子与霍夫变换检测圆与直线,附完整可运行代码,希望可以带来帮助。

一、canny算子

canny算子可以分为以下几步:

  1. 应用高斯滤波来平滑图像,目的是去除噪声
  2. 找寻图像的强度梯度(intensity gradients)
  3. 应用非最大抑制(non-maximum suppression)技术来消除边误检(本来不是但检测出来是)
  4. 应用双阈值的方法来决定可能的(潜在的)边界
  5. 利用滞后技术来跟踪边界

先看下lena经canny算子的效果图:

 高斯滤波其实就是将所指像素用周围的像素的某种均值代替(即卷积核),卷积核尺寸越大,去噪能力越强,因此噪声越少,但图片越模糊,canny检测算法抗噪声能力越强,但模糊的副作用也会导致定位精度不高。高斯的卷积核大小推荐:一般情况下,尺寸5 * 5,3 * 3也行。

二、canny算子代码

import cv2
img =  cv2.imread("lena.png")
img_5 = cv2.Canny(img, 100, 200)
cv2.namedWindow("W5")
cv2.imshow("W5", img_5)
cv2.imwrite("canny_img.jpg",img_5)
cv2.waitKey()
cv2.destroyAllWindows()

 三、霍夫变换检测直线

霍夫直线检测利用图像与霍夫空间中点与线的对偶性,将图像空间中待检测的离散像素点集通过参数方程映射为霍夫空间中极坐标上的曲线集,并将曲线的交点作为通过n个离散点的直线方程参数映射到图像空间中的直线。即点(图像空间)-线(霍夫空间)-交点(霍夫空间)-线(图像空间)。将找直线问题转换为找交点问题,同时考虑到笛卡尔坐标系存在垂直线无法检测的问题,因而利用极坐标去表示,转换为曲线交点检测。
HoughLine函数:

HoughLine(inputimage,outputline,double rho,double theta,int tereshold,double srn=0,double stn=0)

霍夫变换基于opencv的实现
@para1:输入图像,需要为8位单通道二进制图像
@para2:储存输出的矢量线条,用θ,ρ表示。ρ为直线离坐标原点(图像左上角)的距离。θ表示弧度线条旋转角度(0为垂线,π/2为水平线)
@para3:以像素为单位的距离精度(即搜索直线时ρ轴的步进分辨率,一般为1)
@para4:以弧度为单位的角度精度(即搜索直线时θ轴的步进分辨率,一般为CV_PI/180,即1度)
@para5:累加空间的阈值参数,即识别直线时在累加空间必须达到的阈值,大于threshold的线段才能被认为检测到。
@para6:默认值0。对于多尺度霍夫变换srn表示@para3步进分辨率的除数距离。
@para7:默认值0。对于多尺度霍夫变换stn表示@para4步进分辨率的除数距离。如果srn和stn都为0时表示经典霍夫变换,否则应为正数。


四、霍夫变换检测直线代码

import cv2
import numpy as np
def lines_judge(img):o = img.copy()# 使用中值滤波进行降噪o = cv2.medianBlur(o, 5)# 从彩色图像变成单通道灰度图像gray = cv2.cvtColor(o, cv2.COLOR_BGR2GRAY)# 绘制边缘图像binary = cv2.Canny(o, 50, 150)# 检测直线 不限步长,不限角度,至少50个点确定一条线lines = cv2.HoughLines(binary, 1, np.pi / 180, 285)# print(lines)# print(lines.shape)try:list = [ line for line in lines]except TypeError or IndentationError:print("未检测到直线!")else:for line in lines:rho, theta = line[0]a = np.cos(theta)b = np.sin(theta)x0 = a * rhoy0 = b * rhox1 = int(x0 + 1000 * (-b))y1 = int(y0 + 1000 * (a))x2 = int(x0 - 1000 * (-b))y2 = int(y0 - 1000 * (a))cv2.line(img, (x1, y1), (x2, y2), (0, 0, 255), 2)cv2.imshow("img", img)cap = cv2.VideoCapture(0) # 调用本地摄像头
while True:flag,frame = cap.read()if not flag:breaklines_judge(frame)if ord("q") == cv2.waitKey(1):break
cv2.waitKey()
cv2.destroyAllWindows()

五、霍夫变换检测直线效果

车道识别视频

看看代码运行的效果:我在电脑里插入一段视频,和前面的原理类似,捕获每一帧,如果在这一帧里检测到直线就标出来,没检测的话在对话框里给出反馈:没检测到直线。这样在调整参数时,更加直观。

六、霍夫变换检测圆

Hough Transform(霍夫变换)是早期的一种以投票方案进行图形拟合的算法。所谓拟合就是要将图像中的一些边缘用数学方式来描述,可以使人们更好的操作使用图像提供的信息。相比较最小二乘法、鲁棒估计以及RANSAC方法,霍夫变换的优点在于可以进行多目标的拟合。本次在此讨论研究霍夫圆的拟合原理。

霍夫圆算法的实现一共可分为两个步骤:

  • 建立霍夫参数三维空间,并对空间内各个单元进行投票
  • 设置阈值从投票结果中筛选合适的圆,并做非极大化抑制

详细了解可以看这篇文章:霍夫变换检测圆

七、霍夫变换检测圆代码

import cv2
import numpy as npdef decodeDisplay(video, flag):gay_img = cv2.cvtColor(video, cv2.COLOR_BGRA2GRAY)img = cv2.medianBlur(gay_img, 7)  # 进行中值模糊,去噪点cimg = cv2.cvtColor(img, cv2.COLOR_GRAY2BGR)circles = cv2.HoughCircles(img, cv2.HOUGH_GRADIENT, 1, 50, param1=100, param2=30, minRadius=100, maxRadius=150)if circles is not None:circles = np.uint16(np.around(circles))print(circles)for i in circles[0, :]:  # 遍历矩阵每一行的数据cv2.circle(video, (i[0], i[1]), i[2], (0, 255, 0), 2)cv2.circle(video, (i[0], i[1]), 2, (0, 0, 255), 3)cv2.imshow("gay_img", video)else:pass# 如果识别不出,显示圆心不存在# print('x: None y: None')# cv2.imshow('frame', video)def detect():cap = cv2.VideoCapture(0)while True:# 逐帧捕获ret, frame = cap.read()# cv2.imshow("img", frame)flag = cv2.waitKey(1)if ord("q") == flag:breakelse:flag = decodeDisplay(frame, flag)
# 一切完成后,释放捕获cap.release()cv2.destroyAllWindows()if __name__ == '__main__':detect()

八、霍夫变换检测圆效果

霍夫变换检测圆

同样我们直接看视频:在我的手里是一个圆形的物体,我调用本地摄像头,对图片检测。可以看到,检测效果很好,绿色的标记一直跟着我的手在运动;并且左下角不断输出着圆心的坐标。

好啦,今天的分享就到这里啦!有什么问题或者发现错误的地方都可以在评论区或者私信联系我哦!

文章最后附canny算子可视调参数的工具链接:https://pan.baidu.com/s/1jIWS1zif8ddi-1LPIjrEaw?pwd=xpj0 
提取码:xpj0


http://chatgpt.dhexx.cn/article/BdK0LXdd.shtml

相关文章

OpenCV——Canny边缘检测(cv2.Canny())

Canny边缘检测 Canny 边缘检测是一种使用多级边缘检测算法检测边缘的方法。1986 年,John F. Canny 发 表了著名的论文 A Computational Approach to Edge Detection,在该论文中详述了如何进行边缘 检测。 Canny()边缘检测步骤 Canny 边缘检测分为如下…

(十一)Canny 边缘检测算法

Canny边缘检测算法 一、边缘检测的步骤 1)滤波: 边缘检测的算法主要是基于图像强度的一阶和二阶导数,但导数通常对噪声很敏感, 因此必须采用滤波器来改善与噪声有关的边缘检测器的性能。常见的滤波方法主要有高斯滤波、均值滤波…

Canny边缘检测算法的实现

图像边缘信息主要集中在高频段,通常说图像锐化或检测边缘,实质就是高频滤波。我们知道微分运算是求信号的变化率,具有加强高频分量的作用。在空域运算中来说,对图像的锐化就是计算微分。由于数字图像的离散信号,微分运…

【canny边缘检测】canny边缘检测原理及代码详解

文章目录 前言canny边缘检测算法主要流程一、高斯模糊二、图像梯度计算三、非极大值抑制四、双阈值边界跟踪 前言 本文通过介绍canny边缘检测原理与代码解析,希望能让大家深入理解canny边缘检测 canny边缘检测算法主要流程 canny边缘检测主要分为4个部分&#xff…

Canny边缘检测原理

一. Canny基本思想 1. 边缘检测 解析:边缘是对象和背景之间的边界,还能表示重叠对象之间的边界。边缘检测是图像分割的一部分,图像分割的目的是识别出图像中的区域。边缘检测是定位边缘像素的过程,而边缘增强是增加边缘和背景之…

Canny边缘检测

边缘检测发展 Canny 边缘检测是一种从不同视觉对象中提取有用结构信息并显着减少要处理的数据量的技术。它已广泛应用于各种计算机视觉系统。 Canny 发现,在不同的视觉系统上应用边缘检测的要求是比较相似的。因此,可以在各种情况下实施满足这些要求的边…

Canny边缘检测算法(python 实现)

文章目录 最优边缘准则算法实现步骤1. 应用高斯滤波来平滑(模糊)图像,目的是去除噪声2. 计算梯度强度和方向3. 应用非最大抑制技术NMS来消除边误检4. 应用双阈值的方法来决定可能的(潜在的)边界5. 利用滞后技术来跟踪边界 opencv实现Canny边缘…

左外连接和右外连接是什么样的?

1左外连接 左表的记录都会出现在结果集中,并上右表与之对应的部分,如果右表没有,使用null填充。 举例。 select * from people p left join role r p.idr.id 左外连接结果: 2、右外连接 右表的记录都会出现在结果集中&#xf…

sql左外连接和右外连接的区别

一、数据集合不同 1、左外连接:是A和B的交集再并上A的所有数据。 2、右外连接:是A和B的交集再并上B的所有数据。 二、语法不同 1、左外连接:SELECT *FROM aLEFT OUTER JOIN bON a.ageId b.id。 2、右外连接:SELECT *FROM a…

MySQL自连接和内连接和外连接_左外连接+右外连接

自连接:将一张表看作两张表 练习:查询员工id,员工姓名及其管理者的id和姓名select emp.employee_id,emp.last_name,mgr.employee_id,mgr.last_name from employees emp,employees mgr where emp.manager_id mgr.employee_id;内连接 只是把左…

SQL--左外连接(LEFT JOIN)

LEFT JOIN 关键字从左表(table1)返回所有的行,即使右表(table2)中没有匹配。如果右表中没有匹配,则结果为 NULL。 SQL LEFT JOIN 语法: SELECT column_name(s) FROM table1 LEFT JOIN table2 ON table1.c…

内连接、左连接、左外连接、右连接的区别

一:测试例子 存在如下两张表:年级与班级,表内容如下 班级表 二:内连接与自然连接 1:自然连接 对于select * from gradeclass gc where gc.grade_id in (select id from grade),其结果如下图 其查询是把符…

数据库之SQL(基本连接,内连接,左外连接,右外连接,全外连接,交叉连接,自连接)

之前的博客内容我们分享了数据表的查询与管理,但那只是针对数据库中的一个表格进行的查询管理,现在如果我们想要同时看到两个数据表中的数据的话,那要怎么办呢?采用多连接查询的方式。 SQL中有哪几种多连接的方式? 有七…

左连接、右连接、内连接、外连接简单说明

例如有两个表: test1: test2: 内连接:(inner join on)返回两个表的交集。 例如: select * from test1 a inner join test2 b on a.idb.id; 结果: 外连接:返回两个表的并集。(在此就不做截图…

MySQL之左外连接右外连接

外连接: 假设A和B表进行连接,使用外连接的话, AB两张表中有一张表是主表,一张表是副表,主要查询主表中的数据,捎带着查询副表, 当副表中的数据没有和主表中的数据匹配上,副表自动模…

秒懂sql中的左外连接

左外连接: 1.语法: SELECT 查询字段 FROM 查询表格(左表) LEFT JOIN 右表 ON 查询条件 2.左外连接查询的就是左表,那干嘛加个右表,岂不是没有作用: 区别在于左外连接是查询完左表后&…

sql的四种连接——左外连接、右外连接、内连接、全连接

一、内连接 满足条件的记录才会出现在结果集中。 二、 左外连接(left outer join,outer可省略) 左表全部出现在结果集中,若右表无对应记录,则相应字段为NULL 举例说明: 客户表: 订单表&#x…

数据库的内连接、外连接(左外连接、右外连接、全外连接)以及交叉连接

SQL数据库的连接:内连接、和外连接(左外连接、右外连接、和全连接) 本次实验在MySQL数据库中进行,数据库初始表如下: 一、内连接:结果仅包含符合连接条件的两表中的行。如下: 二、外连接&#…

oracle左外连接、右外连接、完全外连接以及(+)号用法

准备工作 oracle连接分为: 左外连接:左表不加限制,保留左表的数据,匹配右表,右表没有匹配到的行中的列显示为null。右外连接:右表不加限制,保留右表的数据。匹配左表,左表没有匹配到…

左连接,右链接

用两个表(a_table、b_table),关联字段a_table.a_id和b_table.b_id来演示一下MySQL的内连接、外连接( 左(外)连接、右(外)连接、全(外)连接)。 MySQL版本:Server version: 5.6.31 MySQL Community Server (…