当前位置: 首页 > news >正文

图像处理之hough圆形检测

hough检测原理

点击图像处理之Hough变换检测直线查看
下面直接描述检测圆形的方法

基于Hough变换的圆形检测方法

对于一个半径为 r r r,圆心为 ( a , b ) (a,b) a,b的圆,我们将其表示为:
( x − a ) 2 + ( y − b ) 2 = r 2 (x-a)^2+(y-b)^2=r^2 (xa)2+(yb)2=r2
此时 x = [ x , y ] T , a = [ a , b , r ] T x=[x,y]^T,a=[a,b,r]^T x=[x,y]Ta=[a,b,r]T,其参数空间为三维。显然,图像空间上的一点 ( x , y ) (x,y) x,y,在参数空间中对应着一个圆锥,如下图所示。
在这里插入图片描述
而图像空间的一个圆就对应着这一簇圆锥相交的一个点,这个特定点在参数空间的三维参数一定,就表示一定半径一定圆心坐标的图像空间的那个圆。
上述方法是经典的Hough圆检测方法的原理,它具有精度高,抗干扰能力强等优点,但由于该方法的参数空间为三维,要在三维空间上进行证据累计的话,需要的时间和空间都是庞大的,在实际应用中不适用。为加快Hough变换检测圆的速度,学者们进行了大量研究,也出现了很多改进的Hough变换检测圆的方法。如利用图像梯度信息的Hough变换,对圆的标准方程对x求导得到下式:
2 ( x − a ) + 2 ( y − b ) d y d x = 0 2(x-a)+2(y-b)\frac{dy}{dx}=0 2(xa)+2(yb)dxdy=0
从上式看出,此时的参数空间从半径 r r r,圆心 ( a , b ) (a,b) a,b三维,变成了只有圆心 ( a , b ) (a,b) a,b的二维空间,利用这种方法检测圆其计算量明显减少了。
但这种改进的Hough变换检测圆的方法其检测精度并不高,原因在于,此种方法利用了边界斜率。
从本质上讲,边界斜率其实是用曲线在某一点的弦的斜率来代替的,这种情况下,要保证不存在误差,只有在弦长为零的情况。但在数字图像中,曲线的表现形式是离散的,其在某一点处的斜率指的是此点右向n步斜率或是左向n步斜率。如果弦长过小了,斜率的量化误差就会增大。这种方法比较适用于干扰较少的完整圆形目标。
在这里插入图片描述

主要代码:

