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

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      // 检测直线的最大角度 (弧度)
);

主要步骤:

  1. 边缘检测:通常使用 cv::Canny
  2. 应用 cv::HoughLines
  3. 遍历检测到的直线参数,并在原图上绘制。

示例代码:

#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         // 同一直线上两点之间的最大允许间隙,以将它们连接起来
);

主要步骤:

  1. 边缘检测:通常使用 cv::Canny
  2. 应用 cv::HoughLinesP
  3. 遍历检测到的线段端点,并在原图上绘制。

示例代码:

#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 (xa)2+(yb)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 通常能提供更好的结果,但可能较慢。

主要步骤:

  1. 图像预处理:通常转换为灰度图,并进行平滑处理(如高斯模糊 cv::GaussianBlur 或中值滤波 cv::medianBlur)以减少噪声。
  2. 应用 cv::HoughCircles
  3. 遍历检测到的圆,并在原图上绘制。

示例代码:

#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::medianBlurcv::GaussianBlur)有助于减少噪声,从而提高检测的准确性。
  • 图像质量:输入图像的质量直接影响霍夫变换的性能。清晰、对比度好的图像更容易获得好的检测结果。
  • 选择合适的变换类型
    • 如果需要检测到精确的线段端点并且关心效率,cv::HoughLinesP (概率霍夫变换) 通常是更好的选择。
    • 如果需要图像中所有可能的直线信息(参数形式),则使用 cv::HoughLines (标准霍夫变换)。
  • cv::HOUGH_GRADIENT_ALT:对于圆检测,可以尝试使用 method = cv::HOUGH_GRADIENT_ALT,它可能提供更鲁棒的检测结果,但其参数(特别是 param1param2)的含义与 cv::HOUGH_GRADIENT 不同,需要查阅文档并进行调整。

4. 总结 🚀

OpenCV 中的霍夫变换为直线和圆形的检测提供了强大而灵活的工具。理解其基本原理和各个参数的含义,结合适当的图像预处理,可以有效地在各种计算机视觉应用中识别这些基本几何形状。实践和参数调整是掌握霍夫变换的关键。

相关文章:

c/c++的opencv霍夫变换

OpenCV中的霍夫变换 (C/C) Hough Transform 霍夫变换 (Hough Transform) 是一种在图像分析中用于检测几何形状&#xff08;如直线、圆形等&#xff09;的特征提取技术。它通过一种投票机制在参数空间中寻找特定形状的实例。OpenCV 库为 C 开发者提供了强大且易用的霍夫变换函数…...

AAOS系列之(七) --- AudioRecord录音逻辑分析(一)

一文讲透AAOS架构&#xff0c;点到为止不藏私 &#x1f4cc; 这篇帖子给大家分析下 AudioRecord的初始化 1. 场景介绍: 在 AAOS 的 Framework 开发中&#xff0c;录音模块几乎是每个项目都会涉及的重要组成部分。无论是语音控制、车内对讲&#xff08;同行者模式&#xff09;…...

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 示例选择器&#xff08;Eample selectors&#xff09;1.4 ExampleSelector 类型1.5 ExampleSelector案例代码1.6 LangServe工具1.7 LangServe安装1.8 langchain项目结构1.9 …...

大规模JSON反序列化性能优化实战:Jackson vs FastJSON深度对比与定制化改造

背景&#xff1a;500KB JSON处理的性能挑战 在当今互联网复杂业务场景中&#xff0c;处理500KB以上的JSON数据已成为常态。 常规反序列化方案在CPU占用&#xff08;超30%&#xff09;和内存峰值&#xff08;超原始数据3-5倍&#xff09;方面表现堪忧。 本文通过Jackson与Fas…...

【OpenSearch】高性能 OpenSearch 数据导入

高性能 OpenSearch 数据导入 1.导入依赖库2.配置参数3.OpenSearch 客户端初始化4.创建索引函数5.数据生成器6.批量处理函数7.主导入函数7.1 函数定义和索引创建7.2 优化索引设置&#xff08;导入前&#xff09;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云环境中&#xff0c;监控EC2实例的运行状态至关重要。通过CloudWatch告警&#xff0c;用户可以实时感知实例的CPU、网络、磁盘等关键指标异常。本文将详细介绍如何通过AWS控制台创建EC2实例告警&#xff0c;以及如何安全删除不再需要的告警规则&#xff0c;并附操作截图与…...

STM32 搭配 嵌入式SD卡在智能皮电手环中的应用全景评测

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

黑马点评项目01——短信登录以及登录校验的细节

1.短信登录 1.1 Session方式实现 前端点击发送验证码&#xff0c;后端生成验证码后&#xff0c;向session中存放键值对&#xff0c;键是"code"&#xff0c;值是验证码&#xff1b;然后&#xff0c;后端生成sessionID以Cookie的方式发给前端&#xff0c;前端拿到后&a…...

【笔记】Windows 系统安装 Scoop 包管理工具

