OpenCV图像处理学习十八,霍夫变换实现交通车道线检测

一.霍夫变换

经典霍夫变换用来检测图像中的直线,后来霍夫变换经过扩展可以进行任意形状物体的识别,例如圆和椭圆。霍夫变换运用两个坐标空间之间的变换,将在一个空间中具有相同形状的曲线或直线映射到另一个坐标空间的一个点上形成峰值,从而把检测任意形状的问题转化为统计峰值问题。

 

二.霍夫变换直线检测的原理

(1)图像空间中的点与参数空间中的直线一一对应。

在图像空间直角坐标系x-y中,一条直线在直角坐标系下可以表示为:y = k x + b;其中常数k和b是参数,表示直线的斜率和截距。过某一点A ( x 0 , y 0 ) 的所有直线的参数均满足方程:y 0 = k ∗x 0 + b ;即过图像上的一点A ( x 0 , y 0 )可以确定N条直线。
​    

如果我们将方程改写为:b=-kx0+y0;那么该方程在参数空间k-b中就对应了一条直线。也就是说,图像空间直角坐标系x-y中的点( x 0 , y 0 ) ;对应了参数空间k-b中的直线 b = − k ∗ x 0 + y 0 ;因此可以得到结论,图像空间中的点与参数空间中的直线一一对应。

 --------------------------------------------------------------------------------------------------------------------------------

直线y=kx+b上再增加一个点 B(x1, y1),B点在图像空间直角坐标系可以确定N条直线,那么点B ( x 1 , y 1 ) ,但是在参数空间也有一条对应的直线,与A ( x 0 , y 0 ) 确定的直线相较于M点。
​    
 

=========================================================================

(2)图像空间中的直线与参数空间中的点一一对应

图像空间直角坐标系x-y中的点A(x0,y0)和点B(x1,y1),在参数空间坐标系k-b中对应的直线相交于一点,这也就是说AB所确定的直线,在参数空间坐标系中对应着唯一一个点,而这个点的坐标值( k 0 , b 0 ) 也就是直线AB的参数。这就是直线检测任务中的对偶性,这个性质也为我们解决直线检测任务提供了方法,也就是把图像空间中的直线对应到参数空间中的点,最后通过统计特性来解决问题。假如图像空间中有两条直线,那么最终在参数空间中就会对应到两个峰值点,依此类推。

 --------------------------------------------------------------------------------------------------------------------------------

参数空间选择了笛卡尔直角坐标系是为了解释偶性和霍夫变换的基本原理,但在实际应用中,参数空间是不能选择直角坐标系的,原始图像直角坐标空间中的特殊直线x=c(c为常数,垂直x轴,直线的斜率为无穷大)是没办法在基于直角坐标系的参数空间中表示的,一般我们采用极坐标方式作为参数空间。

空间直角坐标系与极坐标系的转换

在下图中可以看出,参数空间的每个点(r,θ)都对应了图像空间直角坐标系的一条直线,或者说图像空间的一个点在参数空间中就对应为一条曲线。参数空间采用极坐标系,这样就可以在参数空间表示图像空间直角坐标系中的所有直线了。此时图像空间直角坐标系x-y上的一个点对应到参数空间(极坐标系ρ-θ)上是一条曲线,确切的说是一条正弦曲线。

经过变换,图像空间中的每个点(x,y)就被映射为一个(r,θ)极坐标空间中的正弦曲线。而图像空间直角坐标系中共线的点所对应的参数空间中正弦曲线相交于一点(r’,θ’)。这样就把在图像空间中检测直线的问题,转化为在极坐标参数空间中寻找通过点(r,θ)的最多正弦曲线数量的问题。霍夫空间中,曲线的交点次数越多,所代表的参数越确定(相交的曲线都是图像空间直角坐标系上的点),画出的图形越饱满。空间直角坐标系上一条直线上的所有点都转化为参数空间上的曲线,曲线一定会交于一个共同点。

 =========================================================================

三.霍夫变换直线检测 API函数接口

OpenCV支持三种霍夫直线检测算法:
1)Standard Hough Transform(SHT,标准霍夫变换)
2)Multiscale Hough Transform(MSHT,多尺度霍夫变换)
3)Progressive Probability Houth Transform(PPHT,渐进概率式霍夫变换)

(1)标准霍夫变换直线检测 cv::HoughLines从平面坐标转换到霍夫空间,最终输出是 (θ,rθ) 表极坐标空间。

#霍夫直线变换API函数接口
cv::HoughLines( 
InputArray src, // 输入图像,必须8-bit的灰度图像 
OutputArray lines, // 输出的极坐标来表示直线 ,经过调用HoughLines函数后储存了霍夫线变换检测到线条 
                   //的输出矢量(每一条线由具有两个元素的矢量(rho,theta)表示)
double rho, // 生成极坐标时候的像素扫描步长 
double theta, //生成极坐标时候的角度步长,一般取值CV_PI/180 
int threshold, // 阈值,只有获得足够交点的极坐标点才被看成是直线 
double srn=0;// 是否应用多尺度的霍夫变换,如果不是设置0表示经典霍夫变换 
double stn=0;//是否应用多尺度的霍夫变换,如果不是设置0表示经典霍夫变换 
double min_theta=0; // 表示角度扫描范围 0 ~180之间, 默认即可 
double max_theta=CV_PI 
) // 一般情况是有经验的开发者使用,需要自己反变换到平面空间

HoughLines函数输出检测到直线的矢量表示集合,每一条直线由具有两个元素的矢量(ρ, θ)表示,其中ρ表示直线距离原点(0, 0)的长度,θ表示直线的角度(以弧度为单位)。HoughLines函数无法输出图像空间中线段的长度。