def AHTforCircles(edge,center_threhold_factor = None,score_threhold = None,min_center_dist = None,minRad = None,maxRad = None,center_axis_scale = None,radius_scale = None,halfWindow = None,max_circle_num = None):if center_threhold_factor == None:center_threhold_factor = 10.0if score_threhold == None:score_threhold = 15.0if min_center_dist == None:min_center_dist = 80.0if minRad == None:minRad = 0.0if maxRad == None:maxRad = 1e7*1.0if center_axis_scale == None:center_axis_scale = 1.0if radius_scale == None:radius_scale = 1.0if halfWindow == None:halfWindow = 2if max_circle_num == None:max_circle_num = 6min_center_dist_square = min_center_dist**2sobel_kernel_y = np.array([[-1.0, -2.0, -1.0], [0.0, 0.0, 0.0], [1.0, 2.0, 1.0]])sobel_kernel_x = np.array([[-1.0, 0.0, 1.0], [-2.0, 0.0, 2.0], [-1.0, 0.0, 1.0]])edge_x = convolve(sobel_kernel_x,edge,[1,1,1,1],[1,1])edge_y = convolve(sobel_kernel_y,edge,[1,1,1,1],[1,1])center_accumulator = np.zeros((int(np.ceil(center_axis_scale*edge.shape[0])),int(np.ceil(center_axis_scale*edge.shape[1]))))k = np.array([[r for c in range(center_accumulator.shape[1])] for r in range(center_accumulator.shape[0])])l = np.array([[c for c in range(center_accumulator.shape[1])] for r in range(center_accumulator.shape[0])])minRad_square = minRad**2maxRad_square = maxRad**2points = [[],[]]edge_x_pad = np.pad(edge_x,((1,1),(1,1)),'constant')edge_y_pad = np.pad(edge_y,((1,1),(1,1)),'constant')Gaussian_filter_3 = 1.0 / 16 * np.array([(1.0, 2.0, 1.0), (2.0, 4.0, 2.0), (1.0, 2.0, 1.0)])for i in range(edge.shape[0]):for j in range(edge.shape[1]):if not edge[i,j] == 0:dx_neibor = edge_x_pad[i:i+3,j:j+3]dy_neibor = edge_y_pad[i:i+3,j:j+3]dx = (dx_neibor*Gaussian_filter_3).sum()dy = (dy_neibor*Gaussian_filter_3).sum()if not (dx == 0 and dy == 0):t1 = (k/center_axis_scale-i)t2 = (l/center_axis_scale-j)t3 = t1**2 + t2**2temp = (t3 > minRad_square)&(t3 < maxRad_square)&(np.abs(dx*t1-dy*t2) < 1e-4)center_accumulator[temp] += 1points[0].append(i)points[1].append(j)M = center_accumulator.mean()for i in range(center_accumulator.shape[0]):for j in range(center_accumulator.shape[1]):neibor = \center_accumulator[max(0, i - halfWindow + 1):min(i + halfWindow, center_accumulator.shape[0]),max(0, j - halfWindow + 1):min(j + halfWindow, center_accumulator.shape[1])]if not (center_accumulator[i,j] >= neibor).all():center_accumulator[i,j] = 0# 非极大值抑制plt.imshow(center_accumulator,cmap='gray')plt.axis('off')plt.show()center_threshold = M * center_threhold_factorpossible_centers = np.array(np.where(center_accumulator > center_threshold))  # 阈值化sort_centers = []for i in range(possible_centers.shape[1]):sort_centers.append([])sort_centers[-1].append(possible_centers[0,i])sort_centers[-1].append(possible_centers[1,i])sort_centers[-1].append(center_accumulator[sort_centers[-1][0],sort_centers[-1][1]])sort_centers.sort(key=lambda x:x[2],reverse=True)centers = [[],[],[]]points = np.array(points)for i in range(len(sort_centers)):radius_accumulator = np.zeros((int(np.ceil(radius_scale * min(maxRad, np.sqrt(edge.shape[0] ** 2 + edge.shape[1] ** 2)) + 1))),dtype=np.float32)if not len(centers[0]) < max_circle_num:breakiscenter = Truefor j in range(len(centers[0])):d1 = sort_centers[i][0]/center_axis_scale - centers[0][j]d2 = sort_centers[i][1]/center_axis_scale - centers[1][j]if d1**2 + d2**2 < min_center_dist_square:iscenter = Falsebreakif not iscenter:continuetemp = np.sqrt((points[0,:] - sort_centers[i][0] / center_axis_scale) ** 2 + (points[1,:] - sort_centers[i][1] / center_axis_scale) ** 2)temp2 = (temp > minRad) & (temp < maxRad)temp = (np.round(radius_scale * temp)).astype(np.int32)for j in range(temp.shape[0]):if temp2[j]:radius_accumulator[temp[j]] += 1for j in range(radius_accumulator.shape[0]):if j == 0 or j == 1:continueif not radius_accumulator[j] == 0:radius_accumulator[j] = radius_accumulator[j]*radius_scale/np.log(j) #radius_accumulator[j]*radius_scale/jscore_i = radius_accumulator.argmax(axis=-1)if radius_accumulator[score_i] < score_threhold:iscenter = Falseif iscenter:centers[0].append(sort_centers[i][0]/center_axis_scale)centers[1].append(sort_centers[i][1]/center_axis_scale)centers[2].append(score_i/radius_scale)centers = np.array(centers)centers = centers.astype(np.float64)return centers

代码效果:
在这里插入图片描述
在这里插入图片描述

全部代码可见本人GitHub仓库,如果代码有用,please click star and watching
hough检测之前需要canny算子检测基础的边缘,点击这里可以查看有关canny算法相关内容

