该脚本用于对局部特征子图进行处理
参考广汽研究院发表的论文复现了其对应的算法并做了改进,由于在停车位识别方面,传统图像处理的算法效果并不好,真的要使用,还是要采用带有深度学习的方案
背景技术
这一章由于其特殊性和数学推导的复杂,很难写得很细。我在此只叙述实现的一些方法和一些意见。具体的工程,在附件中有多份深度学习的源码,可以研究和使用。
传统的方案是采取直线检测来做的,在AVM图像里,用二值化之后利用霍夫变换来对直线进行检测,可能还会用到聚类算法等,最后来拟合构成车位。
但是这一大类利用传统图像处理的方法准确率都偏低,很容易漏检或者混检。
利用深度学习的方法,缺点是必须要使用带算力的SoC,价格一定是相对昂贵的,不管是GPU还是NPU,严重依赖硬件加速,即使对模型进行量化压缩,想要高效又准确也是个难题。
并且各家都在主推自己的工具链,想要在激烈的市场竞争中分得最大的这一块蛋糕,地平线有天工开物,黑芝麻有华山,TI有TIDL,英伟达有TensorRT和CUDA等等。
深度学习的效果,经过实际的验证,确实比传统图像算法优秀得多,以往的方法都是使用人手工精心设计的特征,来进行提取和处理,
比如说利用频谱特征、小波变换、SIFT、ORB、HOG等,但不是所有问题都可以用深度学习来解决!
深度学习本质上强大在非线性拟合能力,用一个三层的神经网络能拟合出任意的函数,但具体问题具体分析,它并没有那么“智能”。
目前已有的空闲车位识别技术可以分为基于超声波雷达探测,基于视觉的空闲车位识别以及超声波与视觉相融合3 种基本模式。
得益于360°环视成像技术的成熟发展,基于环视图像的全视觉空闲车位线识别方法较为成熟了。
在其他学者既已提出的众多研究车位线自动识别方法中,可划分为依据线检测与依据角点检测定位车位两种基本思路。
识别线的思路:
一些方法使用LineSegment Detector (LSD) 检测识别车位线,基于直线检测的车位定位对部分仅画出角点附近车位线的车位适用性不高,
且直线检测对图像噪声点较为敏感,环境复杂的情况下对检测准确度影响较大。
基于角点检测的思路:
训练分类器(例如支持向量机SVM)检测角点并结合先验逻辑约束重构车位,但仅能用于检测角点为直角的车位线。
基于深度学习的车位检测方法,分别用目标检测网络检测角点,并训练另一个网络匹配角点对模式,结合模板匹配确定车位摆向。
利用深度学习强大的非线性拟合能力能够较为准确识别,但对运算所需硬件设备要求较高且角点中心定位准确程度对车位摆向影响较大。
那么看了多篇总结下来,识别角点是优秀的解决方案,当然,新的算法也有,效果也很好,比如说用全卷积网络的思想来做一个语义分割,(论文SPFCN)。
但是!想要部署实现难度还是很大,即使效果再好也没法用,所以说这里先介绍一个更贴近实际上的思路。
想要完成既定“车位识别、定位”的目标,有四个任务:
1、角点检测,逻辑推理重构车位
2、精准定位,尽可能定位到车位入口描述子的精确位置
3、坐标转换,将图像坐标与世界坐标对应起来
4、多目标跟踪,减缓识别框的跳变,稳定检测坐标的位置
对于1,我们设定有两种形态的角点,L和T形态。这个很好理解,在制作label的时候,框出车位入口的描述子即可。
目标检测采用的框架为:YOLO系列,不管是用V1-V3,整个检测算法没有特别大的改进,但是V5的效果出奇的好,并且在端侧部署的支持方面有很大的优势,
用瑞芯微RV1126(它的算力仅仅只有1.9TOPS)都可以跑起来一个非常流畅的YOLOV5多目标检测,实测。更不用说TDA4或者华山A1000这样更高算力的平台。
R-CNN系列的速度太慢了,虽然准确率较高,但是实时性真的是不行,并且占用的资源也较多,不推荐使用这类两阶段的检测算法。
TI在TDA4上提供的demo,也是使用的是单阶段的SSD算法,效果也做得非常不错!这说明了在工业部署中,大家都尽可能使用单阶段检测网络,而不是两阶段检测网络。
所以,实际的工程项目中,我推荐使用YOLOV5来改进和完成,其中的Tiny版本,甚至只需要14M的参数,就能达到很不错的效果,这是经过实际测试和验证的。
对于AVM而言,识别地面标线是它的长处,3D的物体(比如说车)在图中看起来就会被拉长,看起来很奇怪,当然也不好做标注。
最近YOLOV7版本也出了,但是这个工作还没有跟进,听说更厉害,速度更快准确率更好,但对端侧部署的友好程度还尚且未知。
这个端侧部署友好程度可以简单这么解释:
目标检测算法里面的主干网络(backbone),用到了大量的图像卷积运算,例如3*3的卷积,还有激活函数ReLU等,这些操作是对高维矩阵Tensor来进行的,
需要大量的重复运算,比如说加乘,如果说,芯片层面,支持一个专门为这一类运算提供的指令集,且芯片支持大量并行运算,就能极快地提高神经网络前向传播的速度。
当然,有些主干网络设计的时候采用了一些不支持加速的算子,这样在部署的时候就没有那么方便了。
正常来讲,如果选定用某个厂商的平台来开发,那么直接用它提供的工具链和SDK即可,可以最大程度上避免此类不兼容的问题。
不只是在车载设备,路侧设备、甚至停车场入口使用的那个摄像头,人流监控,也是如此。
经过训练,训练还是要迁移到英伟达的平台上来做的,用TensorFlow还是Pytorch还是百度飞桨,无论选哪个都可以,只要它支持ONNX转换即可,
再使用工具链来进行部署。训练后这个神经网络则能拟合车位入口描述子,用opencv在原图画出来,就是人眼看到的那个框。后续还有处理(目标跟踪)在后面再描述。
当然,也可以直接对整个车位进行标注,但是这样,精准定位成了问题。
精准定位:
神经网络对当前帧输出了多个检测框,框里的内容是车位入口描述子,这个时候,称这个描述子图像为descriptor_image,我们需要做的是传统图像处理的内容,
简单来说就是算出这张图像里交点的坐标和相对于车身的角度。
如图所示,只需要将这个描述子用大津阈值法转为二值图,当然用自适应阈值也行,看最后哪个效果好,并且要考虑到实际状况,在这一步要设计一个鲁棒性更强的二值化算法
descriptor_image
然后对二值图开运算,对开运算后较为干净的图像做细化算法,
提取出骨架,然后对骨架使用概率霍夫变换,会得到两条线段,根据描述线段Line的端点则可以算出角度,此外那个交点也可以用通俗的数学运算得到即可,
广汽研究院的论文也使用了这个方法,但是肯定是有所保留的,但是论文里写的都是可以复现的。
这里提出一些简单的示例。
1 | import cv2 |