opencv - py_imgproc - py_houghlines and py_houghcircles 霍夫线和圆变换

news2024/11/24 15:54:31

文章目录

  • 1.霍夫线变换
    • 目标
    • 理论
  • OpenCV 中的霍夫变换
    • 概率霍夫变换
    • 其他资源
  • 2.霍夫圆变换
    • 目标
    • 理论

1.霍夫线变换

目标

在本章中,

  • 我们将了解霍夫变换的概念。
  • 我们将了解如何使用它来检测图像中的线条。
  • 我们将看到以下函数:cv.HoughLines()cv.HoughLinesP()

理论

如果您可以用数学形式表示形状,霍夫变换是一种检测任何形状的流行技术。即使形状有一点损坏或扭曲,它也可以检测到形状。我们将看到它如何适用于一条线。

一条直线可以表示为 y = m x + c y = mx+c y=mx+c,也可以表示为参数形式,即 ρ = x cos ⁡ θ + y sin ⁡ θ \rho = x \cos \theta + y \sin \theta ρ=xcosθ+ysinθ,其中 ρ \rho ρ 是从原点到直线的垂直距离, θ \theta θ 是这条垂直线与水平轴形成的夹角,逆时针测量(该方向取决于您如何表示坐标系。此表示法用于 OpenCV)。查看下图:

在这里插入图片描述

因此,如果直线从原点下方经过,则其 rho 为正,角度小于 180。如果直线从原点上方经过,则角度将小于 180,而不是大于 180,并且 rho 为负。任何垂直线的 rho 为 0 度,水平线的 rho 为 90 度。

现在让我们看看霍夫变换如何对直线起作用。任何直线都可以用这两个项表示, ( ρ , θ ) (\rho, \theta) (ρ,θ)。因此,它首先创建一个 2D 数组或累加器(用于保存两个参数的值),并且最初将其设置为 0。让行表示 ρ \rho ρ,让列表示 θ \theta θ。数组的大小取决于您需要的精度。假设您希望角度的精度为 1 度,则需要 180 列。对于 ρ \rho ρ,可能的最大距离是图像的对角线长度。因此,以一个像素为精度,行数可以是图像的对角线长度。

考虑一个 100x100 的图像,中间有一条水平线。取该线的第一个点。您知道它的 (x,y) 值。现在在线方程中,输入值 θ = 0 , 1 , 2 , . . . . , 180 \theta = 0,1,2,....,180 θ=0,1,2,....,180 并检查您得到的 ρ \rho ρ。对于每个 ( ρ , θ ) (\rho, \theta) (ρ,θ) 对,您将累加器中其对应的 ( ρ , θ ) (\rho, \theta) (ρ,θ) 单元中的值增加一。因此现在在累加器中,单元 (50,90) = 1 以及一些其他单元。

现在取线上的第二个点。执行与上述相同的操作。增加单元格中与你得到的 (rho, theta) 对应的值。这次,单元格 (50,90) = 2。你实际上做的是投票 ( ρ , θ ) (\rho, \theta) (ρ,θ) 值。你对线上的每个点继续此过程。在每个点,单元格 (50,90) 将增加或投票,而其他单元格可能会或可能不会被投票。这样,最后,单元格 (50,90) 将获得最高票数。因此,如果你在累加器中搜索最高票数,你将获得值 (50,90),它表示,此图像中有一条线,距离原点 50 度,角度为 90 度。下面的动画很好地显示了这一点(图片来源:Amos Storkey )

在这里插入图片描述

这就是霍夫变换对线的工作原理。它很简单,也许你可以自己用 Numpy 实现它。下面是一张显示累加器的图像。某些位置的亮点表示它们是图像中可能的线的参数。(图片来源:维基百科 )

在这里插入图片描述

OpenCV 中的霍夫变换

