主要内容

壶穴检测

这个例子扩展了使用双边滤波生成卡通图像示例包括计算质心和在检测到的凹坑上覆盖质心标记和文本标签。

道路危险或坑洞检测是任何自动驾驶系统的重要组成部分。之前[1]在自动路面凹坑检测上的工作将凹坑定义为路面上的一个椭圆形区域,其亮度级别较暗,纹理与周围路面不同。利用图像处理检测坑洞的任务是在路面图像中找到符合所选标准的区域。你可以使用任何或所有的椭圆形状,较暗的亮度或纹理标准。

要测量椭圆形状,可以使用霍夫圆等投票算法,或模板匹配算法,或基于线性代数的方法,如最小二乘拟合。在图像处理中,通过选择一个亮度分割值来测量亮度水平是一种简单的方法。纹理可以通过使用FFT等技术计算区域的空间频率来评估。

这个例子使用一个面积度量的亮度分割,这样较小的缺陷不会被检测到。为了找到缺陷的中心,本设计计算了质心。模型在缺陷的中心覆盖一个标记,并在图像上覆盖一个文本标签。

介绍

PotHoleHDLDetector.slx系统如下所示。pothololhdl子系统包含坑洞检测器和覆盖算法,并支持HDL代码生成。金宝app有四个输入参数控制算法。ProcessorBehavioral子系统将字符映射写入RAM中作为叠加标签使用。

modelname ='potholehdldetector';open_system (modelname);set_param (modelname“SampleTimeColors”“上”);set_param (modelname“SimulationCommand”“更新”);set_param (modelname“开放”“上”);集(allchild (0)'可见的''离开');

FPGA子系统概述

pothololhdl子系统将RGB输入视频转换为强度,然后进行双边滤波和边缘检测。梯形掩模子系统选择巷道区域。然后,该设计应用形态关闭,并计算所有潜在的凹坑的质心坐标。检测器在每一帧中选择最大的凹坑并保存中心坐标。像素流对齐器将坐标的时间与输入流匹配。最后,Fiducial31x31和Overlay32x32子系统在框架上应用alpha通道覆盖,添加凹坑中心标记和文本标签。

open_system ([modelname' / PotHoleHDL '],“力”);

输入参数值

子系统有四个可以在系统运行时更改的输入参数。

梯度强度参数,梯度阈值,控制算法的边缘检测部分。

Cartoon RGB参数改变覆盖层的颜色,即基准标记和文本。

区域阈值参数设置检测窗口中标记像素的最小数量,以便将其分类为凹坑。如果该值过低,则会检测到线形裂缝和其他不属于道路危害的缺陷。如果它太高,那么只有最大的危险才会被检测到。

最终参数显示RAW,允许您更轻松地调试系统。它会切换在RGB输入视频和检测器看到的二进制图像之间绘制叠加的显示图像。将此参数设置为1以查看检测器是如何运行的。

如果只允许在视频帧边界上更改,那么所有这些参数都能发挥最佳效果。FrameBoundary子系统只在帧的有效开始时注册参数。

open_system ([modelname“/ PotHoleHDL / FrameBoundary”],“力”);

RGB至强度

该模型分割输入RGB像素流,使得RGB流的副本继续朝向覆盖块。检测器的第一步是从RGB转换为强度。由于RGB的输入数据类型是uint8,RGB对强度块自动选择uint8作为输出数据类型。

双边滤波器

该算法的下一步是降低高视觉频率噪声和更小的道路缺陷。有许多方法可以实现这一点,但使用双边滤波器具有在减少噪声和更小的区域的同时保留边缘的优点。

双边滤波器块具有邻域大小和两个标准差的参数,一个用于滤波器的空间部分,一个用于滤波器的强度部分。对于这个应用程序,一个相对较大的9x9区域就可以了。该模型使用3和0.75作为标准差。您可以稍后使用这些值进行试验。

Sobel边缘检测

