霍夫变换:原理剖析与 OpenCV 应用实例

news2024/11/30 6:36:13

在这里插入图片描述

简介:本文围绕霍夫变换相关内容展开,先是讲解霍夫变换基本原理,包含从 xy 坐标系到 kb 坐标系及极坐标系的映射等。接着介绍了 cv2.HoughLines、cv2.HoughLinesP 概率霍夫变换、cv2.HoughCircles 霍夫圆变换的函数用法、参数含义、与常规霍夫变换区别以及实现步骤,并附代码示例,助力读者理解和运用这些图像检测技术。
如果我的文章对你有帮助,请点赞收藏关注,我将会持续为您带来更多与OpenCV有关的知识。

霍夫变换:原理剖析与 OpenCV 应用实例

  • 霍夫变换基本原理
  • cv2.HoughLines函数
    • 实现一次霍夫变换
    • cv2.HoughLinesP概率霍夫变换
    • 霍夫圆变换cv2.HoughCircles
  • 致谢

霍夫变换基本原理

画一张图 y = kx+b:,用xy坐标系如图所示:
在这里插入图片描述
如果用k,b坐标系该这样表示:
在这里插入图片描述
(xy空间的一条线确定了kb空间的一个点)
我现在在xy轴里取一个点 (x0,y0):
在这里插入图片描述
此时x0,y0确定,他可能在任意一条直线上,根据公式 y0 = kx0+b,那么b = y0-kx0,所以在kb空间上:
在这里插入图片描述
说明xy的一个点对应 kb的一条线
再来观察,两个xy坐标的点 x0,y0 x1,y1,同时两点确定了一条直线,看图:
在这里插入图片描述
对应在kb空间应该是如下图:
在这里插入图片描述
我们会进行三步推理:
第一步:xy坐标系的一条直线上的两个点,对应着kb空间经过同一个点的两条直线。
第二步:推理可以知道,kb坐标系中间经过一个点的直线越多,说明在xy坐标系中是由更多的点所构成。
第三步:已知两个点确定一条直线,对于图像中的线怎么确定不是谬误,噪声呢?那多个点确定的直线不出错的概率相对来说肯定是更大的
第四步:霍夫变换选择直线的基本思路是,选择又尽可能多的直线交汇的点
但是,有一种特殊情况不能完成从xy坐标系映射到kb坐标系:垂线
在这里插入图片描述
所以可以映射到极坐标系:r = xcosa+ ysina
在这里插入图片描述

cv2.HoughLines函数

lines 返回的ndarray数组,数组的每一对数据都是(r,a) = cv2.HoughLines(image输入图像必须是八位单通道二值图像 ,rho为r的精度一般为1,theta为角度的精度一般情况使用pi/180,threshold是阈值,他是霍夫空间的直线条数大于阈值才能被认为是xy空间的直线,所以阈值越小找到的直线越多)
我们选择验证的例子基于这张图片,我给他命名为calculator.JPG放在跟代码同一个文件夹下,大家可以复制我的图片重命名自己去运行代码:
在这里插入图片描述

实现一次霍夫变换

(第一步)读取图片
(第二步)转化为灰度图
(第三步)使用cv2.Canny边缘检测获得边缘
(第四步)使用霍夫变换
(第五步)为了看到霍夫变化的差异,将原图从bgr转化成 rgb,并复制一张原图片
(第六步)对霍夫变换的结果从极坐标转换成xy坐标并在原图画线
(第七步)展示原图与画线后的图片差别

import numpy as np
import cv2
import matplotlib.pyplot as plt
img = cv2.imread("calculator.JPG")
# 转化为灰度图
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
#使用cv2.Canny边缘检测获得边缘
edges = cv2.Canny(gray,50,150,apertureSize = 3)
#使用霍夫变换
lines = cv2.HoughLines(edges,1,np.pi/180,133)
#为了看到霍夫变化的差异,将原图从bgr转化成 rgb,并复制一张原图片
orgb = cv2.cvtColor(img,cv2.COLOR_BGR2RGB)
oShow = orgb.copy()

