图像处理算法 之 Hough变换

article/2025/9/29 5:59:59

Hough变换

    • 一、标准Hough线变换(SHT)
      • 1.1 原理
      • 1.2 SHT步骤
      • 1.3 缺点
    • 二、渐进概率Hough变换(PPHT)
      • 2.1 原理及步骤
      • 2.2 缺点
    • 三、Hough圆变换
      • 3.1 原理及步骤
      • 3.2 缺点
    • 四、实验代码

一、标准Hough线变换(SHT)

1.1 原理

标准Hough变换(standard hough transform)
图像平面中的一条直线可以通过斜截式y = ax+b来表示,即可以化为a-b平面中的一个点,但是因为斜率的区间为-∞到+∞变化,当直线接近竖直时,此时在a-b平面中是难以表示的,因此通过极坐标形式能够更加方便地表示
在这里插入图片描述
如图(A)所示,在图像平面中,一个点可以通过横纵坐标来表示;而图像平面中的一条直线可以通过距离原点的距离ρ,以及垂线的角度θ来表示,将其转换到θ-ρ平面中如(C)所示,即图像平面中的一条直线可由θ-ρ平面中的一个点表示因此图像平面中的一个点可以由穿过它的直线族在θ-ρ平面中对应的点组成的曲线来表示。如(C)所示,虚线对应(B)中的直线1,2,3,4的交叉点。可以得到在θ-ρ平面中两条曲线的交点即为图像平面中的两个点共线的一条直线

1.2 SHT步骤

因此标准霍夫线变换的步骤就很明了了:
① 首先对图片img进行边缘检测得到二值边缘图像edge_img
② 对于edge_img中的每个非0点都转换为θ-ρ平面中的一条曲线
转换方法如下:
对于图像平面中的一个非0点(x0,y0),使θ由0向2π变化,分别通过下式计算所对应的ρ值,
在这里插入图片描述
可以得到一系列点,这些点组成点(x0,y0)在θ-ρ平面中对应的曲线。
③ 在θ-ρ中进行对所有结果进行累加,则图像平面中的直线将显示为θ-ρ平面中的局部极大值。
④ 根据所设定的阈值对局部极大值进行筛选,得到最终的结果

1.3 缺点

标准霍夫线变换(SHT)是不能提取出线的端点的,并且耗时较长


OpenCV函数原型

//函数HoughLines的原型为:
void HoughLines(
InputArray image, //输入图像,要求是单通道的二值图像
OutputArray lines, //输出直线向量,两个元素的向量(ρ,θ)代表一条直线,原点为图像左上角 
double rho,  //距离分辨率,单位为像素
double theta,  //角度分辨率,单位为弧度
int threshold,  // 阈值,用于筛选p-θ平面的极大值,实际指明了返回的直线至少包含的点的数量
double srn=0// srn与stn是用于多尺度Hough变换(MHT)的参数,与标准hough变换无关
,double stn=0)
//其中rho和theta两个分辨率参数的作用还没仔细研究

多尺度hough变换(MHT)是对SHT的细化,精度更高(是通过srn,stn这两个参数对标准huogh变换的结果进行精确化)

二、渐进概率Hough变换(PPHT)

2.1 原理及步骤

渐进概率Hough变换(Progressive Probabilistic Hough Transform)是对SHT的改进,能够极大的减少计算时间,并且能够计算出直线的端点:
其主要原理是:在Edge图像中随机选择像素,将这些像素点按照SHT中的方法转换到累加平面(p-θ)。 当在累加平面中可以通过阈值筛选出一条直线时,沿该条直线搜索Edge图像,以查看是否存在一个或多个有限长度的线。然后在该直线的所有像素被从Edge图像中除去。通过这种方式,算法返回有限长度的直线。