然后将滤波的图像发送到Sobel边缘检测块,该Sobel边缘检测块地找到图像中的边缘,并返回比梯度阈值参数更强的那些边缘。输出是二进制图像。在最终应用程序中,可以基于该型号,天气,图像亮度等的变量来设置此阈值。阈值是PotholeHDL子系统的输入参数。

梯形的面具

从二值边缘图像中,您需要删除任何与凹坑检测无关的边缘。一个好的策略是使用蒙版,选择一个感兴趣的多边形区域,并使该区域之外的黑色。该模型不使用正常的ROI块,因为那样会删除稍后用于质心计算和标记所需的位置上下文。

操作顺序也很重要,因为如果在边缘检测前使用掩码,则掩码的边缘将成为强的线路,导致探测器处的误报。

在输入视频中,车辆可能遇到坑洞的区域仅限于立即在其前方的道路和前方道路的梯形部分。精确的坐标取决于相机安装和镜头。此示例使用该区域的左侧顶部,右侧顶部,左侧底部和右侧底角的固定坐标。对于该视频,梯形区域的顶部和底部不平行,因此这不是真正的梯形。

面具由角之间的直线组成,连接左、右和上、下。

——rtc / \ / \ lbc-------------rbc

这个示例使用polyfit以确定从角到角的直线拟合。为了易于实现,设计调用polyfit垂直方向作为独立变量。这种用法计算x = f (y)而不是更平常的y = f (x).使用polyfit这种方式允许您使用y方向的行计数器作为查找表的输入地址,该查找表包含每一行感兴趣的区域的起始(左)和结束(右)的x坐标。

查找表通常在FPGA中的BRAM中实现,因此应该以基于0的寻址解决。该模型从Matlab 1的寻址转换为LUT之前的基于0的寻址。为了进一步减小查找表的大小,地址由梯形的起始线偏移。为了获得良好的合成结果,在查找表之后使用寄存器匹配在FPGA中注册的典型块RAM。该寄存器还为设计添加了一些适度的流水线。

对于320x180图像:

栅格= [320,180];LTC = [155,66];LBC = [1,140];RTC = [155,66];RBC = [285,179];%适合于x = f(y)方便的LUT索引ABL = Polyfit([LBC(2),LTC(2)],[LBC(1),LTC(1)],1);%左ABR = Polyfit([RBC(2),RTC(2)],[RBC(1),RTC(1)],1);%的右边左撇子= MAX(1,圆形((LTC(2):RBC(2))* ABL(1)+ ABL(2))));RightXend = min(光栅(1),圆形((LTC(2):RBC(2))* ABR(1)+ AB(2))));startline = min(LTC(2),RTC(2));终点= MAX(LBC(2),RBC(2));%正确到基于零的寻址Leftxstart = Leftxstart - 1;Rightxend = Rightxend - 1;Startline = Startline - 1;Endline = Endline - 1;open_system ([modelname'/ potholehdl / trapezoidalmask'],“力”);

形态学关闭

接下来的设计使用形态学关闭块来删除或关闭小特征。关闭工作首先做膨胀,然后侵蚀,并帮助删除小特征,不太可能是坑。指定块掩码上的邻域,该邻域决定要删除的特征的大小。这个模型使用了一个5x5的邻域,类似于一个磁盘,这样小的特征就被封闭起来了。

重心

质心计算找到活动区域的中心。设计在每个31x31像素区域连续计算标记区域的质心。它只存储检测区域大于输入参数时的中心坐标。这是硬件和软件系统之间的一个共同区别:在为fpga设计硬件时,通常更容易连续计算,但只在需要时存储答案,而不是在软件中根据需要调用函数。

质心计算,你需要计算区域图像的三件事:像素的加权和在水平方向,垂直方向的加权和,和整体的和对应的所有像素的面积显著的部分地区。Line Buffer选择31x31像素的区域,每次返回一列。该算法使用列来计算垂直权重和总权重。对于水平权重,设计组合列以获得31x31的内核。您可以根据您想要的“中心”的含义来选择权重。这个示例使用15:15所以31x31区域的中心是(0,0)在计算结果中。

