1. 引言
随着中国汽车技术的迅猛进步以及汽车智能化程度的不断提高,国内的汽车保有量正呈现逐年增长的趋势。然而,由此引起的道路安全问题也日益严峻。为了确保车辆运行的安全性,基于计算机视觉的车辆辅助驾驶和智能车辆自动驾驶得到了广泛应用,而车道线的准确实时检测是其中一个重要的组成部分 [1] [2] 。车道是交通系统中用来划分道路、保证汽车安全有效行驶的交通标志,车道检测是一种自动检测道路标记的技术,其在自动驾驶方面发挥着重要作用 [3] 。实时准确的车道检测可以让自动驾驶车辆对其位置和状态做出正确的判断,从而确保安全驾驶。
在车道线检测方面,直线车道线的检测是研究最多的。传统车道线检测在经过图片预处理后会采用霍夫变换算法来检测直线,其在直线车道线检测领域表现出了高有效性和高精度。然而,霍夫变换算法的实施过程中存在计算量大和内存占用的问题,这在一定程度上限制了其在实时系统中的应用 [4] 。为了减少图像处理和直线检测的时间,提高检测的实时性,文献 [5] 通过限定斜率范围、设置平均斜率偏离阈值来快速除去噪声,将检测对象锁定在目标车道线上;文献 [6] 通过缩小感兴趣区域并动态跟踪感兴趣区域来减小霍夫变换的计算量;文献 [7] 则利用OpenCV库函数高效地实现了霍夫变换直线检测。
随着道路交通场景的不断复杂化,对应算法的复杂度也显著提升。由于车道线检测在实时性和准确性方面要求很高,以CPU为基础的传统算法已有其局限性。同时,伴随着并行计算的兴起,以GPU为核心的并行计算技术已经被越来越多的应用到各个领域 [8] 。基于CPU + GPU的异构计算架构正在逐渐成为一种高效、低能耗的主流计算方式,为多个应用场景提供了良好的计算平台 [9] 。OpenCL通过统一的编程框架和接口能在CPU + GPU的异构计算环境中,构筑并行计算架构,允许应用程序利用多种硬件资源进行加速,这种并行计算可以同时处理多个任务或数据,显著提高了计算效率和程序性能 [10] 。因此,本文基于OpenCL异构计算架构,旨在通过并行化加速车道线检测算法,着重对车道线检测算法中常用的高斯滤波、边缘检测和霍夫变换等流程进行了GPU并行计算的实现和优化。
2. OpenCL异构计算架构简介
OpenCL包含一系列基础API和高效、快速、可移植的抽象层,使其能够在不同的硬件体系结构上进行异构计算程序开发,这能够更有效地利用现有的计算资源提高程序的性能和效率 [11] 。OpenCL程序包含主机端程序和内核程序。OpenCL程序的运行流程如图1所示。计算任务由主机端开始并在主机端进行数据解包和预处理,在主机端选取设备端建立联系后,主机将数据发送到设备端并调用内核程序进行并行计算,计算完成后,主机端会读取计算结果进行后续处理。
3. 基于OpenCL异构计算架构的车道线检测算法设计
本文研究的车道线检测任务主要分为图像预处理和车道线检测两个部分。为了减少噪声并突出车道线特征,将对含有车道线的图像进行预处理再进行后续的检测流程。这些预处理操作包括将图像转换为灰度图以降低数据的复杂性;应用高斯滤波器以平滑图像并抑制噪声;进行边缘检测以突出车道线的结构特征;以及提取图像中的感兴趣区域,即可能包含车道线的区域。随后进行车道线检测过程,该过程涉及霍夫变换来识别图像中的直线,并使用直线参数聚类技术以区分并选择出最合适的车道线。最终,挑选出的车道线将被准确地标绘在原始图像上,实现车道线的有效检测与视觉呈现。
在这个过程中将使用OpenCL异构计算架构来设计高斯滤波、边缘检测、提取感兴趣区域和霍夫变换等步骤的内核程序,并在GPU上进行实现,以加速整个车道线检测算法。整个算法的结构如图2所示。
3.1. 图像灰度化
彩色图像中的每个像素点包含红绿蓝(RGB)三个颜色通道,将彩色图像转化为灰度图像的步骤涉及对彩色图像中每个像素进行特定计算。可以通过给彩色图像的RGB三个分量施加不同的加权系数,从而进行加权处理将图像灰度化,其加权公式如下:
(1)
彩色图像转换为灰度图像的过程是使用不同的权重提取亮度信息,从而得到灰度图像。灰度图像的每个像素的颜色值表示灰度,灰度的范围一般为0到255,用于表示色彩的浓淡程度和图像的特征信息。图3为原图,图4为灰度化后的图像,与彩色图像相比,灰度图像的数据量更小,内存占用更低,从而使得处理速度加快,这对于需要实时反馈的车道线检测尤其关键。此外,灰度化处理能够在视觉上提高图像对比度,更加突出车道线。
![](//html.hanspub.org/file/5-2571421x9_hanspub.png?20240311083923911)
Figure 2. Structure of lane detection algorithm
图2. 车道线检测算法结构
3.2. 内核程序
在OpenCL框架中,内核程序被用来在OpenCL设备上执行并行计算任务。这类程序通常使用OpenCL C语言编写,该语言借鉴了C99语言的语法,并额外加入了并行编程所需的语法扩展。本研究中所构造的内核程序包括高斯滤波内核、边缘检测内核以及霍夫变换内核,其创建和调用过程均通过OpenCL提供的API实现,具体流程如图5所示。该过程主要包括以下步骤:
![](//html.hanspub.org/file/5-2571421x12_hanspub.png?20240311083923911)
Figure 5. Creation and invocation of kernel programs
图5. 内核程序的创建和调用
步骤一:在当前系统上利用clGetPlatformInfo函数来查找所有可用的OpenCL平台,并基于此选择最适合运行OpenCL程序的平台。在选定的平台上,通过clGetDeviceIDs函数来查询和选定可用的OpenCL设备。
步骤二:利用clCreateContext函数创建上下文环境,该环境主要管理OpenCL执行环境中的程序、内存、命令队列和设备等。
步骤三:利用clCreateCommandQueue函数在特定上下文中为特定设备创建命令队列,该队列主要用于控制内核的执行和内存操作。
步骤四:利用clCreateBuffer函数在设备上创建内存对象,用于存储数据。
步骤五:利用clCreateProgramWithSource函数创建一个程序对象,并加载OpenCL C代码。然后,通过clBuildProgram和clCreateKernel函数,可以进行内核的编译和创建,将OpenCL C代码转换为可执行代码,同时内核函数与主机程序关联,以便后续主机程序执行内核。
步骤六:利用clSetKernelArg函数设置内核参数,以便在主机程序与内核之间进行数据交换。通过设定内核的相关参数,可以保证数据在主机与设备间的正确传输,以确保算法的准确性与正确性。
步骤七:利用clEnqueueNDRangeKernel函数,根据设定的工作组和工作项并行执行内核,使内核在GPU上运行。
步骤八:利用clEnqueueReadBuffer函数将内核执行完毕后的结果传输至主机。
步骤九:在内核执行完毕后,释放所有已分配的资源和对象。
在OpenCL异构编程模型中,这些函数协同工作以准备和管理在异构系统上运行的程序。它提供一个统一的编程环境使开发者能够充分利用异构平台上的计算资源,降低了编写并行和异构代码的难度,减少了开发周期。
3.2.1. 高斯变换内核
对经过灰度化的图像进行滤波处理是车道线检测算法中的重要步骤。滤波的目的是为了减少图像中由于各种外部条件(如树木阴影、光线变化、路面标记等)引起的噪声,而噪声可能会对车道线特征的提取产生干扰。有效的滤波可以提高图像质量,使得车道线特征更加突出,便于后续的边缘检测和车道线识别步骤。在车道线检测中,高斯滤波是一种较为常用的选择,因为它在去除噪声的同时,能较好地保留车道线的边缘特征,有利于后续的边缘检测算法的准确执行,因此本文选择使用3 × 3的高斯核对车道线图像进行滤波处理。
高斯滤波过程如图6所示,经过灰度化处理后的图像可以通过并行处理使用高斯滤波核进行处理,通过将图像数据划分为多个工作项,每个工作项负责处理图像的一部分,并利用并行计算的能力,可以同时对多个像素进行高斯滤波处理。这样的并行处理方式可以显著提高图像处理的速度和效率。每个像素点H (i, j)与3 × 3的高斯核进行卷积,得到新的像素值H * (i, j)。最后得到的高斯滤波后的图像如图7所示。
3.2.2. 边缘检测内核和感兴趣区域划分
边缘检测在图像处理中的作用是寻找灰度值波动较大的位置以生成二值化图像,如车道线与道路交界处的明显变化。常用的边缘检测算子包括Prewitt、Sobel、Roberts和Canny算子,其中Canny边缘检测算法是由John F. Canny在1986年开发的一个多级边缘检测工具,它旨在提供一个可靠的边缘检测算法,能够尽可能准确地检测图像中的边缘。在车道线检测的应用中,Canny算子因其优秀的检测性能和准确性而被广泛使用。
本文中的Canny边缘检测内核的流程主要分为三步。首先,使用Sobel算子对图像进行梯度计算,以获得图像中每个像素点的梯度强度和方向信息。其次,通过非极大值抑制的方法,对梯度图像进行处理,去除非边缘的噪点,使得边缘更加细腻。在这一步中,只保留梯度图像上局部极大值点,即将具有最大梯度值的像素点保留下来,其他非极大值点则被抑制掉。最后,将采用两个预设的阈值:一个高阈值和一个低阈值,来辨识和连接图像中的边缘。像素强度超过高阈值的将被标记为明确的强边缘,而那些低于低阈值的像素将被认定为非边缘区域。至于那些介于两个阈值之间的像素,它们会根据是否紧邻已确认的边缘像素来决定身份,与强边缘相连的将被视作边缘,反之则视为非边缘。
为减少后续霍夫变换步骤的计算量,在完成边缘检测之后,对图像执行了感兴趣区域选取和区域分割。由于车道线通常集中在图像的某些特定部分,将图像切割以仅留下可能包含车道线的片段,并专注于这些片段进行霍夫变换可以更精确地提取车道线数据。这一策略的实施有效减少了处理所需的计算资源并提高了车道线检测的效率。边缘检测及感兴趣区域提取的结果如图8所示。
![](//html.hanspub.org/file/5-2571421x15_hanspub.png?20240311083923911)
Figure 8. Results of edge detection and ROI extraction
图8. 边缘检测和感兴趣区域提取的结果
3.2.3. 霍夫变换内核
边缘检测经过之前的图像预处理后,下一步是对图像中的直线信息进行检测,需要采用霍夫变换将图像中被检测为边缘的像素点从几何空间转换到霍夫空间。在霍夫变换中,几何空间中的直线将被映射到参数空间的一个点。具体来说,对于图像中的每个边缘点存在通过该点的无数条直线,这些直线映射到在霍夫空间中是许多正弦曲线。然后,在霍夫空间中对这些正弦曲线通过的点进行累积投票,以确定霍夫空间中的峰值点。这些峰值点代表了在几何空间中可能存在的直线的参数。通过在参数空间中寻找峰值点并根据峰值点的大小可以判断在几何空间中是否存在直线。因此,霍夫变换将判断直线是否存在的问题转化为在霍夫空间中寻找峰值点的任务。通过找到霍夫空间中的峰值点,可以确定几何空间中的直线参数,从而实现直线的检测和提取。这种转换过程使得直线检测问题变得更加简单和直观,并且能够有效应对图像中的噪声和变形。它的原理如图9所示:
假设在图中的几何空间中的点(xi, yi)位于同一直线上,在x-y坐标系下的直线方程可以通过式(2)表达,其中直线的斜率用k表示,截距用b表示。那么通过点(xi, yi)的所有直线可以由式(3)表示,直线到原点的距离用r表示,x轴与直线的法线的夹角用θ表示。因此通过点(xi, yi)的所有直线经过式(3)的变换后都变成霍夫空间的正弦曲线,并且由于点(xi, yi)位于同一直线上,因此这些位于同一直线上的点(xi, yi)所对应的正弦曲线会相交于一点(r0, θ0)。通过寻找霍夫空间的峰值点就能得到点(r0, θ0),从而计算出点(xi, yi)所在的直线的参数,r0表示原点到直线的距离,θ0表示直线的法线与x轴的夹角。
(2)
(3)
因此在对边缘检测后得到的图像进行霍夫变换时,会对每个像素点进行判断和处理。对是边缘的像素点会根据其坐标信息进行霍夫变换,并在霍夫空间中进行投票,在所有边缘像素点完成投票后得到霍夫空间的数据。通过在霍夫空间中累积投票并设置大小合适的阈值,可以找到参数空间中的峰值点,这些峰值点对应着在几何空间中的直线。对于每个峰值点,可以通过反变换将其转换回几何空间,从而得到所需的直线的位置和方向。
3.3. 直线筛选聚类
通过Canny边缘检测与霍夫变换直线检测的配合使用,能够获得霍夫空间的投票数据。根据霍夫变换的结果进一步进行筛选和聚类,以获取更为精确的车道线参数。整个流程如下图10所示:
在得到霍夫变换后的数据后设置相应的阈值,将大于阈值的投票数对应的(r, θ)作为初步的车道线候选线的参数,由于候选线中包含大量的干扰线,为了得到准确的左右两条车道线需要进一步进行筛选。通过车道线候选线的θ参数,从而可以求出每条直线与水平方向的夹角。鉴于左右车道线与水平线的夹角通常位于特定区间,通过评估θ值的大小,可以有效地筛除一些噪声线条。之后会将具有相近(r, θ)参数的候选线判断为是同一条直线,并根据投票数num的大小对被判断为同一直线的(r, θ)参数做加权平均得到最终得车道线参数。得到最终得车道线参数后在原图中画出检测到得车道线如图11所示,可以看到该算法能很好的检测到左右两侧的车道线并在图中标注出来。
4. 车道线检测结果与分析
本文用以下实验装置验证基于OpenCL的车道线检测方法:PC机的CPU配置为12th Gen Intel(R) Core(TM) i3-12100 3.30 GHz,GPU配置为Intel(R) UHD Graphics 730,运行内存为16 GB,配置的OpenCL版本为OpenCL3.0,以C++作为编程语言。
为了对比CPU的处理时间,还配置了OpenCV3.2.0计算机视觉库,OpenCV是一个优秀的计算机视觉库,其中包含了许多针对图像处理和计算机视觉任务的优化算法和实现,这些算法通常经过了专门的性能优化和高效实现,它们的实现进行了相当彻底的优化,包括但不限于底层并行化、SIMD指令集优化、缓存友好的算法设计等。为了更多样的对比,在对图像灰度化,高斯滤波,边缘检测时决定采用OpenCV自带的函数,另外在对图像进行霍夫变换时采用C++编写的霍夫变换函数。车道线检测的结果对比如图12所示,可以看出两种方式检测的结果相差不大,都可以很准确的识别到车道线的位置,表明基于OpenCL的算法能达到CPU执行的算法的效果。
分别选用不同大小的图片进行处理时间的对比。平均每张图片基于OpenCL异构并行处理与CPU处理的车道线检测时间对比如表1所示。其中显示了使用不同方式检测车道线所花的时间,使用不同大小的图片进行了测试对测试时间取平均得到每张图片的处理时间,从结果可以看出基于OpenCL的检测方法对比单独使用CPU进行检测有着明显的加速作用,在对1280 × 720大小的图片进行检测时能达到5.497的加速比,加速比为使用CPU下算法运行时间与使用OpenCL下算法运行时间之比。
表2表示使用OpenCL与使用CPU处理过程各个步骤所消耗的时间,包括高斯滤波、边缘检测和霍夫变换3个过程使用的时间对比,OpenCL处理时只计算了内核所运行的时间,不包括CPU与GPU进行数据传输的时间。其中使用CPU进行高斯滤波和边缘检测时是直接采用OpenCV中的性能优化和高效实现对应函数进行处理,霍夫变换过程没有采用OpenCV中的函数,而是另外编写的C++函数,以此形成对比。使用OpenCL进行加速时采用C++编写的内核程序,从各个内核的处理时间来看,其中霍夫变换内核有着高达32.771的加速比,其它内核的加速比在2~4之间。这表明基于OpenCL的算法实现对比单纯使用CPU有明显的加速效果。
![](//html.hanspub.org/file/5-2571421x21_hanspub.png?20240311083923911)
Figure 12. OpenCL processing result (left), CPU processing result (right)
图12. OpenCL处理结果(左侧),CPU处理结果(右侧)
![](Images/Table_Tmp.jpg)
Table 1. Comparison of lane detection time
表1. 车道线检测时间对比
![](Images/Table_Tmp.jpg)
Table 2. Comparison of elapsed time of each kernel
表2. 各内核消耗时间对比
5. 结论
本文采用OpenCL异构计算编程模型实现了对传统车道线检测算法的并行加速,整个算法包括图像预处理、直线检测和直线参数筛选和聚类,并且能准确检测到图像中的车道线并进行标注。为了验证算法的加速效果,采用大小相同的图片分别使用OpenCL编程模型和单纯使用CPU进行处理,并对比了两种方法的处理时间。在对1280 × 720大小的图片进行车道线检测时整个算法相比与单纯使用CPU进行检测能达到5.497的加速比,平均检测一张图片只需要7.581 ms。算法中各内核函数的性能相比于使用CPU处理也有明显提升,其中霍夫变换内核的加速效果最好,达到了32.771的加速比,高斯滤波内核达到了3.463的加速比,边缘检测内核达到了2.891的加速比。经验证,算法大大缩短了检测时间,确保了车道线检测的实时性。