c/c++的opencv霍夫变换
OpenCV中的霍夫变换 (C/C++) Hough Transform
霍夫变换 (Hough Transform) 是一种在图像分析中用于检测几何形状(如直线、圆形等)的特征提取技术。它通过一种投票机制在参数空间中寻找特定形状的实例。OpenCV 库为 C++ 开发者提供了强大且易用的霍夫变换函数。
1. 霍夫直线变换 (Hough Line Transform) 📏
霍夫直线变换用于检测图像中的直线。其基本思想是将图像空间中的点映射到参数空间(通常是极坐标 ( ρ , θ ) (\rho, \theta) (ρ,θ) 空间),并在参数空间中寻找峰值,这些峰值对应于图像空间中的直线。
直线方程: ρ = x cos θ + y sin θ \rho = x \cos\theta + y \sin\theta ρ=xcosθ+ysinθ
其中:
- ρ \rho ρ (rho) 是从原点到直线的垂直距离。
- θ \theta θ (theta) 是这条垂直线与 x 轴之间的角度。
1.1 标准霍夫变换 (Standard Hough Transform - SHT)
cv::HoughLines
函数实现了标准霍夫变换。它返回一个包含 ( ρ , θ ) (\rho, \theta) (ρ,θ) 对的向量。
函数原型:
void cv::HoughLines(cv::InputArray image, // 输入图像 (必须是8位单通道二值图像,通常是Canny边缘检测的输出)cv::OutputArray lines, // 输出向量,存储检测到的直线的参数 (cv::Vec2f 表示 rho 和 theta)double rho, // rho 的累加器分辨率 (以像素为单位)double theta, // theta 的累加器分辨率 (以弧度为单位)int threshold, // 累加器阈值参数,只有累加值大于该阈值的直线才会被检测到double srn = 0, // 对于多尺度霍夫变换,它是 rho 的除数。如果为0,则使用经典霍夫变换。double stn = 0, // 对于多尺度霍夫变换,它是 theta 的除数。如果为0,则使用经典霍夫变换。double min_theta = 0, // 检测直线的最小角度 (弧度)double max_theta = CV_PI // 检测直线的最大角度 (弧度)
);
主要步骤:
- 边缘检测:通常使用
cv::Canny
。 - 应用
cv::HoughLines
。 - 遍历检测到的直线参数,并在原图上绘制。
示例代码:
#include <opencv2/opencv.hpp>
#include <iostream>
#include <vector>int main() {cv::Mat src = cv::imread("your_image_with_lines.png", cv::IMREAD_GRAYSCALE);if (src.empty()) {std::cerr << "Error: Could not load image." << std::endl;return -1;}cv::Mat edges;cv::Canny(src, edges, 50, 200, 3); // 1. 边缘检测std::vector<cv::Vec2f> lines; // (rho, theta)// 2. 标准霍夫变换cv::HoughLines(edges, lines, 1, CV_PI / 180, 150, 0, 0);cv::Mat color_dst;cv::cvtColor(edges, color_dst, cv::COLOR_GRAY2BGR); // 用于绘制彩色线条// 3. 绘制直线for (size_t i = 0; i < lines.size(); i++) {float rho = lines[i][0], theta = lines[i][1];cv::Point pt1, pt2;double a = cos(theta), b = sin(theta);double x0 = a * rho, y0 = b * rho;pt1.x = cvRound(x0 + 1000 * (-b));pt1.y = cvRound(y0 + 1000 * (a));pt2.x = cvRound(x0 - 1000 * (-b));pt2.y = cvRound(y0 - 1000 * (a));cv::line(color_dst, pt1, pt2, cv::Scalar(0, 0, 255), 1, cv::LINE_AA);}cv::imshow("Source", src);cv::imshow("Detected Lines (Standard Hough)", color_dst);cv::waitKey(0);return 0;
}
1.2 概率霍夫变换 (Progressive Probabilistic Hough Transform - PPHT)
cv::HoughLinesP
函数实现了概率霍夫变换。它是一种更高效的霍夫变换,因为它只对图像中的一个随机子集点进行投票。它还直接返回检测到的线段的两个端点。
函数原型:
void cv::HoughLinesP(cv::InputArray image, // 输入图像 (8位单通道二值图像)cv::OutputArray lines, // 输出向量,存储检测到的线段的端点 (cv::Vec4i 表示 x1, y1, x2, y2)double rho, // rho 的累加器分辨率 (以像素为单位)double theta, // theta 的累加器分辨率 (以弧度为单位)int threshold, // 累加器阈值参数double minLineLength = 0, // 检测线段的最小长度double maxLineGap = 0 // 同一直线上两点之间的最大允许间隙,以将它们连接起来
);
主要步骤:
- 边缘检测:通常使用
cv::Canny
。 - 应用
cv::HoughLinesP
。 - 遍历检测到的线段端点,并在原图上绘制。
示例代码:
#include <opencv2/opencv.hpp>
#include <iostream>
#include <vector>int main() {cv::Mat src = cv::imread("your_image_with_lines.png", cv::IMREAD_COLOR);if (src.empty()) {std::cerr << "Error: Could not load image." << std::endl;return -1;}cv::Mat gray, edges;cv::cvtColor(src, gray, cv::COLOR_BGR2GRAY);cv::Canny(gray, edges, 50, 200, 3); // 1. 边缘检测std::vector<cv::Vec4i> linesP; // (x1, y1, x2, y2)// 2. 概率霍夫变换cv::HoughLinesP(edges, linesP, 1, CV_PI / 180, 80, 50, 10);// 3. 绘制线段for (size_t i = 0; i < linesP.size(); i++) {cv::Vec4i l = linesP[i];cv::line(src, cv::Point(l[0], l[1]), cv::Point(l[2], l[3]), cv::Scalar(0, 0, 255), 2, cv::LINE_AA);}cv::imshow("Source", gray); // 显示灰度图或原彩色图cv::imshow("Detected Lines (Probabilistic Hough)", src);cv::waitKey(0);return 0;
}
2. 霍夫圆变换 (Hough Circle Transform) ⭕
霍夫圆变换用于检测图像中的圆形。圆的方程是 ( x − a ) 2 + ( y − b ) 2 = r 2 (x-a)^2 + (y-b)^2 = r^2 (x−a)2+(y−b)2=r2,其中 ( a , b ) (a,b) (a,b) 是圆心, r r r 是半径。因此,参数空间是三维的。OpenCV 使用一种称为霍夫梯度法 (Hough Gradient Method) 的两阶段算法,它首先检测圆心,然后找到最佳半径。
函数原型:
void cv::HoughCircles(cv::InputArray image, // 输入图像 (8位单通道灰度图像)cv::OutputArray circles, // 输出向量,存储检测到的圆 (cv::Vec3f 表示 x, y, radius 或 cv::Vec4f x, y, radius, votes)int method, // 检测方法,目前仅支持 cv::HOUGH_GRADIENT 和 cv::HOUGH_GRADIENT_ALTdouble dp, // 累加器图像分辨率与输入图像分辨率的反比。例如,如果 dp=1,则累加器具有与输入图像相同的分辨率。如果 dp=2,累加器的宽度和高度只有一半。对于 HOUGH_GRADIENT_ALT,推荐值为 dp=1.5。double minDist, // 检测到的圆心之间的最小距离。如果参数太小,除了真实的圆之外,可能还会错误地检测到多个邻近的圆。如果太大,可能会漏掉一些圆。double param1 = 100, // Canny边缘检测器的高阈值 (低阈值是其一半)。对于 HOUGH_GRADIENT_ALT,这是推荐的霍夫变换累加器阈值。double param2 = 100, // 圆心检测的累加器阈值。它越小,就越容易检测到假圆。对于 HOUGH_GRADIENT_ALT,这是圆的 "完美度" 度量。越接近1,检测到的圆形状越好。int minRadius = 0, // 圆的最小半径int maxRadius = 0 // 圆的最大半径 (如果 <= 0, 则使用图像的最大维度;如果 < 0, 则返回圆心而不寻找半径)
);
注意: cv::HOUGH_GRADIENT_ALT
通常能提供更好的结果,但可能较慢。
主要步骤:
- 图像预处理:通常转换为灰度图,并进行平滑处理(如高斯模糊
cv::GaussianBlur
或中值滤波cv::medianBlur
)以减少噪声。 - 应用
cv::HoughCircles
。 - 遍历检测到的圆,并在原图上绘制。
示例代码:
#include <opencv2/opencv.hpp>
#include <iostream>
#include <vector>int main() {cv::Mat src = cv::imread("your_image_with_circles.png", cv::IMREAD_COLOR);if (src.empty()) {std::cerr << "Error: Could not load image." << std::endl;return -1;}cv::Mat gray;cv::cvtColor(src, gray, cv::COLOR_BGR2GRAY); // 1. 转换为灰度图// 1. 平滑处理以减少噪声,避免错误检测cv::medianBlur(gray, gray, 5); // 中值滤波对于椒盐噪声效果好std::vector<cv::Vec3f> circles; // (x, y, radius)// 2. 霍夫圆变换// 参数需要根据具体图像进行仔细调整cv::HoughCircles(gray, circles, cv::HOUGH_GRADIENT,1, // dp: 累加器分辨率与图像分辨率的反比gray.rows / 8, // minDist: 圆心之间的最小距离 (可调整)100, // param1: Canny边缘检测的高阈值30, // param2: 圆心累加器阈值 (值越小,检测到的圆越多,也可能包括假圆)10, // minRadius: 最小半径100 // maxRadius: 最大半径 (根据你的图像调整));// 3. 绘制检测到的圆for (size_t i = 0; i < circles.size(); i++) {cv::Point center(cvRound(circles[i][0]), cvRound(circles[i][1]));int radius = cvRound(circles[i][2]);// 绘制圆心cv::circle(src, center, 3, cv::Scalar(0, 255, 0), -1, 8, 0);// 绘制圆轮廓cv::circle(src, center, radius, cv::Scalar(0, 0, 255), 2, 8, 0);}cv::imshow("Source", src); // 在原彩色图上绘制cv::imshow("Detected Circles", src);cv::waitKey(0);return 0;
}
3. 重要提示与技巧 💡
- 参数调整:霍夫变换的参数(如
threshold
,rho
,theta
,minDist
,param1
,param2
,minRadius
,maxRadius
等)对检测结果影响很大。通常需要根据具体的应用场景和图像特性进行仔细调整和实验。 - 预处理:
- 对于直线检测,
cv::Canny
边缘检测是必不可少的步骤,其阈值也会影响最终结果。 - 对于圆检测,适当的平滑处理(如
cv::medianBlur
或cv::GaussianBlur
)有助于减少噪声,从而提高检测的准确性。
- 对于直线检测,
- 图像质量:输入图像的质量直接影响霍夫变换的性能。清晰、对比度好的图像更容易获得好的检测结果。
- 选择合适的变换类型:
- 如果需要检测到精确的线段端点并且关心效率,
cv::HoughLinesP
(概率霍夫变换) 通常是更好的选择。 - 如果需要图像中所有可能的直线信息(参数形式),则使用
cv::HoughLines
(标准霍夫变换)。
- 如果需要检测到精确的线段端点并且关心效率,
cv::HOUGH_GRADIENT_ALT
:对于圆检测,可以尝试使用method = cv::HOUGH_GRADIENT_ALT
,它可能提供更鲁棒的检测结果,但其参数(特别是param1
和param2
)的含义与cv::HOUGH_GRADIENT
不同,需要查阅文档并进行调整。
4. 总结 🚀
OpenCV 中的霍夫变换为直线和圆形的检测提供了强大而灵活的工具。理解其基本原理和各个参数的含义,结合适当的图像预处理,可以有效地在各种计算机视觉应用中识别这些基本几何形状。实践和参数调整是掌握霍夫变换的关键。
相关文章:
c/c++的opencv霍夫变换
OpenCV中的霍夫变换 (C/C) Hough Transform 霍夫变换 (Hough Transform) 是一种在图像分析中用于检测几何形状(如直线、圆形等)的特征提取技术。它通过一种投票机制在参数空间中寻找特定形状的实例。OpenCV 库为 C 开发者提供了强大且易用的霍夫变换函数…...
AAOS系列之(七) --- AudioRecord录音逻辑分析(一)
一文讲透AAOS架构,点到为止不藏私 📌 这篇帖子给大家分析下 AudioRecord的初始化 1. 场景介绍: 在 AAOS 的 Framework 开发中,录音模块几乎是每个项目都会涉及的重要组成部分。无论是语音控制、车内对讲(同行者模式)…...
MySQL大表结构变更利器:pt-online-schema-change原理与实战指南
MySQL大表结构变更利器:pt-online-schema-change原理与实战指南 MySQL数据库运维中,最令人头疼的问题之一莫过于对大表进行结构变更(DDL操作)。传统的ALTER TABLE操作会锁表,导致业务长时间不可用,这在724小时运行的互联网业务中是不可接受的。本文将深入剖析Percona To…...

