霍夫直线——检测、聚类与跟踪

0 概要

本文主要介绍三部分内容:
1、霍夫直线检测;
2、直线聚类;
3、直线跟踪;

1 霍夫直线基本数学原理

1.1 直线描述

1.1.1 霍夫直线参数含义

霍夫直线参数位rho,theta。
其中,
rho代表图像原点至直线的距离;
theta代表直线的角度,垂直为0度,顺时针旋转逐渐增大,水平位90度。
theta的取值范围:大于等于0度, 小于180度。

1.1.2 数学方程表示直线

已知: rho,theta;
直线系数:a = cos(theta), b = sin(theta);
垂点坐标:x0 = a * rho, y0 = b * rho;
直线方程:x = x0 - bt, y = y0 + at;

1.2 直线运算

1.2.1 直线反侧变换

标准直线参数的theta范围位[0,PI),在直线之间进行运算时会用到theta在此范围外的值,例如将1度的直线变换为181度,或者将179度的直线变换为-1度,这种变换成为反侧变换,反侧变换前后的直线等效,为同一直线。

  • 反侧变换一:
new_theta = old_theta - PI;
new_rho = - old_rho;
  • 反侧变换二:
new_theta = old_theta + PI;
new_rho = - old_rho;

1.2.2 直线规范化操作

将直线参数的角度值控制在[0,PI)范围内。

while (center_theta > PI)
{
	center_theta -= PI;
	center_rho = - center_rho;
}

while (center_theta < 0)
{
	center_theta += PI;
	center_rho = - center_rho;
}

1.2.3 霍夫直线间求差

在霍夫直线聚类时,需要将直线参数看作二维点,在此计算二维点之间的距离。
设两直线参数为(rho1, theta1)、(rho2, theta2),求取绝对误差:

error_theta = abs(theta1-theta2);
if error_theta <= PI/2 时:
	error_rho = abs(rho1 - rho2);
if error_theta > PI/2 时:
	error_theta = PI - error_theta;
	error_rho = abs(rho1 + rho2);

计算归一化直线误差(距离):

d0 = drho/Rho_max;
d1 = dtheta/(CV_PI*0.5);
error_cj = sqrtf(d0*d0 + d1*d1);   

1.2.4 霍夫直线求和与均值

在霍夫直线聚类求取中心点时,需要计算多直线参数累加和、均值。

  • 计算累加和:
    当样本直线距离该聚类中心直线的角度差大于90度时,需要做反侧变换,伪代码描述过程如下。
sum_theta = 0;
sum_rho = 0;
this_cluster_num = 0
for every lines in this cluster center:
	this_cluster_num ++;
	# 直线角度距离大于90度,则做反侧变换
	if (this_theta - center_theta) > PI/2:
		this_theta = this_theta - PI;
		this_rho = - this_rho;
	else if (this_theta - center_theta) < - PI/2:
		this_theta = this_theta + PI;
		this_rho = - this_rho;
	sum_theta += this_theta;
	sum_rho += this_rho;
  • 求取均值(中心点)
center_theta = sum_theta/this_cluster_num;
center_rho = sum_rho/this_cluster_num;
  • 结果规范化操作
    为了保持中心直线参数在多伦的聚类迭代运算时,始终保持在一定的范围内,需要对其进行常规化操作,将其范围控制在[0,PI)之间。

1.2.5 霍夫直线滤波

在直线跟踪时,为了保证目标直线的平滑行,需要加入滤波处理。
普通一阶低通滤波的方法: y = y_1 + k*(x - y_1);
霍夫直线滤波时需要考虑直线反侧变换,过程用伪代码表示:

# 偏差检测与反侧变换
error_theta = x_theta - y_theta;	
if (error_theta > PI/2):
	# 直线反侧变换
	x_u_theta = x_theta - PI;
	x_u_rho = - x_rho;
else if (error_theta < -PI/2):
	# 直线反侧变换
	x_u_theta = x_theta + PI;
	x_u_rho = - x_rho;
else:
	x_u_theta = x_theta;
	x_u_rho = -x_rho;

# 滤波处理
y_line = y_line + k*(x_u_line - y_line);

2 霍夫直线检测函数

2.1 函数HoughLines()

void HoughLines(InputArray image, OutputArray lines, 
				double rho, double theta, int threshold, 
				double srn=0, double stn=0, 
				double min_theta = 0, double max_theta = CV_PI )