# 对霍夫变换的结果从极坐标转换成xy坐标并在原图画线
for line in lines:
    rho,theta =line[0]
    a = np.cos(theta)
    b = np.sin(theta)
    x0 = a*rho
    y0 = b*rho
    x1 = int(x0+1000*(-b))
    y1 = int(y0+1000*(a))
    x2 = int(x0-1000*(-b))
    y2 = int(y0-1000*(a))
    cv2.line(orgb,(x1,y1),(x2,y2),(0,0,255),2)

plt.subplot(121)
plt.imshow(oShow)
plt.axis("off")
plt.title("original")

plt.subplot(122)
plt.imshow(orgb)
plt.axis("off")
plt.title('huofu')

plt.show()

在这里插入图片描述

cv2.HoughLinesP概率霍夫变换

与霍夫变换的区别:

  1. 霍夫变换考虑了所有的点,而概率只考虑了一个足以进行线检测的随机点的子集
  2. 概率设置了所接受直线的最小长度
  3. 接受直线时所允许的最大像素点间距
    语法上多了两个参数 一个是最小长度minLineLength和maxLineGap

步骤上并没有太多区别,仅仅是在调用函数时后多两个参数,阈值调低(后两个参数保证了即使低阈值也不会产生很多无效的直线)。

import numpy as np
import cv2
import matplotlib.pyplot as plt
img = cv2.imread("calculator.JPG")
# 转化为灰度图
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
#使用cv2.Canny边缘检测获得边缘
edges = cv2.Canny(gray,50,150,apertureSize = 3)
#使用概率霍夫变换 设置minLineLength和maxLineGap
lines = cv2.HoughLinesP(edges,1,np.pi/180,1,minLineLength = 120,maxLineGap = 10)
#为了看到霍夫变化的差异,将原图从bgr转化成 rgb,并复制一张原图片
orgb = cv2.cvtColor(img,cv2.COLOR_BGR2RGB)
oShow = orgb.copy()

# 对霍夫变换的结果从极坐标转换成xy坐标并在原图画线
for line in lines:
    x1,y1,x2,y2 = line[0]
    cv2.line(orgb,(x1,y1),(x2,y2),(0,0,255),2)

plt.subplot(121)
plt.imshow(oShow)
plt.axis("off")
plt.title("original")

plt.subplot(122)
plt.imshow(orgb)
plt.axis("off")
plt.title('huofu')

plt.show()

在这里插入图片描述

霍夫圆变换cv2.HoughCircles

需要考虑圆半径和圆心x,y。两轮筛选,第一轮找出可能存在的圆心,第二轮判断半径。
circles 由圆心坐标和半径组成的ndarray= cv2.HoughCircles(image八位单通道灰度图,method检测方法 cv2.HOUGH_GRADIENT,dp累计其分辨率,若dp=1输入图像和结果具有相同的分辨率,minDist圆心之间的最小间距,太小会有多个邻近的圆,太大会漏掉一些圆,param1默认为100他是canny边缘检测的阈值,param2默认是100他越大检测到的圆越少,minRadius和maxRadius圆半径的最大值最小值 )
注意:在调用函数之前要进行平滑处理,减少噪声避免误判
使用这张图我命名为bicycly.JPG,存在和代码同一个文件夹下,大家可以复制我的图片然后重命名:在这里插入图片描述

import numpy as np
import cv2
import matplotlib.pyplot as plt
img = cv2.imread("bicycle.JPG",0)
o = cv2.cvtColor(img,cv2.COLOR_BAYER_BG2RGB)
oshow = o.copy()
# 使用中值滤波
img = cv2.medianBlur(img,5)
circles = cv2.HoughCircles(img,cv2.HOUGH_GRADIENT,1,200,param1 = 5,
                           param2 = 5,minRadius =3, maxRadius = 200)
circles = np.uint16(np.around(circles))
for i in circles[0,:]:
    cv2.circle(o,(i[0],i[1]),i[2],(255,0,0),12)
    cv2.circle(o,(i[0],i[1]),2,(255,0,0),12)
    
plt.subplot(121)
plt.imshow(oshow)
plt.axis("off")
plt.title("original")

plt.subplot(122)
plt.imshow(o)
plt.axis("off")
plt.title("circle")

