刘金清,陈存弟
1(福州外语外贸学院,福州 350202)
2(福建师范大学 光电与信息工程学院,医学光电科学与技术教育部重点实验室,福州 350007)
车道偏离检测和前向车距检测的目的是防止无人车偏离本车道或者与前方车辆距离较近时发生交通事故.近年来,国内外学者基于机器视觉的方法对车道偏离[1-4]和车距检测技术[5-7]展开了相应的研究.本文在前人研究的基础上,实现了车道偏离和车距检测算法的改进与仿真,并移植到嵌入式平台上测试.
车道偏离检测算法和车辆前向车距检测算法均需要通过相机采集的图像重建出三维世界,以此算出客观世界中的真实数据.在机器视觉中,三维重建可以定义为根据图像坐标系与世界坐标系的转换关系进而计算到相机参数,进一步推导出图像坐标与世界坐标系的关系,因此车道偏离检测与防撞检测的首要条件是相机标定.本文采用张氏相机标定方法[8].
相机标定的理论推导涉及4 种坐标系,分别是以像素为单位的像素平面坐标系(u,v);表示每毫米包含的像素数量的图像物理坐标系(x,y);相机坐标系(Xc,Yc,Zc)和世界坐标系(Xw,Yw,Zw).如图1 所示.
图1 坐标映射模型
(1)图像物理坐标系到像素坐标系的转换
图像像素坐标系(u,v)中的u和v分别表示行和列,其坐标原点在图像的左上角.图像物理坐标系(x,y)的x和y分别与图像像素的u、v轴平行,相机的光心与像平面的交点为坐标原点.假设光心对应的图像平面坐标为(u0,v0),dx表示x方向每个像素的毫米宽度,dy表示表示y方向每个像素的毫米宽度,式(1)为图像坐标系转换为像素坐标系.
(2)相机坐标系到物理坐标系的转换
光心是相机坐标系(Xc,Yc,Zc)的原点,Zc轴与光轴重合且方向相同,Xc与Yc轴各自平行于图像物理坐标系的x和y轴.令相机的焦距为f,相机坐标系与像素坐标系的关系式为式(2)所示.
(3)世界坐标系到相机坐标系的转换
世界坐标系(Xw,Yw,Zw)到相机坐标的转换实质上是平移和旋转的过程,其中旋转矩阵T为三维平移矢量,旋转矩阵R为3×3 的正交单位矩阵,其转换关系为式(3)所示.
整合4 个坐标系的转换关系,可以得出像素坐标系与世界坐标系的变换过程,其转换过程为:
式(4)中包 含 有fdx、fdy、u0、v0等4 个 相关参数,[R,T]是相机的外参矩阵.在相机的内参数已知的情况下,就能得到像素坐标与世界坐标之间的投影矩阵P=A[R,T].因此,对于世界坐标上的任意点M(Xw,Yw,Zw)可以计算出对应的像素坐标(u,v),但是P具有不可逆性,不能用已知的像素坐标推导出世界坐标,而在车道偏离检测与车距检测中均需要从像素坐标计算出世界中客观的物理量,这就需要在已知相机内外参数情况下再次建立相应的路面模型计算出相关的物理量.
(4)求解相机畸变参数
在几何光学和阴极射线管显示中,畸变是对直线投影的一种偏移,即一条直线投影到图片上并不是以直线的形式投影在图像上.一般将畸变分成对图像的投影影响较大的径向畸变和切向畸变,其表达式为:
(5)OpenCV 上的相机标定
张氏标定法简单稳定,因此得到广泛的使用.具体标定步骤如下:
① 制作棋盘标定板:在固定的相机角度下,拍摄不同角度,多尺度且旋转多变的棋盘图像20 张,棋盘格数为9×5.
② 令棋盘的左上角为世界坐标原点,初始化棋盘格上所有角点的世界坐标,且Xw轴与Yw轴分别对应棋盘的长和宽,Zw=0,每个棋盘格的长宽为30×30 mm,如图2 所示.图3 为检测到的棋盘角点结果.
图2 棋盘世界坐标
图3 棋盘角点坐标
③ 引用calibrateCamera()函数计算相机的内外参数和畸变参数得到的标定参数为:
畸变系数:
相机内参矩阵:
车距检测模型,如图4 所示.假设相机能够获取的路面区域为ABCD,路面E点投影在图像最顶边的Eo点上;F点是相机刚好拍到靠近相机的路面边界处,其投影在图像最底边Fo点上,G点是相机光心射向的路面焦点,该点投影在图像的o点处;路面上随意的P点投影在Po点处;Q点表示相机的位置,h、ZF和ZG可用尺子测量.∠ZQF=γ ,∠FQG=β,∠TQG=α.假设P点是检测到的车辆,计算车距即是求解路面上ZP距离,Z是相机在路面上的投影点.
图4 路面车距检测模型
根据图4 的路面建模图,结合相机成像规则,可以得到以下关系:
本文在实验室通过模拟车道来测试算法的可靠性.相机光心投影在图像上的像素坐标为(u0,v0)=(268.62,192.25),x方向的焦距为fdx=885.78,y方向的焦距为fdy=882.80,相机距离地面的高度为h=690 mm,通过实地测量相机投影在路面与图像最低边在真实路面上的距离为ZF=2050 mm.
图5 中随机的路面坐标Po(300,295),投影在真实路面上的数据为:PT=197.13 mm,ZT=5520.95 mm,通过欧氏公式随机路面点到相机的距离为:ZP=5524.47 mm,实际距离为5400 mm.模拟的车辆位置与相机的偏离角度为右偏2.05 度.计算结果与实际测量的结果之差仅为| 5524.47-5400|=124.47 mm.
图5 畸变校正与路面测距模拟结果图
表1 中的距离结果以mm 为单位,角度单位为度,从模拟路面上的6 组数据中可以看出,实际值与测量值的误差较小,在10 m 内的误差控制在200 mm 内,说明本文建立的车距测量模型较准确.在实际的高速路面上,安全车距不少于50 米,可以通过本文的算法设置固定的车距安全阈值来实现车距安全检测.
表1 无人车相对于光轴的偏航角和车距测量表
由于无人车驾驶过程中容易出现偏航现象,如果不及时调整方向便会偏离到其他车道.此外,车辆压到分道线导致左轮或者右轮偏离在其他车道中,将影响其他车辆的正常运行,甚至导致不可预知的交通事件,因此需要车道偏离提示.车辆准备超车时会提前打开左转向灯,所以,无人车在没有检测到左转向灯打开时,车道偏离报警系统才会发挥相应的警报作用.
无人车正常行驶时,行驶方向与左右分道线趋近平行,因而,可以利用车道俯视图模型来计算出偏航的角度和车辆与左右分道的边距,以做出相应的报警信息反馈.
CCP 算法需要预知无人车的横向宽度bc和车道宽度bl,标准高速公路的车道宽度为3.75 m,可以通过式(6)判断车道偏离情况.y0表示无人车中心与车道中线的距离.如果△y1<0 或△y2<0,则认为是车道偏离;如果 △y1>0 和△y2>0则认为是无人车在当前行驶的车道内.如果判别到无人车是左偏离,那么如图6 所示,可知 △y1是 车辆与左分道线的距离,△y2是车辆与右分道线的距离;如果判别到无人车是右偏离,那么 △y1是车辆与右线的距离,△y2是车辆与左线的距离.
图6 CCP 车道偏离检测
相机的光心在图像上的坐标为(u0,v0),因此图像中坐标点Fo(u0,Ih)为相机光轴投影在地面上投影的点,Ih是图像的高,Iw为图像的宽.如图7 所示,是一张车身右偏而行驶方向偏左的图像,图中L1和L2是左右车道线,L3是L1和L2交叉角的平分线,Pt(u,v)是L3上任意一点,L3与 图像底边的交点为V(u,v).
图7 车向偏离示意图
如图8 所示,在路面上建立一个路面坐标,以分道线平行的中线为正向y轴,无人车所在的位置横向为x轴,右方向为正,其中θ 是无人车的偏航角,∠FVoPo=φ,Ib是相机成像后靠近车辆的底边,Vo、Po分别是图像中V、Pt点的实际路面投影点,Po为随机投影点,像素坐标中直线u=u0与车道平分线的交点投影在路面上,即是图中Po点.
图8 车辆偏离俯视图模型
(1)无人车偏航角的计算
① 余太武[9]计算左右车道的角平分线作为车道中线,而本文计算车道中线的方法是基于左右车道斜率和截距求平均的方法.
如图9 所示,基于角平分线求解车道中线的方法存在误差,而基于式(7)求解的结果正确.
图9 求解车道中线的比较
② 基于2.1 节介绍的路面建模图像,我们随机取车道中线上的某点Pt,接下来,计算出车道中线上V点坐标,分别计算出Fo, V,Pt,分别对应在路面上的F,Vo,Po点 ,以此计算出实际路面上的距离|FVo|、 |PoVo|和|FPo|.
根据余弦定理求∠FV0P0=φ:
③ 计算偏航角:
(2)无人车与左右分道线的距离计算
② 若Fo.u>V.u,可初步判断为车辆向左偏离车道中线.
无人车距左分道线距离为:
无人车距右分道线距离:
③ 若Fo.u<V.u,可初步判断为车辆右偏离车道中线
无人车距左分道线距离:
无人车距右分道线距离:
获取到无人车与左右分道线的偏离距离和偏航角后,就可以设定相应的阈值来判断当前无人车的行驶状况.如图10 所示,沿车道方向分割成安全区域和报警区域.对于一般小车宽度为1.5-1.8 m 之间,标准高速路宽度为3.7 m.本文设置车辆与左右分道线0.5 m范围内为报警区,车道中间2.75 m 内为安全区.
图10 车道安全区域与报警区域的划分
如图11 所示为两帧车道偏离检测结果,其中第1 行输出为车辆左轮与左分道线的间距和右轮与右分道线的间距;第2 行输出为车辆行驶方向与车道中线的偏航角,当偏航角小于5 度时表示行驶方向正常.第3 行表示车辆当前的运行状态,只有当偏航角、无人车与左右分道线的间距不超过设定的安全阈值时才会断定为正常行驶.
图11 车道偏离检测结果
如图12 所示,本文实验模拟的车道宽度为120 cm,车辆宽度为36 cm,相机投影在地面到图像底边的实际地面边界的距离为205 cm,其高为70 cm,模拟得到的结果为表2 和表3.
图12 模拟偏航试验图
表2 无人车相对于车道的偏航角(度)
表3 无人车与左右分道线距离
TI 公司的DM3730[10,11]整合了具有控制优势的ARM 核和具有运算优势的DSP 核.DSP 端依靠DSP/BIOS 操作系统来支持音视频算法,ARM 端依靠Linux 系统来控制芯片的外部设备,而ARM 与DSP 双核之间的数据传输与通信则依赖Codec Engine 架构来管理[12].ARM+DSP 框架如图13 所示.
图13 DSP+ARM 双核框架
(1)处理器:DM3730 处理器.
① Pin-to-Pin 兼容DM3730 系列处理器.
② 1000-MHz 主频ARM CortesxTM-A8 内核.
③ 800-MHz DSP TMS320C64x+TM 内核.
④ 片内集成存储器用于ARM CPU(16 KB ICache,16 KB D-Cache,256 KB L2 Cache)和片上存储(64 KB SHared SDRAM,112 KB ROM).
(2)存储器:Micron mDDR 与NandFlash 集成芯片.
① 256 MByte 32 位mDDR 133 MHz.
② 512 MByte 16 位Nand Flash.
(3)视频接口、USB 接口、音频插座、调试接口、SD/MMC 插座、电源接口、串口插座、扩展接口、网络接口.
搭建软件开发平台的资源有:VirtualBox;uBuntu V10.04;PC 端的超级终端Tera Term Pro.
安装TI 提供的支持音频和视频算法的DVSDK组件包,该包含有各算法支持库和各支持库的调用管理引擎(Code Engine),以及XDM 算法的编译工具xdctools,同时提供了音频、视频算法进行编解码的例程以供参考.利用该包可以很方便地开发DSP 下的图像语音处理软件,并且实现ARM 与DSP 之间的联系.Codec Engine 是DVSDK 组件包的核心模块,是ARM 和DSP 的通信与数据传输桥梁,过渡于ARM 应用层和DSP 信号处理层之间.该模块要与DSP 端建立的Codec Engine 服务器进行通信需要使用DSP/BIOS、DSP Link、DSP 算法接口的标准xDIAS[13]和XDM 协议.为了发挥DM3730 的双核作用,Codec Engine、DSP Link、xDIAS 和XDM 是软件中不可缺少的部分.
DM3730 开发板可以从板载的NandFlash 中启动,也可以从SD 卡的Fat32 分区中启动.无论是从板载的NandFlash 中启动还是从SD 卡启动,都需要用XLoader对开发板进行一些初始化工作,接着从NandFlash/SD中读取Uboot 程序到存储器,然后Uboot 从NandFlash/SD卡读入启动参数,加载Linux 内核uImage 到存储器,解压缩后运行,直到Linux 内核启动后,重新初始化DM3730 板,加载NandFlash/SD 卡上的FileSystem,执行FileSystem 中的程序并启动控制台.由此可见,开发板上的Xloader、Uboot、uImage 和文件系统在整个启动过程是层层依赖的关系.
安装DVSDK 组件包后有自带的交叉编译器—arm-arago-linux-gnueabi-gcc.只需将DVSDK 组件包中的交叉编译器的安装路径添加在用户目录中的.bashrc文件中即可.
TFTP 网络能将编译的程序和数据烧写到目标版上运行,或将目标版上文件或者运行结果上传到Linux主机端.tftp 工作目录在/tftpboot,在文件传输过程中,均需要先将文件拷贝到该目录下,然后才能在超级终端Tera Term Pro 中使用以下命令实现uBuntu 和目标板中文件的传输:
(1)tftp -g -r fileName uBuntu 的IP 地址
(2)tftp -p -l fileName uBuntu 的IP 地址
(3)g:get,-r:remote,-p:put,-l:local
OpenCV 开源的视觉库提供了丰富的图像处理算法,在各大操作系统上均可编译通过生成相应的执行文件,因此,这些代码只要经过适当修改和编译便可移植在嵌入式系统中.
EMCV 库基于C 语言实现,能运行于TI DM64x系列DSP 中,移植EMCV 相当于把OpenCV 中少部分算法移植到DSP 中[14].
在DM3730 的ARM 应用程序中调用交叉编译后的OpenCV 接口函数,而在DSP 端调用EMCV 接口函数.适用cmake 交叉编译OpenCV 库之前,需要编译安装ffmpeg 资源包、libx264 和libxvid 两个库、汇编编译器yasm,以及libpng 和libjpeg 库,OpenCV 才能读取和显示png 和jpeg 格式图片,而libpng 库的安装依赖于zlib 库.
所有库的安装目录均设置在交叉编译的目录中,且将编译安装后的生成库通过tftp 网络传送到目标板的lib 目录上.至此,就可以实现在DM3730 目标板的ARM 端调用OpenCV 库函数了.
本文使用Qt 开发图形界面对处理后的视频在LCD 上显示.先在Qt 中的项目文件.pro 中添加OpenCV的头文件路径和库文件.编译后生成的二进制文件传送到目标板的文件系统上就可以在ARM 端调用OpenCV 函数接口,处理后的结果使用Qt 来显示.
使用Codec Engine 作为ARM 和DSP 的连接桥梁,模仿Codec Engine 自带的video_copy 例程来添加算法.针对EMCV 的移植,将EMCV 的文件添加到video_copy 中,并在配置文件中添加EMCV 的文件名.车道识别和车辆检测算法移植后,进而测试本文的车道偏离检测和车距安全检测算法,得到的效果良好.
TI 的DVSDK 组件包提供了Codec Engine 软件模块来实现ARM 和DSP 的通信和协同工作.Codec Engine 是一组应用程序编程接口,用于实例化和运行xDAIS 算法,还有VISA(Video,Image,Speech,Audio)接口,用于与xDM 兼容的xDAIS 算法进行交互[15,16],使ARM 端的Linux 可以调用VISA 标准接口来管理ARM 与DSP 的软件.如图14 所示,Codec Engine 框架中,Server 集成Codec 端算法,DSPLink 模块隐藏了APP 调用Server 端算法的整个过程,因此在实例应用中只能看到Server 和APP 端.
图14 ARM 与DSP 的通信框架
如图15 所示,ARM 应用程序调用Codec Engine的VISA API 接口,VIDENC_process(a,b,c)传递a,b,c参数,Codec Engine 的stub 会把参数a,b,c以及VISA 接口信息封装处理,利用消息队列msgq 传递给DSP 端.DSP 端的skeleton 解开这个封装包,把ARM端的参数a,b,c(虚拟地址)转换成DSP 端的参数x,y,z(物理地址).DSP 端的处理process 中的请求即能实现ARM 端VIDENC_process(a,b,c)函数的操作[17,18].
图15 ARM 和DSP 通信的函数传递
图16 为本文算法移植在DM3730 平台上的运行结果.已知采集高速车道视频的相机内外参,使用本文的车距模型和车道偏离模型,计算的车距和车道偏离角度均显示在图片上.车辆正常行驶拍摄到的视频得到的检测结果良好.
图16 本文算法在DM3730 平台上的运行结果图
本文的车距检测模型[19],不但能够检测前方车辆与无人车的距离,还能计算出前方车辆相对于相机光轴的偏转角度.基于CCP 车道偏离算法,建立车道偏离模型,实现了无人车当前位置和相对于分道线的偏航角的计算,并设定无人车在车道上的安全区和警报区实现车道偏离的及时报警.对于车距的建模,在实验室模拟车道计算路面上的随机点,得到的误差较小,稳定性较好.对于车道偏离检测,模拟高速路车道搭建车道偏离模型,计算车辆偏离车道的偏航角且车辆与左右分道线的距离,检测误差范围小,准确性较高.还使用运行状况良好的高速路视频测试本文算法,偏离反馈均显示正常.尽管本文采用先进的ARM+DSP 框架实现车辆动态图像识别的系统设计,且采用Codec Engine 框架实现ARM 和DSP 的通信,实验过程稳定性较高,但是在嵌入式平台内存和运行主频有限且运行算法尚未优化的情况下难以实现算法的实时性处理,因此有待完善运行平台,更好地协调车道检测、车辆检测与跟踪、车道偏离检测和车距检测4 个模块.有待进一步使用本文的算法在路面上测试.