主要内容

壶穴检测

此示例扩展了使用双边滤波生成卡通图像示例包括计算质心和在检测到的坑洞上叠加质心标记和文本标签。

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

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

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

输入文件下载

这个例子使用了potholes2。Avi文件作为输入。该文件的大小大约为50 MB。从MathWorks网站下载该文件,并解压缩下载的文件。

potholeZipFile = matlab.internal.examples.downloadSupportFile (“visionhdl”“potholes2.zip”);[outputFolder, ~, ~] = fileparts (potholeZipFile);解压缩(potholeZipFile outputFolder);potholeVideoFile = fullfile (outputFolder,“potholes2”);目录(potholeVideoFile);

简介

PotHoleHDLDetector.slx系统如下所示。PotHoleHDL子系统包含壶穴检测器和覆盖算法,并支持HDL代码生成。有四个输入参数控制算法。processorbehavior子系统将字符映射写入RAM中用作覆盖标签。

modelname =“PotHoleHDLDetector”;open_system (modelname);set_param (modelname“SampleTimeColors”“上”);set_param (modelname“SimulationCommand”“更新”);set_param (modelname“开放”“上”);集(allchild (0)“可见”“关闭”);

FPGA子系统概述

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

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

输入参数值

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

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

Cartoon RGB参数更改覆盖的颜色,也就是基准标记和文本。

区域阈值参数设置检测窗口中标记像素的最小数量,以便将其归类为坑洞。如果这个值太低,则会检测到线状裂缝和其他不构成道路危害的缺陷。如果浓度过高,则只能检测到最大的危害。

最后一个参数Show Raw允许您更容易地调试系统。它切换显示的图像,在RGB输入视频和检测器看到的二进制图像之间绘制叠加。将此参数设置为1,以查看检测器的工作情况。

如果只允许在视频帧边界上进行更改,那么所有这些参数的工作效果最好。FrameBoundary子系统只在帧的有效起始处注册参数。

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

RGB,强度

模型分割输入RGB像素流,以便RGB流的副本继续朝向覆盖块。探测器的第一步是将RGB转换为强度。因为RGB的输入数据类型是uint8, RGB to Intensity块自动选择uint8作为输出数据类型。

双边滤波器

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

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

Sobel边缘检测

然后将过滤后的图像发送给Sobel边缘检测块,Sobel边缘检测块查找图像中的边缘并返回那些比梯度阈值参数强的边缘。输出是二值图像。在最终的应用程序中,可以根据路况、天气、图像亮度等变量设置这个阈值。对于这个模型,阈值是PotHoleHDL子系统的输入参数。

梯形的面具

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

操作的顺序在这里也很重要,因为如果您在边缘检测之前使用掩码,掩码的边缘将成为强线,这将在检测器上导致假阳性。

在输入视频中,车辆可能遇到坑洞的区域被限制在其正前方的道路和前方的梯形路段。准确的坐标取决于相机的安装和镜头。本例对该区域的左侧顶部、右侧顶部、左侧底部和右侧底部角使用固定坐标。在这个视频中,梯形的顶部和底部是不平行的所以这不是一个真正的梯形。

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

Ltc——rtc / \ / \ / \ lbc-------------rbc . txt

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

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

对于320x180的图像:

光栅= [320180];LTC = [155, 66];LBC = [1,140];RTC = [155, 66];加拿大皇家银行= [285179];%适合x = f(y)方便的LUT索引abl = polyfit ([lbc (2) ltc(2)]、[lbc (1) ltc (1)), 1);%左abr = polyfit([红细胞(2),清债信托公司(2)]、[红细胞(1),清债信托公司(1)),1);%的右边leftxstart = max(1、圆(ltc(2):红细胞(2))* abl (1) + abl (2)));rightxend = min(光栅(1)轮((ltc(2):红细胞(2))* abr (1) + abr (2)));startline = min (ltc(2),清债信托公司(2));红细胞endline = max (lbc (2), (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 Toolbox块强制输出数据为零,如像素控制总线输出中所示。虽然不是严格要求的,但这种行为使测试和调试更加容易。为了实现质心结果的这种行为,模型使用Switch块,其中常量块设置为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.mat十字=本(fiducialROM);十字丝(十字= =' 0 ') =' '%将'0'改为空格以更好地显示
十字= 31日×31 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 1”“11111111111111111111111”' 1 ' ' 1 ' ' 1 ' ' 1 '

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

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

字符叠加

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

由于字符数据通常由CPU用ASCII写入,最简单的方法是将字符数据存储在双端口RAM中的8位ASCII地址下。字体ROM存储ASCII字符33("!")到122 ("z")。该设计将地址偏移了33。

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

让角色形象化B在字体ROM中,以二进制显示。

负载charROM16x16.matletterB =本(charROM16x16 (529:544));%字符数组letterB (letterB = =' 0 ') =' '%删除'0'字符以更好地显示
letterB = 16×16字符数组的“111111111”“11111111111”“111 111年的111 111年的111 111年的111 111年的“1111111111”“111111111”“111 111年的111 111年的111 111年的111 111年的111 1111年的“11111111111”“111111111”
open_system ([modelname“/ PotHoleHDL / Overlay32x32”),“力”);

查看检测器原始图像

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

HDL代码生成

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

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

makehdl (“PotHoleHDLDetector / PotHoleHDL”

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

makehdltb (“PotHoleHDLDetector / PotHoleHDL”

您可以在FPGA上实现的这个模型的部分是帧到像素和像素到帧块之间的部分。这就是称为PotHoleHDL的子系统,它包含了探测器的所有元素。

在HDL模拟器中的模拟

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

FPGA的合成

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

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

要进一步

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

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

  • 梯形口罩块可以通过观察车辆的车轮位置和调整线性适合口罩的倾斜边来“操纵”。

  • 通过观察RGB图像的平均亮度或相对于周围路面的强度图像,探测器可以变得更强大,因为坑坑通常比周围区域的强度更暗。

  • 凹坑的可视频率谱图也可用于寻找凹坑中特定类型的表面。

  • 利用梯形巷道区域的平均强度计算出探测面积阈值。

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

结论

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

参考文献

科赫,克里斯蒂安和约阿尼斯·布里拉基斯。沥青路面图像中的坑洞检测。先进的工程信息25岁,没有。3(2011): 507 - 15。doi: 10.1016 / j.aei.2011.01.002。

[2]奥马诺维奇,萨米尔,埃米尔·布扎和阿尔文·胡塞诺维奇。基于图像处理和光谱聚类的坑洞检测。第二届信息技术和计算机网络国际会议(ICTN '13),土耳其安塔利亚。2013年10月。

Baidu
map