如果本文对你有帮助,关注加点赞!!!!!

相关文章:

图像处理之hough圆形检测

hough检测原理 点击图像处理之Hough变换检测直线查看 下面直接描述检测圆形的方法 基于Hough变换的圆形检测方法 对于一个半径为 r r r&#xff0c;圆心为 &#xff08; a , b &#xff09; &#xff08;a,b&#xff09; &#xff08;a,b&#xff09;的圆&#xff0c;我们将…...

el-upload文件上传(只能上传一个文件且再次上传替换上一个文件) vue3+vite+ts

组件&#xff1a; <template><el-upload class"upload-demo" v-model:file-list"fileList" ref"uploadDemo" action"/public-api/api/file" multiple:on-preview"handlePreview" :on-remove"handleRemove&quo…...

随手笔记——根据点对来估计相机的运动综述

随手笔记——根据点对来估计相机的运动综述 说明计算相机运动 说明 简单介绍3种情况根据点对来估计相机运动所使用的方法 计算相机运动 有了匹配好的点对&#xff0c;接下来&#xff0c;要根据点对来估计相机的运动。这里由于相机的原理不同分为&#xff1a; 当相机为单目时…...

ip校园广播音柱特点

ip校园广播音柱特点IP校园广播音柱是一种基于IP网络技术的音频播放设备&#xff0c;广泛应用于校园、商业区、公共场所等地方。它可以通过网络将音频信号传输到不同的音柱设备&#xff0c;实现远程控制和集中管理。IP校园广播音柱具备以下特点和功能&#xff1a;1. 网络传输&am…...

用 Node.js 手写 WebSocket 协议

目录 引言 从 http 到 websocekt 的切换 Sec-WebSocket-Key 与 Sec-WebSocket-Accept 全新的二进制协议 自己实现一个 websocket 服务器 按照协议格式解析收到的Buffer 取出opcode 取出MASK与payload长度 根据mask key读取数据 根据类型处理数据 frame 帧 数据的发…...

Xilinx AXI VIP使用教程

AXI接口虽然经常使用&#xff0c;很多同学可能并不清楚Vivado里面也集成了AXI的Verification IP&#xff0c;可以当做AXI的master、pass through和slave&#xff0c;本次内容我们看下AXI VIP当作master时如何使用。 新建Vivado工程&#xff0c;并新建block design&#xff0c;命…...

mysql主主架构搭建,删库恢复

mysql主主架构搭建&#xff0c;删库恢复 搭建mysql主主架构环境信息安装msql服务mysql1mysql2设置mysql2同步mysql1设置mysql1同步mysql2授权测试用账户 安装配置keepalivedmysql1检查脚本mysql2检查脚本 备份策略mysqldump全量备份mysqldump增量备份数据库目录全量备份 删除my…...

pythonweek1

引言 做任何事情都要脚踏实地&#xff0c;虽然大一上已经学习了python的基础语法&#xff0c;大一下也学习了C加加中的类与对象&#xff0c;但是自我觉得基础还不太扎实&#xff0c;又害怕有什么遗漏&#xff0c;所以就花时间重新学习了python的基础&#xff0c;学习Python的基…...

进程虚拟地址空间区域划分

目录 图示 详解 代码段 备注&#xff1a;x86 32位linux环境下&#xff0c;进程虚拟地址空间区域划分 图示 详解 用户空间 用于存储用户进程代码和数据&#xff0c;只能由用户进程访问 内核空间 用于存储操作系统内核代码和数据&#xff0c;只能由操作系统内核访问 text t…...

OpenAI Code Interpreter 的开源实现:GPT Code UI

本篇文章聊聊 OpenAI Code Interpreter 的一众开源实现方案中&#xff0c;获得较多支持者&#xff0c;但暂时还比较早期的项目&#xff1a;GPT Code UI。 写在前面 这篇文章本该更早的时候发布&#xff0c;但是 LLaMA2 发布后实在心痒难忍&#xff0c;于是就拖了一阵。结合 L…...

macOS Ventura 13.5 (22G74) 正式版发布,ISO、IPSW、PKG 下载