LangChain【3】之进阶内容
文章目录 说明一 LangChain Chat Model1.1 少量示例提示(Few-Shot Prompting)1.2 Few-Shot示例代码1.3 示例选择器(Eample selectors)1.4 ExampleSelector 类型1.5 ExampleSelector案例代码1.6 LangServe工具1.7 LangServe安装1.8 langchain项目结构1.9 …...

大规模JSON反序列化性能优化实战:Jackson vs FastJSON深度对比与定制化改造
背景:500KB JSON处理的性能挑战 在当今互联网复杂业务场景中,处理500KB以上的JSON数据已成为常态。 常规反序列化方案在CPU占用(超30%)和内存峰值(超原始数据3-5倍)方面表现堪忧。 本文通过Jackson与Fas…...
【OpenSearch】高性能 OpenSearch 数据导入
高性能 OpenSearch 数据导入 1.导入依赖库2.配置参数3.OpenSearch 客户端初始化4.创建索引函数5.数据生成器6.批量处理函数7.主导入函数7.1 函数定义和索引创建7.2 优化索引设置(导入前)7.3 初始化变量和打印开始信息7.4 线程池设置7.5 主数据生成和导入…...
HTML5有那些更新
语义化标签 header 头部nav 导航栏footer 底部aside 内容的侧边栏 媒体标签 audio 音频播放video 视频播放 dom查询 document.querySelector,document.querySelectorAll他们选择的对象可以是标签,也可以是类(需要加点),也可以是ID(需要加#) web存储 localStorage和sessi…...

AWS EC2 实例告警的创建与删除
在AWS云环境中,监控EC2实例的运行状态至关重要。通过CloudWatch告警,用户可以实时感知实例的CPU、网络、磁盘等关键指标异常。本文将详细介绍如何通过AWS控制台创建EC2实例告警,以及如何安全删除不再需要的告警规则,并附操作截图与…...

STM32 搭配 嵌入式SD卡在智能皮电手环中的应用全景评测
在智能皮电手环及数据存储技术不断迭代的当下,主控 MCU STM32H750 与存储 SD NAND MKDV4GIL-AST 的强强联合,正引领行业进入全新发展阶段。二者凭借低功耗、高速读写与卓越稳定性的深度融合,以及高容量低成本的突出优势,成为大规模…...

黑马点评项目01——短信登录以及登录校验的细节
1.短信登录 1.1 Session方式实现 前端点击发送验证码,后端生成验证码后,向session中存放键值对,键是"code",值是验证码;然后,后端生成sessionID以Cookie的方式发给前端,前端拿到后&a…...

【笔记】Windows 系统安装 Scoop 包管理工具
#工作记录 一、问题背景 在进行开源项目 Suna 部署过程中,执行设置向导时遭遇报错:❌ Supabase CLI is not installed. 根据资料检索,需通过 Windows 包管理工具Scoop安装 Supabase CLI。 初始尝试以管理员身份运行 PowerShell 安装 Scoop…...
LVS + Keepalived高可用群集
目录 一:keepalived双击热备基础知识 1.keepalived概述及安装 1.1keepalived的热备方式 1.2keepalived的安装与服务控制 (1)安装keepalived (2)控制keepalived服务 2.使用keepalived实现双击热备. 2.1主服务器的…...

MySQL之约束和表的增删查改
MySQL之约束和表的增删查改 一.数据库约束1.1数据库约束的概念1.2NOT NULL 非空约束1.3DEFAULT 默认约束1.4唯一约束1.5主键约束和自增约束1.6自增约束1.7外键约束1.8CHECK约束 二.表的增删查改2.1Create创建2.2Retrieve读取2.3Update更新2.4Delete删除和Truncate截断 一.数据库…...
Greenplum:PB级数据分析的分布式引擎,揭开MPP架构的终极武器
一、Greenplum是谁?—— 定位与诞生背景 核心定位:基于PostgreSQL的开源分布式分析型数据库(OLAP),专为海量数据分析设计,支撑PB级数据仓库、商业智能(BI)和实时决策系统。 诞生背…...

Oracle数据库性能优化的最佳实践
原创:厦门微思网络 以下是 Oracle 数据库性能优化的最佳实践,涵盖设计、SQL 优化、索引管理、系统配置等关键维度,帮助提升数据库响应速度和稳定性: 一、SQL 语句优化 1. 避免全表扫描(Full Table Scan)…...
云原生时代 Kafka 深度实践:02快速上手与环境搭建
2.1 本地开发环境搭建 单机模式安装 下载与解压:前往Apache Kafka 官网,下载最新稳定版本的 Kafka 二进制包(如kafka_2.13-3.6.0.tgz,其中2.13为 Scala 版本)。解压到本地目录,例如/opt/kafka:…...
Redis7 新增数据结构深度解析:ListPack 的革新与优化
Redis 作为高性能的键值存储系统,其核心优势之一在于丰富的数据结构。随着版本迭代,Redis 不断优化现有结构并引入新特性。在 Redis 7.0 中,ListPack 作为新一代序列化格式正式登场,替代了传统的 ZipList(压缩列表&…...
分布式爬虫架构设计
随着互联网数据的爆炸式增长,单机爬虫已经难以满足大规模数据采集的需求。分布式爬虫应运而生,它通过多节点协作,实现了数据采集的高效性和容错性。本文将深入探讨分布式爬虫的架构设计,包括常见的架构模式、关键技术组件、完整项…...

汽配快车道:助力汽车零部件行业的产业重构与数字化出海
汽配快车道:助力汽车零部件行业的数字化升级与出海解决方案。 在当今快速发展的汽车零部件市场中,随着消费者对汽车性能、安全和舒适性的要求不断提高,汽车刹车助力系统作为汽车安全的关键部件之一,其市场需求也在持续增长。汽车…...

Windows 11 家庭版 安装Docker教程
Windows 家庭版需要通过脚本手动安装 Hyper-V 一、前置检查 1、查看系统 快捷键【winR】,输入“control” 【控制面板】—>【系统和安全】—>【系统】 2、确认虚拟化 【任务管理器】—【性能】 二、安装Hyper-V 1、创建并运行安装脚本 在桌面新建一个 .…...

PyQt6基础_QtCharts绘制横向柱状图
前置: pip install PyQt6-Charts 结果: 代码: import sysfrom PyQt6.QtCharts import (QBarCategoryAxis, QBarSet, QChart,QChartView, QValueAxis,QHorizontalBarSeries) from PyQt6.QtCore import Qt,QSize from PyQt6.QtGui import QP…...

《TCP/IP 详解 卷1:协议》第2章:Internet 地址结构
基本的IP地址结构 分类寻址 早期Internet采用分类地址(Classful Addressing),将IPv4地址划分为五类: A类和B类网络号通常浪费太多主机号,而C类网络号不能为很多站点提供足够的主机号。 子网寻址 子网(Su…...
Python学习(5) ----- Python的JSON处理
下面是关于 Python 中如何全面处理 JSON 的详细说明,包括模块介绍、数据类型映射、常用函数、文件操作、异常处理、进阶技巧等。 🧩 一、什么是 JSON? JSON(JavaScript Object Notation)是一种轻量级的数据交换格式&a…...

如何通过一次需求评审,让项目效率提升50%?
想象一下,你的团队启动了一个新项目,但需求模糊不清,开发到一半才发现方向错了,返工、加班、客户投诉接踵而至……听起来像噩梦?一次完美的需求评审就能避免这一切!它就像项目的“导航仪”,确保…...

再见Notepad++,你好Notepad--
Notepad-- 是一款国产开源的轻量级、跨平台文本编辑器,支持 Window、Linux、macOS 以及国产 UOS、麒麟等操作系统。 除了具有常用编辑器的功能之外,Notepad-- 还内置了专业级的代码对比功能,支持文件、文件夹、二进制文件的比对,支…...

element-plus bug整理
1.el-table嵌入el-image标签预览时,显示错乱 解决:添加preview-teleported属性 <el-table-column label"等级图标" align"center" prop"icon" min-width"80"><template #default"scope"&g…...

技术-工程-管用养修保-智能硬件-智能软件五维黄金序位模型
融智学工程技术体系:五维协同架构 基于邹晓辉教授的框架,工程技术体系重构为:技术-工程-管用养修保-智能硬件-智能软件五维黄金序位模型: math \mathbb{E}_{\text{技}} \underbrace{\prod_{\text{Dis}} \text{TechnoCore}}_{\…...

LangChain-自定义Tool和Agent结合DeepSeek应用实例
除了调用LangChain内置工具外,也可以自定义工具 实例1: 自定义多个工具 from langchain.agents import initialize_agent, AgentType from langchain_community.agent_toolkits.load_tools import load_tools from langchain_core.tools import tool, …...

用 3D 可视化颠覆你的 JSON 数据体验
大家好,这里是架构资源栈!点击上方关注,添加“星标”,一起学习大厂前沿架构! 复杂的 JSON 数据结构常常让人头疼:层层嵌套的对象、错综复杂的数组关系,用传统的树状视图或表格一览千头万绪&…...
联想小新笔记本电脑静电问题导致无法开机/充电的解决方案
一、问题背景 近期部分用户反馈联想小新系列笔记本电脑在特定环境下(如秋冬干燥季节)出现无法开机或充电的问题。经分析,此类现象多由静电积累触发主板保护机制导致,少数情况可能与电源适配器、电池老化或环境因素相关。本文将从技…...