【数字图像处理】霍夫变换——传统方法车道线检测C++

前言

利用霍夫变换提取图像中的直线, 具体代码如下所示。霍夫变换的原理在此不多赘述,重点想讲述一下直线筛选的过程。
由于霍夫变换之后得到的直线数量很多,为了得到符合条件的直线,我们有必要对直线进行一定的筛选。在 draw_lane()函数种对直线进行比较精确地筛选,首先根据车道线的淘汰画面中较为平行的直线,接着设定 rho 和 angle 的阈值,淘汰重复的直线,使得每条车道仅有一条直线保留。


应用

话不多说直接上代码

输入

传入的参数为cv::Mat img 和阈值 threshold
我的车道线检测项目中传入边缘提取后的二值图像
在这里插入图片描述

具体代码

std::vector<int> hough_line_detect(cv::Mat img, int threshold)
{
	int row, col;
	int i, k;
	//参数空间的参数极角angle(角度),极径p;
	int angle, p;
	//累加器
	int** socboard;
	int* buf;
	int w, h;
	w = img.cols;
	h = img.rows;
	int Size;
	int offset;
	std::vector<int> lines;
	//申请累加器空间并初始化
	Size = w * w + h * h;
	Size = 2 * sqrt(Size) + 100;
	offset = Size / 2;
	cout << "offset: " << offset << endl;
	socboard = (int**)malloc(Size * sizeof(int*));
	if (!socboard)
	{
		printf("mem err\n");
		return lines;
	}
	for (i = 0; i < Size; i++)
	{
		socboard[i] = (int*)malloc(181 * sizeof(int));
		if (socboard[i] == NULL)
		{
			printf("buf err\n");
			return lines;
		}
		memset(socboard[i], 0, 181 * sizeof(int));
	}
	//遍历图像并投票
	int src_data;
	p = 0;
	for (row = 0; row < img.rows; row++)
	{
		for (col = 0; col < img.cols; col++)
		{
			//获取像素点
			src_data = img.at<uchar>(row, col);
			if (src_data == 255)
			{
				for (angle = 0; angle < 181; angle++)
				{
					p = col * cos(angle * PI / 180.0) + row * sin(angle * PI /180.0) + offset;
					//错误处理
					if (p < 0)
					{
						printf("at (%d,%d),angle:%d,p:%d\n", col, row, angle, p);
						printf("warrning!");
						printf("size:%d\n", Size / 2);
						continue;
					}
				//投票计分
				socboard[p][angle]++;
				}
			}
		}
	}
	//遍历计分板,选出符合阈值条件的直线
	//int count = 0;
	int Max = 0;
	int kp, kt, r;
	kp = 0;
	kt = 0;
	for (i = 0; i < Size; i++)//p
	{
		for (k = 0; k < 181; k++)//角度0-180
		{
			if (socboard[i][k] > Max)
			{
				Max = socboard[i][k];
				kp = i - offset;
				kt = k;
			}
			if (socboard[i][k] >= threshold)
			{
				r = i - offset;
				lines.push_back(i - Size / 2);//rho
				lines.push_back(k);//angle
			}
		}
	}
	//释放资源
	for (int e = 0; e < Size; e++)
	{
		free(socboard[e]);
	}
	free(socboard);
	return lines;
}

效果

【注】threshold需要自己好好调一调
在这里插入图片描述

附录

  1. 查看完整车道线检测项目代码
  2. 查看完整车道线检测项目思路
  • 1
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
车道线检测是自动驾驶和辅助驾驶技术中非常重要的一项任务。霍夫变换是一种常用的图像处理算法,可用于检测图像中的直线。本文将介绍如何使用霍夫变换和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) ``` 这是一个简单的车道线检测系统的实现。但是,它还有很大的改进空间。例如,它只能检测直线,无法检测曲线,因此在实际应用中可能需要使用更高级的算法。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值