#工作记录 一、问题背景 在进行开源项目 Suna 部署过程中&#xff0c;执行设置向导时遭遇报错&#xff1a;❌ Supabase CLI is not installed. 根据资料检索&#xff0c;需通过 Windows 包管理工具Scoop安装 Supabase CLI。 初始尝试以管理员身份运行 PowerShell 安装 Scoop…...

LVS + Keepalived高可用群集

目录 一&#xff1a;keepalived双击热备基础知识 1.keepalived概述及安装 1.1keepalived的热备方式 1.2keepalived的安装与服务控制 &#xff08;1&#xff09;安装keepalived &#xff08;2&#xff09;控制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是谁&#xff1f;—— 定位与诞生背景 核心定位&#xff1a;基于PostgreSQL的开源分布式分析型数据库&#xff08;OLAP&#xff09;&#xff0c;专为海量数据分析设计&#xff0c;支撑PB级数据仓库、商业智能&#xff08;BI&#xff09;和实时决策系统。 诞生背…...

Oracle数据库性能优化的最佳实践

原创&#xff1a;厦门微思网络 以下是 Oracle 数据库性能优化的最佳实践&#xff0c;涵盖设计、SQL 优化、索引管理、系统配置等关键维度&#xff0c;帮助提升数据库响应速度和稳定性&#xff1a; 一、SQL 语句优化 1. 避免全表扫描&#xff08;Full Table Scan&#xff09;…...

云原生时代 Kafka 深度实践:02快速上手与环境搭建

2.1 本地开发环境搭建 单机模式安装 下载与解压&#xff1a;前往Apache Kafka 官网&#xff0c;下载最新稳定版本的 Kafka 二进制包&#xff08;如kafka_2.13-3.6.0.tgz&#xff0c;其中2.13为 Scala 版本&#xff09;。解压到本地目录&#xff0c;例如/opt/kafka&#xff1a…...

Redis7 新增数据结构深度解析:ListPack 的革新与优化

Redis 作为高性能的键值存储系统&#xff0c;其核心优势之一在于丰富的数据结构。随着版本迭代&#xff0c;Redis 不断优化现有结构并引入新特性。在 Redis 7.0 中&#xff0c;ListPack 作为新一代序列化格式正式登场&#xff0c;替代了传统的 ZipList&#xff08;压缩列表&…...

分布式爬虫架构设计

随着互联网数据的爆炸式增长&#xff0c;单机爬虫已经难以满足大规模数据采集的需求。分布式爬虫应运而生&#xff0c;它通过多节点协作&#xff0c;实现了数据采集的高效性和容错性。本文将深入探讨分布式爬虫的架构设计&#xff0c;包括常见的架构模式、关键技术组件、完整项…...

汽配快车道:助力汽车零部件行业的产业重构与数字化出海

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

Windows 11 家庭版 安装Docker教程

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

PyQt6基础_QtCharts绘制横向柱状图

前置&#xff1a; pip install PyQt6-Charts 结果&#xff1a; 代码&#xff1a; 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采用分类地址&#xff08;Classful Addressing&#xff09;&#xff0c;将IPv4地址划分为五类&#xff1a; A类和B类网络号通常浪费太多主机号&#xff0c;而C类网络号不能为很多站点提供足够的主机号。 子网寻址 子网&#xff08;Su…...

Python学习(5) ----- Python的JSON处理

下面是关于 Python 中如何全面处理 JSON 的详细说明&#xff0c;包括模块介绍、数据类型映射、常用函数、文件操作、异常处理、进阶技巧等。 &#x1f9e9; 一、什么是 JSON&#xff1f; JSON&#xff08;JavaScript Object Notation&#xff09;是一种轻量级的数据交换格式&a…...

如何通过一次需求评审,让项目效率提升50%?

想象一下&#xff0c;你的团队启动了一个新项目&#xff0c;但需求模糊不清&#xff0c;开发到一半才发现方向错了&#xff0c;返工、加班、客户投诉接踵而至……听起来像噩梦&#xff1f;一次完美的需求评审就能避免这一切&#xff01;它就像项目的“导航仪”&#xff0c;确保…...

再见Notepad++,你好Notepad--

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

element-plus bug整理

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

技术-工程-管用养修保-智能硬件-智能软件五维黄金序位模型

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

LangChain-自定义Tool和Agent结合DeepSeek应用实例

除了调用LangChain内置工具外&#xff0c;也可以自定义工具 实例1&#xff1a; 自定义多个工具 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 数据体验

大家好&#xff0c;这里是架构资源栈&#xff01;点击上方关注&#xff0c;添加“星标”&#xff0c;一起学习大厂前沿架构&#xff01; 复杂的 JSON 数据结构常常让人头疼&#xff1a;层层嵌套的对象、错综复杂的数组关系&#xff0c;用传统的树状视图或表格一览千头万绪&…...

联想小新笔记本电脑静电问题导致无法开机/充电的解决方案

一、问题背景 近期部分用户反馈联想小新系列笔记本电脑在特定环境下&#xff08;如秋冬干燥季节&#xff09;出现无法开机或充电的问题。经分析&#xff0c;此类现象多由静电积累触发主板保护机制导致&#xff0c;少数情况可能与电源适配器、电池老化或环境因素相关。本文将从技…...