plt.show()

在这里插入图片描述

致谢

本文参考了一些博主的文章,博取了他们的长处,也结合了我的一些经验,对他们表达诚挚的感谢,使我对 OpenCV霍夫变换 有更深入的了解,也推荐大家去阅读一下他们的文章。纸上学来终觉浅,明知此事要躬行:
【OpenCV学习笔记】之霍夫变换(Hough Transform)

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

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

相关文章

【Debug】hexo-github令牌认证 Support for password authentication was removed

title: 【Debug】hexo-github令牌认证 date: 2024-07-19 14:40:54 categories: bug解决日记 description: “Support for password authentication was removed on August 13, 2021.” cover: https://pic.imgdb.cn/item/669b38ebd9c307b7e9f3e5e0.jpg 第一章 第一篇博客记录一…

JVM 性能调优 -- JVM常用调优工具【jps、jstack、jmap、jstats 命令】

前言: 前面我们分析怎么去预估系统资源,怎么去设置 JVM 参数以及怎么去看 GC 日志,本篇我们分享一些常用的 JVM 调优工具,我们在进行 JVM 调优的时候,通常需要借助一些工具来对系统的进行相关分析,从而确定…

net9 abp vnext 多语言通过数据库动态管理

通过数据库加载实现动态管理,用户可以自己修改界面显示的文本,满足国际化需求 如图所示,前端使用tdesign vnext 新建表TSYS_Localization与TSYS_LocalizationDetail 国旗图标下载网址flag-icons: Free Country Flags in SVG 在Shared下创建下图3个文件 …

Vue:使用 KeepAlive 缓存切换掉的 component

一、内置特殊元素 不是组件 <component>、<slot> 和 <template> 具有类似组件的特性&#xff0c;也是模板语法的一部分。但它们并非真正的组件&#xff0c;同时在模板编译期间会被编译掉。因此&#xff0c;它们通常在模板中用小写字母书写。 1.1 <compone…

Spring中每次访问数据库都要创建SqlSession吗?

一、SqlSession是什么二、源码分析1&#xff09;mybatis获取Mapper流程2&#xff09;Spring创建Mapper接口的代理对象流程3&#xff09;MapperFactoryBean#getObject调用时机4&#xff09;SqlSessionTemplate创建流程5&#xff09;SqlSessionInterceptor拦截逻辑6&#xff09;开…

【数据结构】填空集

基本术语 顺序队列在实现的时候&#xff0c;通常将数组看成是一个首尾相连的循环队列&#xff0c;这样做的目的是为避免产生&#xff08;溢出&#xff09;现象 数组q[M]&#xff08;M等于6&#xff09;存储一个循环队&#xff0c;first和last分别指向首尾指针。已知first2,la…

【趣味升级版】斗破苍穹修炼文字游戏HTML,CSS,JS

目录 图片展示 开始游戏 手动升级&#xff08;满100%即可升级&#xff09; 升级完成&#xff0c;即可解锁打怪模式 新增功能说明&#xff1a; 如何操作&#xff1a; 完整代码 实现一个简单的斗破苍穹修炼文字游戏&#xff0c;你可以使用HTML、CSS和JavaScript结合来构建…

【在Linux世界中追寻伟大的One Piece】多线程(三)

目录 1 -> Linux线程同步 1.1 -> 条件变量 1.2 -> 同步概念与竞态条件 1.3 -> 条件变量函数 1.4 -> 为什么pthread_cond_wait需要互斥量 1.5 -> 条件变量使用规范 2 -> 生产者消费者模型 2.1 -> 为什么要使用生产者消费者模型 2.2 -> 生产…

AI数据分析工具(一)

Looker Studio&#xff08;谷歌&#xff09;-免费 优点 免费使用&#xff1a;对于中小型企业和个人用户来说&#xff0c;没有任何费用压力&#xff0c;可以免费享受到数据可视化和报表创建的功能。与Google服务集成&#xff1a;特别适合使用Google产品生态的企业&#xff0c;…

个人博客接入github issue风格的评论,utteranc,gitment