macOS Ventura 13.5 (22G74) 正式版发布&#xff0c;ISO、IPSW、PKG 下载 本站下载的 macOS Ventura 软件包&#xff0c;既可以拖拽到 Applications&#xff08;应用程序&#xff09;下直接安装&#xff0c;也可以制作启动 U 盘安装&#xff0c;或者在虚拟机中启动安装。另外也…...

Electron 主进程和渲染进程传值及窗口间传值

1 渲染进程调用主进程得方法 下面是渲染进程得代码: let { ipcRenderer} require( electron ); ipcRenderer.send( xxx ); //渲染进程中调用 下面是主进程得代码: var { ipcMain } require( electron ); ipcMain.on("xxx",function () { } )...

C#设计模式之---建造者模式

建造者模式&#xff08;Builder Pattern&#xff09; 建造者模式&#xff08;Builder Pattern&#xff09;是将一个复杂对象的构建与它的表示分离&#xff0c;使得同样的构建过程可以创建不同的表示。建造者模式使得建造代码与表示代码的分离&#xff0c;可以使客户端不必知道…...

output delay 约束

output delay 约束 一、output delay约束概述二、output delay约束系统同步三、output delay约束源同步 一、output delay约束概述 特别注意&#xff1a;在源同步接口中&#xff0c;定义接口约束之前&#xff0c;需要用create_generated_clock 先定义送出的随路时钟。 二、out…...

html2Canvas+jsPDF 下载PDF 遇到跨域的对象存储的图片无法显示

一、问题原因 对象存储的域名和你网址的域名不一样&#xff0c;此时用Canvas相关插件 将DOM元素转化为PDF&#xff0c;就会出现跨域错误。 二、解决办法 两步 1. 图片元素上设置属性 crossorigin"anonymous" 支持原生img和eleme组件 2. 存储桶设置资源跨域访问…...

【C#】并行编程实战:异步流

本来这章该讲的是 ASP .NET Core 中的 IIS 和 Kestrel &#xff0c;但是我看了下这个是给服务器用的。而我只是个 Unity 客户端程序&#xff0c;对于服务器的了解趋近于零。 鉴于我对服务器知识和需求的匮乏&#xff0c;这里就不讲原书&#xff08;大部分&#xff09;内容了。本…...

在家下载论文使用哪些论文下载工具比较好

在家下载论文如果不借助论文下载工具是非常艰难的事情&#xff0c;因为很多查找下载论文的数据库都是需要账号权限才可使用的。 例如&#xff0c;我们查找中文论文常用的知网、万方等数据库以及众多国外论文数据库。 在家下载知网、万方数据库论文可用下面的方法&#xff1a;…...

【LeetCode 算法】Handling Sum Queries After Update 更新数组后处理求和查询-Segment Tree

文章目录 Handling Sum Queries After Update 更新数组后处理求和查询问题描述&#xff1a;分析代码线段树 Tag Handling Sum Queries After Update 更新数组后处理求和查询 问题描述&#xff1a; 给你两个下标从 0 开始的数组 n u m s 1 和 n u m s 2 nums1 和 nums2 nums1…...

基于Linux操作系统中的MySQL数据库SQL语句(三十一)

MySQL数据库SQL语句 目录 一、SQL语句类型 1、DDL 2、DML 3、DCL 4、DQL 二、数据库操作 1、查看 2、创建 2.1、默认字符集 2.2、指定字符集 3、进入 4、删除 5、更改 6、练习 三、数据表操作 &#xff08;一&#xff09;数据类型 1、数值类型 1.1、TINYINT …...

【Matlab】基于BP神经网络的数据回归预测新数据(Excel可直接替换数据)

【Matlab】基于BP神经网络的数据回归预测新数据(Excel可直接替换数据) 1.模型原理2.数学公式3.文件结构4.Excel数据5.分块代码5.1 main.m5.2 NewData.m6.完整代码6.1 main.m6.2 NewData.m7.运行结果1.模型原理 基于BP神经网络的数据回归预测是一种常见的机器学习方法,用于处…...

SpringBoot-17-MyBatis动态SQL标签之常用标签