以上解释的所有内容都封装在 OpenCV 函数 cv.HoughLines() 中。它只是返回一个 :math:(rho,
theta)` 值的数组。 ρ \rho ρ 以像素为单位, θ \theta θ 以弧度为单位。第一个参数,输入图像应该是二值图像,因此在应用霍夫变换之前应用阈值或使用 Canny 边缘检测。第二个和第三个参数分别是 ρ \rho ρ θ \theta θ 精度。第四个参数是阈值,这意味着它应该获得的最小投票数被视为一条线。请记住,投票数取决于线上的点数。因此它表示应该检测到的线的最小长度。
@include hough_line_transform.py
检查以下结果:

在这里插入图片描述

概率霍夫变换

在霍夫变换中,你可以看到,即使对于具有两个参数的线,也需要大量的计算。概率霍夫变换是我们看到过的霍夫变换的优化。它不会考虑所有点。相反,它只采用足以进行线检测的随机点子集。我们只需降低阈值即可。参见下图,其中比较了霍夫空间中的霍夫变换和概率霍夫变换。(图片来源:Franck Bettinger 的主页)

在这里插入图片描述

OpenCV 实现基于 Matas, J. 和 Galambos, C. 以及 Kittler, J.V. @cite Matas00 的“使用渐进概率霍夫变换进行稳健的直线检测”。使用的函数是 cv.HoughLinesP()。它有两个新参数。

  • minLineLength - 直线的最小长度。短于此长度的线段将被拒绝。
  • maxLineGap - 允许的线段间最大间隙,以将它们视为一条直线。

最好的是,它直接返回直线的两个端点。在前一种情况下,您只获得直线的参数,并且必须找到所有点。在这里,一切都直接而简单。
@include probabilistic_hough_line_transform.py
查看以下结果:

在这里插入图片描述

其他资源

  • 维基百科上的霍夫变换

2.霍夫圆变换

目标

在本章中,

  • 我们将学习使用霍夫变换在图像中查找圆。
  • 我们将看到这些函数:cv.HoughCircles()

理论

圆在数学上表示为 ( x − x c e n t e r ) 2 + ( y − y c e n t e r ) 2 = r 2 (x-x_{center})^2 + (y - y_{center})^2 = r^2 (xxcenter)2+(yycenter)2=r2,其中 ( x c e n t e r , y c e n t e r ) (x_{center},y_{center}) (xcenter,ycenter) 是圆的中心, r r r 是圆的半径。从等式中,我们可以看到我们有 3 个参数,所以我们需要一个用于霍夫变换的 3D 累加器,这将非常低效。因此,OpenCV 使用更棘手的方法,即Hough 梯度法,它使用边缘的梯度信息。

我们在这里使用的函数是cv.HoughCircles()。它有很多参数,文档中对此进行了很好的解释。所以我们直接看代码。

import numpy as np
import cv2 as cv

img = cv.imread('opencv-logo-white.png',0)
img = cv.medianBlur(img,5)
cimg = cv.cvtColor(img,cv.COLOR_GRAY2BGR)

circles = cv.HoughCircles(img,cv.HOUGH_GRADIENT,1,20,
                            param1=50,param2=30,minRadius=0,maxRadius=0)

circles = np.uint16(np.around(circles))
for i in circles[0,:]:
    # draw the outer circle
    cv.circle(cimg,(i[0],i[1]),i[2],(0,255,0),2)
    # draw the center of the circle
    cv.circle(cimg,(i[0],i[1]),2,(0,0,255),3)

cv.imshow('detected circles',cimg)
cv.waitKey(0)
cv.destroyAllWindows()

查看以下结果:
在这里插入图片描述

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

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

相关文章

数据结构 ——— 用堆解决TOP-K问题

目录 何为TOP-K问题 用堆解决TOP-K问题 代码实现 何为TOP-K问题 比如:整个专业的前10名,世界500强,富豪榜,游戏中前100的活跃玩家等 对于 TOP-K 问题,能想到的最简单直接的方式就是排序 但是,如果数据…

开发之翼:划时代的原生鸿蒙应用市场开发者服务

前言 随着"纯血鸿蒙" HarmonyOS NEXT在原生鸿蒙之夜的正式发布,鸿蒙生态正以前所未有的速度蓬勃发展。据知已有超过15000个鸿蒙原生应用和元服务上架,覆盖18个行业,通用办公应用覆盖全国3800万多家企业。原生鸿蒙操作系统降低了接…

WAF+AI结合,雷池社区版的强大防守能力

网上攻击无处不不在,为了保护我自己的网站,搜索安装了一个开源免费的WAF 刚安装完成就收到了海外的攻击,看到是海外的自动化攻击工具做的 雷池刚好也有AI分析,于是就尝试使用这个功能,看看这个ai能力到底怎么样 以下…

Elasticsearch —— ES 环境搭建、概念、基本操作、文档操作、SpringBoot继承ES

文章中会用到的文件,如果官网下不了可以在这下 链接: https://pan.baidu.com/s/1SeRdqLo0E0CmaVJdoZs_nQ?pwdxr76 提取码: xr76 一、 ES 环境搭建 注:环境搭建过程中的命令窗口不能关闭,关闭了服务就会关闭(除了修改设置后重启的…

CSP2024 游记

又是一年 CSP。。。 10 月 5 日,终于过 S 初赛了。。。 然后开始漫长的备战。。 在考试开始前 1 day,我还在兢兢业业地学习图论。然后发现没有考。。。 10 月 25 日下午 15:30,来到 CQBS 试机。我想,怎么测试性能呢&#xff1…

opencv - py_imgproc - py_grabcut GrabCut 算法提取前景

文章目录 使用 GrabCut 算法进行交互式前景提取目标理论演示 使用 GrabCut 算法进行交互式前景提取 目标 在本章中 我们将了解 GrabCut 算法如何提取图像中的前景我们将为此创建一个交互式应用程序。 理论 GrabCut 算法由英国剑桥微软研究院的 Carsten Rother、Vladimir K…

视频制作软件新手必备:8款剪辑工具剪辑思路分享!

随着视频的高度发展,视频已成为一种重要的工具,用以学习娱乐、记录生活点滴以及传递各类信息。不论是制作个人MV、进行企业宣传,还是创作短视频内容,拥有一款功能恰当的视频剪辑软件都显得至关重要。对于初学者而言,选…

无人机避障——路径规划篇(一) JPS跳点搜索算法A*算法对比

JSP 跳点搜索算法与改进 A*算法对比 一、算法概述: 跳点搜索(Jump Point Search,JPS)算法:一种用于路径规划的启发式搜索算法。它主要用于在网格地图(如游戏地图、机器人运动规划地图等)中快速找到从起点到终点的最短路径。该算法在改进 A*算法的基础上进行了优化,通过跳过一…

解决Linux安装Anaconda后出现的conda: command not found问题

参考链接:解决Linux安装Anaconda后出现的conda: command not found问题-百度开发者中心

AI直播带货场景切换模块的搭建!

AI直播带货,作为电商领域的新宠,正以其独特的魅力和高效的营销手段,引领着销售模式的新变革。 在AI直播带货中,场景切换模块是不可或缺的一部分,它不仅能够提升观众的观看体验,还能更好地展示商品&#xf…

15 Docker容器存储架构:docker存储驱动简介

文章目录 一、Docker 存储驱动探索1.1 存储驱动1.2 存储驱动方式1.3 非持久化存储1.4 持久化存储一、Docker 存储驱动探索 1.1 存储驱动 Storage driver处理各镜像层及容器层的处理细节,实现了多层数据的堆叠,为用户提供了多层数据合并后的统一视图。 [superman@docker ~]$…

Aicbo:一键生成高质量画作,适合初学者的AI绘画助手

越来越多的智能工具开始进入人们的视野,它们不仅简化了创作流程,还极大地提高了作品的质量。在这一背景下,Aicbo作为一款新兴的AI绘画工具,以其独特的优势和免费试用的政策,迅速获得了广泛的关注和好评。本文将从多个角…

STM32 从0开始系统学习5

目录 STM32 GPIO输入的四种模式 Practice And Usage 练习与封装 Detailed And Reference 更加具体的说明 输入浮空模式 输入上拉模式 输入下拉模式 模拟功能 我们下面聊一聊输入的事情,输入指的是我们的处理器从外部端口接受外设发过来的信号。在我们没有接…

使用Git进行版本控制的最佳实践

文章目录 Git简介基本概念仓库(Repository)提交(Commit)分支(Branching) 常用命令初始化仓库添加文件提交修改查看状态克隆仓库分支操作合并分支推送更改 最佳实践使用有意义的提交信息定期推送至远程仓库使…

冒泡排序和二分查找--go

冒泡排序的逻辑 二分查找的逻辑 func bubbleSort(arr *[5]int){//冒泡排序fmt.Println(*arr)temp : 0for j : len(*arr); j > 0; j-- {for i : 0; i < j-1; i {temp (*arr)[i]if((*arr)[i] > (*arr)[i1]){(*arr)[i] (*arr)[i1](*arr)[i1] temp}}} }func binaryF…

flutter区别于vue的写法

View.dart 页面渲染&#xff1a; 类似于vue里面使用 <template> <div> <span> <textarea>等标签绘制页面, flutter 里面则是使用不同的控件来绘制页面 样式 与传统vue不同的是 flutter里面没有css/scss样式表&#xff0c; Flutter的理念是万物皆…

电影《焚城》全国上映 王丹妮诠释新时代女性力量

今日&#xff0c;电影《焚城》全国上映&#xff0c;该片由刘德华、白宇、莫文蔚和王丹妮主演&#xff0c;以一场由高强度放射性物质铯137泄漏引发的城市灾难为背景&#xff0c;深刻描绘了人们在生死存亡关头的抉择与抗争。 王丹妮在片中饰演飒爽独立、智慧勇敢的消防队长Madam …

uniapp:启动界面关闭时长控制

代码控制关闭启动界面 App启动后不会自动关闭启动界面&#xff0c;需要在代码中调用plus.navigator.closeSplashscreen关闭启动界面。"app-plus" : {"splashscreen" : {"alwaysShowBeforeRender" : false,"autoclose" : false,}, }很多…

Three.js 快速入门构建你的第一个 3D 应用

![ 开发领域&#xff1a;前端开发 | AI 应用 | Web3D | 元宇宙 技术栈&#xff1a;JavaScript、React、Three.js、WebGL、Go 经验经验&#xff1a;6年 前端开发经验&#xff0c;专注于图形渲染和AI技术 开源项目&#xff1a;github 晓智元宇宙、数字孪生引擎、前端面试题 大家好…

二:java 基础知识(2)-- 初始java/语法基础

目录 idea中文插件 第一个 Java 程序 Java数据类型&#xff0c;常量与变量 1. 数据类型 1.1 基本数据类型 1.2 引用数据类型 2. 常量 2.1 特性 2.2 定义常量 ​编辑 3. 变量 3.1 变量的定义与初始化 3.2 变量的类型 局部变量&#xff1a;在方法内声明的变量&#xff0…