在做个人博客的时候&#xff0c;如果你需要评论功能&#xff0c;但是又不想构建用户体系和评论模块&#xff0c;那么可以直接使用github的issue提供的接口&#xff0c;对应的开源项目有utteranc和gitment&#xff0c;尤其是前者。 它们的原理是一样的&#xff1a;在博客文章下…

springboot 配置跨域访问

什么是 CORS&#xff1f; CORS&#xff0c;全称是“跨源资源共享”&#xff08;Cross-Origin Resource Sharing&#xff09;&#xff0c;是一种Web应用程序的安全机制&#xff0c;用于控制不同源的资源之间的交互。 在Web应用程序中&#xff0c;CORS定义了一种机制&#xff0…

探索Python WebSocket新境界:picows库揭秘

文章目录 探索Python WebSocket新境界&#xff1a;picows库揭秘第一部分&#xff1a;背景介绍第二部分&#xff1a;picows库概述第三部分&#xff1a;安装picows库第四部分&#xff1a;简单库函数使用方法第五部分&#xff1a;场景应用第六部分&#xff1a;常见Bug及解决方案第…

【Linux】-学习笔记06

第二章、时间同步服务器 2.1时间同步服务器的使用 2.1.1系统时区时间的管理 timedatectl set-time "2024-02-13 10:41:55" ##设定系统时间 timedatectl list-timezones ##显示系统的所有时区 timedatectl set-timezone "Asia/Shangh…

Mac使用charles抓包

一、官网下载安装 二、配置Help--->SSL Proxying 有证书选择全部信任即可 三、设置系统代理&#xff0c;mac每次重启都需要选择&#xff0c;否则会没有数据 四、设置端口&#xff08;如果无法获取https&#xff09; 五、手机链接&#xff0c;从网页下载证书保存到手机&…

3d扫描建模产品开发-三维扫描检测蓝光检测

现当下&#xff0c;汽车制造、航空航天&#xff0c;还是消费电子、医疗器械&#xff0c;三维扫描检测与蓝光技术正以前所未有的精度和效率&#xff0c;推动着产品从概念到实物的快速转化。 三维扫描技术&#xff0c;简而言之&#xff0c;就是通过激光、结构光&#xff08;如蓝…

Hive中的基本数据类型和表的类型

Hive支持关系数据库中大多数据基本数据类型&#xff0c;同时还支持三种复杂类型。 示例&#xff1a; Hive表 创建表 – 直接建表法 create table t_page_view ( page_id bigint comment ‘页面ID’, page_name string comment ‘页面名称’, page_url string comment ‘页面…

Python PDF转JPG图片小工具

Python PDF转JPG图片小工具 1.简介 将单个pdf装换成jpg格式图片 Tip: 1、软件窗口默认最前端&#xff0c;不支持调整窗口大小&#xff1b; 2、可通过按钮选择PDF文件&#xff0c;也可以直接拖拽文件到窗口&#xff1b; 3、转换质量有5个档位&#xff0c;&#xff08;0.25&a…

剖析 SpringBoot 于夕阳红公寓管理系统架构搭建的核心作用

3 系统分析 本文作者在确定了研究的课题之后&#xff0c;从各大数字图书馆下载文献来阅读&#xff0c;并了解同类型的网站具备的大致功能&#xff0c;然后与本系统用户的实际需求结合进行分析&#xff0c;得出本系统要研究的具体功能与性能。虽然分析系统这一阶段性工作主要是确…

springboot336社区物资交易互助平台pf(论文+源码)_kaic

毕 业 设 计&#xff08;论 文&#xff09; 社区物资交易互助平台设计与实现 摘 要 传统办法管理信息首先需要花费的时间比较多&#xff0c;其次数据出错率比较高&#xff0c;而且对错误的数据进行更改也比较困难&#xff0c;最后&#xff0c;检索数据费事费力。因此&#xff…

嵌入式linux系统中网络编程的具体实现

1.网络编程简介 要编写通过计算机网络通信的程序,首先要确定这些程序同通信的协议(protocol),在设计一个协议的细节之前,首先要分清程序是由哪个程序发起以及响应何时产生。 举例来说,一般认为WEB服务器程序是一个长时间运行的程序(守护进程deamon),它只在响应来自网…