文章目录 1 代码1.1 实体User.java1.2 接口UserMapper.java1.3 映射UserMapper.xml1.3.1 标签if1.3.2 标签if和where1.3.3 标签choose和when和otherwise1.4 UserController.java2 常用动态SQL标签2.1 标签set2.1.1 UserMapper.java2.1.2 UserMapper.xml2.1.3 UserController.ja…...

第19节 Node.js Express 框架

Express 是一个为Node.js设计的web开发框架&#xff0c;它基于nodejs平台。 Express 简介 Express是一个简洁而灵活的node.js Web应用框架, 提供了一系列强大特性帮助你创建各种Web应用&#xff0c;和丰富的HTTP工具。 使用Express可以快速地搭建一个完整功能的网站。 Expre…...

OpenLayers 可视化之热力图

注&#xff1a;当前使用的是 ol 5.3.0 版本&#xff0c;天地图使用的key请到天地图官网申请&#xff0c;并替换为自己的key 热力图&#xff08;Heatmap&#xff09;又叫热点图&#xff0c;是一种通过特殊高亮显示事物密度分布、变化趋势的数据可视化技术。采用颜色的深浅来显示…...

Mac下Android Studio扫描根目录卡死问题记录

环境信息 操作系统: macOS 15.5 (Apple M2芯片)Android Studio版本: Meerkat Feature Drop | 2024.3.2 Patch 1 (Build #AI-243.26053.27.2432.13536105, 2025年5月22日构建) 问题现象 在项目开发过程中&#xff0c;提示一个依赖外部头文件的cpp源文件需要同步&#xff0c;点…...

CVE-2020-17519源码分析与漏洞复现(Flink 任意文件读取)

漏洞概览 漏洞名称&#xff1a;Apache Flink REST API 任意文件读取漏洞CVE编号&#xff1a;CVE-2020-17519CVSS评分&#xff1a;7.5影响版本&#xff1a;Apache Flink 1.11.0、1.11.1、1.11.2修复版本&#xff1a;≥ 1.11.3 或 ≥ 1.12.0漏洞类型&#xff1a;路径遍历&#x…...

算法:模拟

1.替换所有的问号 1576. 替换所有的问号 - 力扣&#xff08;LeetCode&#xff09; ​遍历字符串​&#xff1a;通过外层循环逐一检查每个字符。​遇到 ? 时处理​&#xff1a; 内层循环遍历小写字母&#xff08;a 到 z&#xff09;。对每个字母检查是否满足&#xff1a; ​与…...

iview框架主题色的应用

1.下载 less要使用3.0.0以下的版本 npm install less2.7.3 npm install less-loader4.0.52./src/config/theme.js文件 module.exports {yellow: {theme-color: #FDCE04},blue: {theme-color: #547CE7} }在sass中使用theme配置的颜色主题&#xff0c;无需引入&#xff0c;直接可…...

(一)单例模式

一、前言 单例模式属于六大创建型模式,即在软件设计过程中,主要关注创建对象的结果,并不关心创建对象的过程及细节。创建型设计模式将类对象的实例化过程进行抽象化接口设计,从而隐藏了类对象的实例是如何被创建的,封装了软件系统使用的具体对象类型。 六大创建型模式包括…...

【堆垛策略】设计方法

堆垛策略的设计是积木堆叠系统的核心&#xff0c;直接影响堆叠的稳定性、效率和容错能力。以下是分层次的堆垛策略设计方法&#xff0c;涵盖基础规则、优化算法和容错机制&#xff1a; 1. 基础堆垛规则 (1) 物理稳定性优先 重心原则&#xff1a; 大尺寸/重量积木在下&#xf…...

云原生周刊:k0s 成为 CNCF 沙箱项目

开源项目推荐 HAMi HAMi&#xff08;原名 k8s‑vGPU‑scheduler&#xff09;是一款 CNCF Sandbox 级别的开源 K8s 中间件&#xff0c;通过虚拟化 GPU/NPU 等异构设备并支持内存、计算核心时间片隔离及共享调度&#xff0c;为容器提供统一接口&#xff0c;实现细粒度资源配额…...