当输出无效时,Vision HDL工具箱块强制输出数据为零,如pixelcontrol总线输出所示。虽然不是严格要求,但这种行为使测试和调试更加容易。为了实现质心结果的这种行为,模型使用Switch块,并将Constant块设置为0。

由于您希望检测到的区域的中心相对于整体图像坐标系,因此将水平和垂直像素计数添加到计算的质心。

open_system ([modelname'/ potholehdl / centroid31'],“力”);

open_system ([modelname'/ potholehdl / centroid31 / centroidkernel'],“力”);

检测并保存

检测器作用于从质心开始的总面积和。检测器本身很简单:将质心面积值与阈值参数进行比较,找出大于阈值的最大面积。模型逻辑将存储的区域值与当前区域值进行比较,并在输入大于当前存储值时存储一个新区域。通过使用>或者> =您可以选择最早的阈值或阈值的最新值。该模型存储最新值,因为稍后的值更接近相机和车辆。当探测器存储新的获胜区域值时,它还更新对应于该区域的X和Y质心值。然后将这些坐标传递给子系统的对齐和覆盖部分。

要将X、Y和有效指示传递给对齐算法,请将值打包到一个23位的单词中。一旦它们与用于叠加的输入帧及时对齐,模型就会将它们解压缩。

open_system ([modelname“/ PotHoleHDL / DetectAndHold”],“力”);

像素流控制器

像素流对齐块从检测器获取流信息并将其和原始RGB像素流发送到覆盖子系统。对齐器补偿由检测算法的所有前面部分所增加的处理延迟,而不需要知道任何关于这些块的延迟。如果稍后更改邻域大小或添加更多处理,对准器可以进行补偿。如果总延迟超过最大行数参数,请调整参数。

基准的叠加

基准标记是表示为31位固定点数的31元件阵列的方形掩模版。此表示方便,因为单个读取返回每行的整个覆盖像素的整个单词。

该图通过将定点数据转换为二进制显示了覆盖模式。这个图案可以是任何你想要的31x31尺寸。

负载fiducialROM31x31.matCrosshair = Bin(Fiducialrom);Crosshair(Crosshair ==' 0 ') =' '%将“0”更改为空间以获得更好的显示
十字= 31 x31 char数组' 1 ' ' 1 ' ' 1 ' ' 1 '“11111111111111111111111”“1 1 1”“1 1 1”“1 1 1”“1 1 1”“1 1 1”“1 1 1”“1 1 1”“1 1”“1 1”“1 1”“111111111111 111111111111”“1 1”“1 1”“1 1”“1 1 1”“1 1 1”“1 1 1”“1 1 1”“1 1 1”“1 1”的1 1 1 ' 11111111111111111111111 ' ' 1 ' ' 1 ' ' 1 ' ' 1 '

基准叠加子系统有一个水平和垂直计数器,其中有一组四个比较器,比较器使用被检测区域的中心作为区域的中心作为标记。标记数据被用作开启alpha通道覆盖的二进制开关。alpha值是一个固定的透明参数,在ExpandData子系统中,当二进制Detect信号被解包时,它作为增益应用于该信号。

open_system ([modelname'/ potholehdl / fiducial31x31'],“力”);

字符叠加

用于屏幕显示的字符字体ROM以类似于上述基准ROM的方式存储数据。每个16位固定点数表示16个连续的水平像素。字符映射为16x16。

由于字符数据通常由ASCII中的CPU写入,因此最简单的方式是将字符数据存储在双端口RAM中的8位ASCII地址下。字体ROM将ASCII字符33(“!”)存储到122(“Z”)。该设计将此地址抵消33。