该算法可以概括如下:
①创建输入边 Edge 图像(IMG1)的副本(IMG2)。
②用从 IMG2 随机选择的像素更新累加器。
③从 IMG2 中删除像素。
④如果修改的累加器(BINX)中具有最大值的较低阈值,转到第1点。
⑤沿着由BINX指定的线在 IMG1 中搜索,找到连续或间隙不超过给定阈值的间隔的最长像素段。
⑥从 IMG2 中删除段中的像素,清除BINX。
⑦如果检测到的线段比给定的最小长度长,请将其添加到输出列表中。
⑧转到第2点

2.2 缺点

该算法的一个问题是,多次运行可能会产生不同的结果。 如果许多直线共享像素,则会出现这种情况。如果两条线交叉,要检测的第一条线将去除公共像素(以及其周围的部分),从而导致另一条线上出现凹陷。 如果多条线交叉,则许多像素可能会错过最后一行,并且累加器中的投票可能无法达到阈值。

OpenCV函数:

void HoughLinesP(
InputArray image, //输入图像,要求是单通道的二值图像
OutputArray lines, //输出直线向量,为四通道向量,分别是线段的两个端点的坐标:(x0,y0,x1,y1) 
double rho,  //距离分辨率,单位为像素
double theta,  //角度分辨率,单位为弧度
int threshold,  // 阈值,用于筛选p-θ平面的极大值,实际指明了返回的直线至少包含的点的数量
double minLineLength=0// 线段长度阈值
,double maxLineGap=0   //线段之间的间隔阈值)

三、Hough圆变换

3.1 原理及步骤

Hough圆变换的原理与前文的Hough线变换相似,Hough线变换是在p-θ平面中不断累加,最后寻找极大值点,Hough圆变换也可以通过类似的方式寻找,需要在三维空间中累加体积,三维分别是圆心的横坐标、纵坐标、半径,但是这样时间复杂度和空间复杂度会非常大,所以实际实现时没有采用这种方法。OpenCV中的Hough圆变换是通过Hough梯度法实现的。

首先看一张图:
在这里插入图片描述
可以看到圆上的每一个点(橙色点)都存在一条线(蓝色虚线)相交于圆心(红点),而这些线就是各个点的梯度方向(蓝色箭头)所在的直线。圆心是它们的交点,这就与Hough线变换中的累加平面非常相似了,此时将所有直线都累加起来,圆心就是一个局部极大值点!

所以Hough圆变换就可以通过下面的方法实现了:
① 同样的,首先对图像进行边缘检测,得到edge_img;
② 对edge_img中的每一个非0点计算局部梯度(可以通过Sobel算子计算)
③ 沿着每个点的梯度所在的直线在累加平面中进行累加,同时记录非0点的位置
④ 根据阈值选取累加平面中的局部极大值点作为候选圆心
⑤ 对于每个圆心都有一个与它相关的非0点的列表(步骤③中记录的),计算这些非0点与该圆心的距离,从中选取出最优值作为半径
⑥ 如果有足够数量的点构成圆且该圆心与其它圆心间距超过阈值,就保留这个圆
⑦ 最终就能够得到检测结果

3.2 缺点

①累加器阈值过低时速度会非常慢,因为需要考虑每个非0点
②对每个圆心只能选一个圆,同心圆时只能检测到一个
③Sobel计算的是局部梯度,所以会出现噪音,稳定性略低

OpenCV函数:

//HoughCircles中调用了Canny函数,因此不需要另外对图像进行边缘检测
void HoughCircles(
InputArray image, //输入图像,要求是8位图像,即灰度图,因为需要计算梯度,使用灰度图更精准,与HoughLines中要求二值图像不同
OutputArray circles, //输出,为矩阵或者向量,矩阵的话就是F32C3的数组,三个通道分别为圆心坐标和半径;向量的话就是vector<Vec3f>类型 
int method,  //实际设置为cv::HOUGH_GRADIENT
double dp,  //累加图像的分辨率,需要大于等于1
double minDist,  // 圆之间的最小距离阈值
double param1=100//用于Canny中的高阈值,Canny的低阈值设为它的一半
double param2=100   //累加器阈值,与HoughLines中的threshold类似
int minRadius = 0,		//最小半径阈值
int maxRadius = 0		//最大半径阈值
)

四、实验代码


void hough_test()
{Mat src = imread("../Images/10.jpg");if (src.empty()) { cout << "read the image failed!!!!!!" << endl;}//读入灰度图,用于hough圆变换检测Mat src_circles = imread("../Images/11.jpg");Mat src_circles_gray;cv::cvtColor(src_circles, src_circles_gray, cv::COLOR_BGR2GRAY);Mat src_PPHT;src.copyTo(src_PPHT);Mat edge_img;vector<Vec2f> hough_lines;vector<Vec4f> hough_P_lines;vector<Vec3f> hough_circles;//图像的宽和高int w = src.cols;int h = src.rows;//Canny滤波Canny(src, edge_img, 50, 150);//SHT 标准hough线变换HoughLines(edge_img, hough_lines, 1, CV_PI/180, 130);//PPHT 渐进hough线变换HoughLinesP(edge_img, hough_P_lines, 1, CV_PI / 180, 130, 20, 100);//Hough圆变换HoughCircles(src_circles_gray, hough_circles, cv::HOUGH_GRADIENT, 2, 50, 100, 100, 10, 300);//在原图上绘制SHT检测出的直线for (auto& line_iter : hough_lines){float rho = line_iter[0];float theta = line_iter[1];Point point1, point2;point1.x = rho*cos(theta) + w*sin(theta);point1.y = rho*sin(theta) - w*cos(theta);point2.x = rho*cos(theta) - w*sin(theta);point2.y = rho*sin(theta) + w*cos(theta);line(src, point1, point2, Scalar(0, 255, 0), 2,8);}//绘制PPHT检测到的直线for (auto& line_iter : hough_P_lines){line(src_PPHT, Point(line_iter[0], line_iter[1]), Point(line_iter[2], line_iter[3]),Scalar(0,0,255),2,8);}//绘制Hough圆变换检测到的圆for (auto& circles : hough_circles){circle(src_circles, Point(circles[0], circles[1]), circles[2], Scalar(0,0,255), 2);}namedWindow("src_SHT", WINDOW_NORMAL);imshow("src_SHT", src);namedWindow("src_PPHT", WINDOW_NORMAL);imshow("src_PPHT", src_PPHT);namedWindow("edge_img", WINDOW_NORMAL);imshow("edge_img", edge_img);namedWindow("circles_img", WINDOW_NORMAL);imshow("circles_img", src_circles);waitKey(0);
}

实验结果如图:
在这里插入图片描述
在这里插入图片描述

参考资料:
《学习OpenCV3》
https://sikasjc.github.io/2018/04/20/Hough/
https://blog.csdn.net/qq_37059483/article/details/77891698


最后,如有错误的地方还请大佬指正,同时欢迎一起讨论,转载请注明出处


http://chatgpt.dhexx.cn/article/Ypb9xgKw.shtml

相关文章

MATLAB中的Hough变换

下面来介绍一下关于Hough变换的原理及其如何在MATLAB中实现。 Hough变换&#xff1a;Hough变换是一种使用表决原理的参数估计技术。其原理是利用图像空间和Hough参数空间的点&#xff0d;线对偶性&#xff0c;把图像空间中的检测问题转换到参数空间。国内外对Hough变换的研究及…

智能图像分析——Hough变换

一、原理 引用 hough变换利用点、线对偶的思想&#xff0c;把提取图像空间中直线的问题转换成在参数空间/hough空间中计算点的峰值的问题。 在x − y坐标系中&#xff0c;假设有一条直线过点( x0 , y0 )&#xff0c;那么我们可以把这条直线的方程记为 ymxb&#xff08;1&#…

霍夫Hough变换

参考: https://blog.csdn.net/qq_15971883/article/details/80583364 MATLAB帮助文档 Hough变换是一种使用表决方式的参数估计技术,其原理是利用图像空间和Hough参数空间的线-点对偶性,把图像空间中的检测问题转换到参数空间中进行。 利用Hough变换检测直线 记住:直角坐标…

Hough变换及MATLAB示例

前言 在车道线检测中&#xff0c;最小二乘法&#xff0c;Hough变换是车道线模型拟合的传统方法之一&#xff0c;通过一系列离散的点拟合出车道直线&#xff0c;也就是得到基于像素平面坐标系的左车道和右车道直线方程。 Hough变换 Hough变换的基本思想 我们先来看看如何表达…

hough变换算法

VoteNet网络中会用Deep Hough Voting&#xff0c;所以先来学习一下Hough Voting。 正文开始 hough变换算法 1、算法思想 霍夫变换于1962年由Paul Hough 首次提出&#xff0c;后于1972年由Richard Duda和Peter Hart推广使用&#xff0c;经典霍夫变换用来检测图像中的直线&…

Hough 变换

Hough 变换是图像处理中&#xff0c;检测直线最基本&#xff0c;也是应用最广泛的一种传统方法。虽然现在是深度学习大行其道的时代&#xff0c;但是很多传统的算法&#xff0c;依然有其参考的价值所在&#xff0c;至少从数学表达上来看&#xff0c;是更加的简洁&#xff0c;有…

Hough transform(霍夫变换)

主要内容&#xff1a; 1、Hough变换的算法思想 2、直线检测 3、圆、椭圆检测 4、程序实现 一、Hough变换简介 Hough变换是图像处理中从图像中识别几何形状的基本方法之一。Hough变换的基本原理在于利用点与线的对偶性&#xff0c;将原始图像空间的给定的曲线通过曲线表达形式变…

Hough变换

目录 一、Hough变换简介 二、Hough变换的数学理解 1.x-y变量空间至k-b参数空间的变换 2.x-y变量空间至-空间的变换 三、Hough变换应用于线检测&#xff08;MATLAB实现&#xff09; 1.检测步骤 2.使用MATLAB工具箱中的Hough变换函数进行边缘检测 一、Hough变换简介 霍夫变…

图像处理:Hough变换原理分析

目录 一、前言 二、直线函数的形式化表示 2.1 直线被方程表示 2.2 直线被图表表示 2.3 直线的表格表示 三、hough变换的提出 3.1 极坐标表示点和线 四、 hough变换的原理 4.1 极坐标的​编辑表格 4.2 用​编辑平面表示&#xff1a;过任意点P(x,y)做所有射线&#xff0…

Hough变换原理-直线检测

目录 一、简介 二、原理 三、Python代码实现 一、简介 Hough&#xff08;霍夫&#xff09;变换是图像处理中从图像中识别几何形状的基本方法之一。Hough变换是将图像坐标空间变换到参数空间&#xff0c;利用点与线的对偶性&#xff0c;将原始图像空间的给定的曲线&#xff08…

YUV444、YUV422、YUV420、YUV420P、YUV420SP、YV12、YU12、NV12、NV21

前言 各种YUV格式多如牛毛啊&#xff0c;刚开始学起来确实很费劲&#xff0c;网上搜索的文章讲的并不是很明白。 各种不同的YUV格式其实只是采样方式和存储方式不同&#xff0c;就这两点&#xff0c;不同的采样方式是为了实现节省内存&#xff0c;不同的存储方式暂时不了解有…

2023-02-24:请用go语言调用ffmpeg,解码mp4文件并保存为YUV420SP格式文件,采用YUV420P转YUV420SP的方式。

2023-02-24&#xff1a;请用go语言调用ffmpeg&#xff0c;解码mp4文件并保存为YUV420SP格式文件&#xff0c;采用YUV420P转YUV420SP的方式。 答案2023-02-24&#xff1a; 使用 github.com/moonfdd/ffmpeg-go 库。 解码后就是yuv420p&#xff0c;然后用SwsScale函数转换成yuv…

ffmpeg处理YUV422和YUV420P相互转换

YUV422空间大小计算 YUV422封包width*heightwidth/2*height*2YUYV Y分量width*heightYUYV U分量width/2*heightYUYV V分量width/2*height YUV420空间大小计算 YUV420封包width*heightwidth/2*height/2*2Y分量width*heightU分量width/2*height/2V分量width/2*height/2 extern &…

Android Camera2 YUV420_888 格式详解

Camera2 YUV420_888 官网文档介绍 Android PAI 对 YUV420_888的介绍 &#xff0c;大致意思如下&#xff1a; 它是YCbCr的泛化格式&#xff0c;能够表示任何4:2:0的平面和半平面格式&#xff0c;每个分量用8 bits 表示。带有这种格式的图像使用3个独立的Buffer表示&#xff0c;每…

【音视频数据数据处理 2】【YUV篇】将YUV420P_I420数据旋转90°-180°-270°-镜像旋转

【音视频数据数据处理 2】【YUV篇】将YUV420P_I420数据旋转90 一、理论分析&#xff08;以yuv420p_i420格式为例&#xff09;二、顺时针旋转90 代码实现三、顺时针旋转180 代码实现四、旋转90-180-270-镜像旋转&#xff0c;完整代码实现五、运行结果 本文接着前文&#xff1a; …

YUV420->RGB888格式转换的CPP实现

git地址&#xff1a; GitHub - Evayangelion/EYUVConverter: A YUV converter implemented by cpp 上一次学习了YUV各种采样和存储方式的区别&#xff08;YUV知识存档&#xff09; 接下来一起学习一下RGB格式的知识和YUV到RGB的转换方式 RGB色彩模式的分类 RGB的分类相较YUV来说…

YUV444,YUV420P,YUV420SP,YUV422P,YUV422SP,NV12,NV21,NV16,NV61等格式区分与存储简介

一、基础知识&#xff1a; 概述 YUV是顏色編碼方式&#xff0c;常用於視頻及圖像處理中。 其中的YUV是三個分量。“Y”表示明亮度&#xff08;Luminance或Luma&#xff09;&#xff0c;也就是灰度值。“U”和“V” 表示的是彩色信息&#xff0c;分別爲色度和濃度&#xff08;C…

OpenGL渲染YUV420P

一 、YUV420P数据格式二 、GLFW渲染YUV420P2.1 定义顶点数据2.2 创建YUV三张纹理2.3上行YUV420数据2.4 渲染纹理2.5 着色器 三、代码地址以及存在的问题四 、解决存在的问题 一 、YUV420P数据格式 图片来源于谷歌 结合上图可以看出YUV420P的特点如下&#xff1a; ①无论在横向还…

详解 YUV 格式(I420/YUV420/NV12/NV12/YUV422)

转载自&#xff1a;划水型派大星 YUV &#xff08;YCbCr&#xff09;是一种像素格式&#xff0c;常见于视频编码与静态图像。与 RGB 格式&#xff08;红-绿-蓝&#xff09;相反&#xff0c;YUV 分别由一个称为 Y&#xff08;相当于灰度&#xff09;的“亮度”分量&#xff08;…

ffmpeg学习笔记(2)-YUV420算法原理

ffmpeg学习笔记(2)——YUV420算法原理 一、YUV像素格式 YUV的组成格式如下图所示 Y:明亮度&#xff0c;即灰度值 U、V&#xff1a;颜色 YUV格式将亮度信息和色彩信息分离&#xff0c;没有色彩信息依然能够显示图像&#xff08;没有色彩信息&#xff09;&#xff0c;很好的解…