参数解释:
第一个参数:InputArray类型的image,输入图像,即源图像,需为8位的单通道二进制图像,可以将任意的源图载入进来后由函数修改成此格式后,再填在这里。
第二个参数:InputArray类型的lines,经过调用HoughLines函数后储存了霍夫线变换检测到线条的输出矢量。每一条线由具有两个元素的矢量表示,其中,是离坐标原点((0,0)(也就是图像的左上角)的距离。 是弧度线条旋转角度(0垂直线,π/2水平线)。
第三个参数:double类型的rho,以像素为单位的距离精度。另一种形容方式是直线搜索时的进步尺寸的单位半径。PS:Latex中/rho就表示 。
第四个参数:double类型的theta,以弧度为单位的角度精度。另一种形容方式是直线搜索时的进步尺寸的单位角度。
第五个参数:int类型的threshold,累加平面的阈值参数,即识别某部分为图中的一条直线时它在累加平面中必须达到的值。大于阈值threshold的线段才可以被检测通过并返回到结果中。
第六个参数:double类型的srn,有默认值0。对于多尺度的霍夫变换,这是第三个参数进步尺寸rho的除数距离。粗略的累加器进步尺寸直接是第三个参数rho,而精确的累加器进步尺寸为rho/srn。
第七个参数:double类型的stn,有默认值0,对于多尺度霍夫变换,srn表示第四个参数进步尺寸的单位角度theta的除数距离。且如果srn和stn同时为0,就表示使用经典的霍夫变换。否则,这两个参数应该都为正数。
第八个参数:double类型的 min_theta,对于标准和多尺度Hough变换,检查线条的最小角度。必须介于0和max_theta之间。
第九个参数:double类型的 max_theta, 对于标准和多尺度Hough变换,检查线条的最大角度。必须介于min_theta和CV_PI之间.

2.2 函数HoughLinesP()

void HoughLinesP(InputArray image, OutputArray lines, 
				 double rho, double theta, int threshold, 
				 double minLineLength=0, double maxLineGap=0 )

参数解释:
第一个参数,InputArray类型的image,输入图像,即源图像,需为8位的单通道二进制图像,可以将任意的源图载入进来后由函数修改成此格式后,再填在这里。
第二个参数,InputArray类型的lines,经过调用HoughLinesP函数后后存储了检测到的线条的输出矢量,每一条线由具有四个元素的矢量(x_1,y_1, x_2, y_2) 表示,其中,(x_1, y_1)和(x_2, y_2) 是是每个检测到的线段的结束点。
第三个参数,double类型的rho,以像素为单位的距离精度。另一种形容方式是直线搜索时的进步尺寸的单位半径。
第四个参数,double类型的theta,以弧度为单位的角度精度。另一种形容方式是直线搜索时的进步尺寸的单位角度。
第五个参数,int类型的threshold,累加平面的阈值参数,即识别某部分为图中的一条直线时它在累加平面中必须达到的值。大于阈值threshold的线段才可以被检测通过并返回到结果中。
第六个参数,double类型的minLineLength,有默认值0,表示最低线段的长度,比这个设定参数短的线段就不能被显现出来。
第七个参数,double类型的maxLineGap,有默认值0,允许将同一行点与点之间连接起来的最大的距离。

2.3 函数使用说明

HoughLines检测到的直线参数是(rho, theta),表示一条直线的参数;不区分直线上的线段。HoughLinesP检测返回值是线段两端点的点坐标值,表示的是一条线段。
本文采用的是HoughLines函数,使用前需要做预处理:

image颜色通道分离;
红色引导线提取:(red - sat) > (blue  + green)

3 直线聚类

直线聚类的算法流程

聚类中心数量cluster_center_num = 1;
while 聚类未完成:	
	for 聚类N次数:
		聚类初始化工作;
		随机分布聚类中心点:在数据样本集中随机选取cluster_center_num 个点,作为数据中心点;
		while 本次聚类未达到收敛状态:
			根据当前聚类中心值,计算每一个点归属于哪一个聚类中心;
			根据归属关系,计算新的聚类中心值;
			当新的聚类中心与上次聚类中心一致时,本次聚类达到收敛状态;
		计算本次聚类完成后的样本点均方差,并记录;
	选取N次聚类结果中,均方差最小的那一次数据,作为聚类结果。
	若聚类均方差小于设定阈值,则聚类完成;否则,cluster_center_num  ++,开启新的N轮聚类。

随机分布聚类中心点的方法:
(1)在取值空间中随机取值坐标点,产生cluster_center_num 个数据点;
(2)在数据样本集中随机选取cluster_center_num 个点,作为数据中心点;
如果样本点在空间中分布非常不均匀的情况下,方法(1)产生的数据中心点有些偏离数据较远,则很难达到较好的收敛状态,即某些聚类中心可能没有隶属样本点。

需要考虑的问题:

  • 聚类的总类别个数不确定
    因为事先不知道图形中存在多少真实的直线,所以要自适应寻找聚类的类别数,判断依据是聚类后的均方差是否足够小;
  • 霍夫直线参数误差计算时的特殊处理
    (1) 角度处理
    由霍夫直线参数物理含义可知,1度的直线与179度的直线,在斜率上仅仅差别2度。所以,
    当两直线的误差error = | theta1 - theta2 |大于90度时,
    其真实误差是| PI - error|。
    (2) 距离处理
    当两个直线的角度偏差计算经过折算处理时,其斜率计算也需要进行折算处理。

4 直线跟踪

直线跟踪的本质是动态跟踪直线参数,或者是实时寻找距离上次参考直线最近的直线,并不断迭代的过程。跟踪的本质原理,在连续的视频拍摄中,直线在视野中的位置是连续变化的,那么被跟踪直线的参数(或其反侧变换)应该是连续变化的,即前后误差较小。
直线跟踪算法的伪代码表示:

# 初始设定:
# 设定被追踪直线的参考参数(rho,theta)
set_track_line_param(rho, theta);
# 实时跟踪:
# 遍历所有直线参数,寻找最近的直线参数;
for every lines in image:
	# 若最近直线与参考直线参数偏差小于阈值,则跟踪成功,参考直线参数 := 最近直线参数;
	if (this_line - track_line) < line_error_sat:
		track_succsess;
		track_line = this_line;
	# 否则,跟踪失败
	else:
		track_failure;
  • 6
    点赞
  • 45
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值