(2)HoughLinesP:渐进概率式霍夫变换

cv::HoughLinesP( 
InputArray src, // 输入图像,必须8-bit的灰度图像 
OutputArray lines, // 输出的极坐标来表示直线 
double rho, // 生成极坐标时候的像素扫描步长 
double theta, //生成极坐标时候的角度步长,一般取值CV_PI/180 
int threshold, // 阈值,只有获得足够交点的极坐标点才被看成是直线 
double minLineLength=0;// 最小直线长度 
double maxLineGap=0;// 最大间隔 
)

渐进概率式霍夫变换直线检测 cv::HoughLinesP最终输出是直线的两个点。HoughLinesP能够检测出线端,即能够检测出图像中直线的两个端点,确切地定位图像中的直线。

=========================================================================

四.霍夫直线变换实现车道线的检测

(1)彩色图像RBG转化为灰度图Gray,opencv上需要注意颜色空间是RGB还是BGR,CImg中RGB分别对应0,1,2通道。
(2)因为霍夫圆检测对噪声比较敏感,所以首先要对图像做中值滤波(或者高斯滤波)去噪,平滑图像,消除图像噪声。 
(3)图像边缘提取(梯度算子、拉普拉斯算子、canny边缘检测算法) 
(4)图像二值化(判断此处是否为边缘点,就看灰度值==255),在高斯去噪和边界提取之后都需要二值化。
(5)映射到霍夫空间(此处准备两个容器,一个CImg用来展示hough-space概况,一个数组hough-space用来储存voting的值,因为投票过程往往有某个极大值超过255,多达几千,不能直接用灰度图来记录投票信息)。
(6)取局部极大值,设定阈值,过滤低于阈值的像素,排除干扰直线
(7)绘制直线。

=========================================================================


代码实现

#include"stdafx.h"
#include<opencv2\imgproc\imgproc.hpp>
#include<opencv2\opencv.hpp>
#include<opencv2\highgui\highgui.hpp>
using namespace std;
using namespace cv;

int main()
{
	Mat Image = imread("F:/photo/cdjc.jpg", 0);
	Mat CannyImg;
	Canny(Image, CannyImg, 140, 250, 3);
	
	
	imshow("CannyImg", CannyImg);

	Mat DstImg;
	cvtColor(Image, DstImg, COLOR_GRAY2BGR);

	vector<Vec4i> Lines;
	HoughLinesP(CannyImg, Lines, 1, CV_PI / 360, 170, 30, 15);
	for (size_t i = 0; i < Lines.size(); i++)
	{
		line(DstImg, Point(Lines[i][0], Lines[i][1]), Point(Lines[i][2], Lines[i][3]), Scalar(0, 0, 255), 2, 8);
	}
	imshow("HoughLines_Detect", DstImg);
	
	waitKey(0);
	return 0;
}

 --------------------------------------------------------------------------------------------------------------------------------

图像处理效果 

  • 3
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
车道线检测是自动驾驶和辅助驾驶技术中非常重要的一项任务。霍夫变换是一种常用的图像处理算法,可用于检测图像中的直线。本文将介绍如何使用霍夫变换和Python实现车道线检测系统。 首先,我们需要导入所需的库,包括OpenCV和NumPy。 ```python import cv2 import numpy as np ``` 接下来,我们需要读取图像并将其转换为灰度图像。然后,我们使用Canny边缘检测算法来检测图像中的边缘。 ```python img = cv2.imread('test_image.jpg') gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) edges = cv2.Canny(gray, 50, 150) ``` 现在,我们可以使用霍夫变换来检测图像中的直线霍夫变换需要设置一些参数,包括距离分辨率、角度分辨率和阈值等。在这里,我们将使用以下参数: ```python rho = 2 # 距离分辨率 theta = np.pi / 180 # 角度分辨率 threshold = 50 # 阈值 min_line_length = 100 # 最小线段长度 max_line_gap = 5 # 最大线段间隙 ``` 然后,我们可以使用cv2.HoughLinesP函数来执行霍夫变换。该函数返回检测到的线段的起点和终点坐标。 ```python lines = cv2.HoughLinesP(edges, rho, theta, threshold, np.array([]), min_line_length, max_line_gap) ``` 最后,我们可以将检测到的线段绘制到原始图像上,以显示车道线的位置。 ```python line_image = np.zeros_like(img) for line in lines: x1, y1, x2, y2 = line[0] cv2.line(line_image, (x1, y1), (x2, y2), (255, 0, 0), 5) result = cv2.addWeighted(img, 0.8, line_image, 1, 0) cv2.imshow('result', result) cv2.waitKey(0) ``` 完整的代码如下所示: ```python import cv2 import numpy as np img = cv2.imread('test_image.jpg') gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) edges = cv2.Canny(gray, 50, 150) rho = 2 # 距离分辨率 theta = np.pi / 180 # 角度分辨率 threshold = 50 # 阈值 min_line_length = 100 # 最小线段长度 max_line_gap = 5 # 最大线段间隙 lines = cv2.HoughLinesP(edges, rho, theta, threshold, np.array([]), min_line_length, max_line_gap) line_image = np.zeros_like(img) for line in lines: x1, y1, x2, y2 = line[0] cv2.line(line_image, (x1, y1), (x2, y2), (255, 0, 0), 5) result = cv2.addWeighted(img, 0.8, line_image, 1, 0) cv2.imshow('result', result) cv2.waitKey(0) ``` 这是一个简单的车道线检测系统的实现。但是,它还有很大的改进空间。例如,它只能检测直线,无法检测曲线,因此在实际应用中可能需要使用更高级的算法

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

肖爱Kun

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值