字体ROM是由公共领域的固定宽度字体构建的,经过几次编辑以提高可读性。在基准标记中,字符ROM数据被用作开启alpha通道覆盖的二进制开关。字符alpha值是一个固定的透明度参数,在ExpandData子系统中,当Detect信号被解包时,它作为增益应用于该信号。

将字符形象化B在字体ROM中,以二进制显示它。

负载charrom16x16.matletterB =本(charROM16x16 (529:544));%字符数组letterB (letterB = =' 0 ')=' '%删除'0'字符以更好地显示
letterb = 16x16 char数组'''111111111''111111111''11111111''111 11111''11111111''111111111''111111111''111 111''111 111''111 111''111 111 111 111''''11111111''111111111'111111111'
open_system ([modelname“/ PotHoleHDL / Overlay32x32”],“力”);

查看探测器原始图像

当您处理复杂的算法时,查看处理过程中的中间步骤对调试和探索非常有帮助。在这个模型中,您可以设置布尔值显示原始参数为1(真的)为了显示二进制图像的形态学关闭的结果,具有检测结果的覆盖层。要将二进制图像转换为8位RGB叠加层,模型将二进制值乘以255并使用所有三种颜色通道上的该值。

HDL代码生成

要检查和生成此示例中引用的HDL代码,必须具有HDL Coder™许可证。

要生成HDL代码,请使用以下命令。

makehdl (“PotHoleHDLDetector / PotHoleHDL”

要生成测试工作台,请使用以下命令。注意,由于数据量大,测试台生成需要很长时间。您可能希望在生成测试台之前减少模拟时间。

makehdltb(“PotHoleHDLDetector / PotHoleHDL”

该模型中可以在FPGA上实现的部分是帧到像素和像素到帧块之间的部分。这个子系统叫做pothololhdl,它包含检测器的所有元素。

在HDL模拟器中的仿真

现在有了HDL代码,就可以在HDL模拟器中模拟它了。自动生成的测试台允许您证明Simulink仿真和HDL仿真匹配。金宝app

FPGA的综合

还可以在FPGA合成工具(如Xilinx Vivado)中合成生成的HDL代码。在Virtex-7 FPGA (xc7v585tffg1157-1)中,该设计实现了超过150 MHz的时钟速率。

利用报告显示,双边滤波器、像素流对准器和质心函数消耗了本设计的大部分资源。双边滤波器需要最多的dsp。质心实现非常高效,只使用两个dsp。质心计算还需要一个对等的查找表,因此使用大量的lut作为内存。

更进一步

这个例子展示了一种检测凹坑的算法的可能实现。本设计可以通过以下方式进行扩展:

  • 可以使用灰色世界模型从平均亮度计算梯度阈值。

  • 梯形遮罩块可以通过查看车辆车轮位置和调整线性适合的坡面遮罩,使“可操纵”。

  • 检测器可以通过查看相对于周围路面的RGB或强度图像的平均亮度,使其更加健壮,因为坑洞的强度通常比周围区域更暗。

  • 坑洞的视觉频谱图也可以用于寻找坑洼的特定类型的表面。

  • 可以使用梯形道路区域中的平均强度来计算检测区域阈值。

  • 通过存储前N个响应而不是仅存储最大检测响应,可以在一帧中检测多个凹坑。基准标记子系统需要稍微重新设计,以允许重叠标记。

结论

该模型显示了如何在FPGA中实现Pothole检测算法。该检测器的许多有用部分可以在其他应用中重用,例如质心块和基准和字符覆盖块。

参考

[1]科赫,克里斯蒂安和伊阿尼斯·布里拉基斯。“沥青路面图像中的坑洞检测”。先进的工程信息25,不。3(2011):507-15。DOI:10.1016 / J.Aei.2011.01.002。

Omanovic, Samir, Emir Buza和Alvin Huseinovic。基于图像处理和光谱聚类的坑洞检测。第二届信息技术和计算机网络国际会议(ICTN’13),土耳其安塔利亚。2013年10月。