\u200E
如何低成本高效监控电瓶车违规停放行为?看看飞桨开发者怎么做
发布日期:2022-01-20T13:15:49.000+0000 浏览量:952次


电动车以其环保节能、小巧便捷、经济实用等特性,市场需求逐年递增,但同时它带来的充电起火、电池爆炸等安全问题也时有发生。大部分小区物业都禁止电瓶车进电梯等违规停放行为,然而实际执行中往往难以监管。人工智能是否能帮助居民减少电瓶车违规停放带来的安全隐患呢?我们尝试用人工智能进行电瓶车检测,来减少人工检测的成本和压力。


本项目以“电梯电动车检测”为首要任务进行开发,使用飞桨全流程开发工具PaddleX和边缘计算硬件EdgeBoard,实现对违规停放的电动车的检测,后续可以将场景延展到楼道门口、居民楼门口、公寓走道等众多关键场地。


本项目流程如下图所示:

图1 项目流程

项目地址:
https://aistudio.baidu.com/aistudio/projectdetail/2493263


PaddleX介绍



PaddleX 是飞桨全流程开发工具,集成飞桨智能视觉领域图像分类、目标检测、语义分割、实例分割任务能力,将深度学习开发全流程从数据准备、模型训练与优化到多端部署端到端打通,并提供统一任务API接口及图形化开发界面Demo。开发者无需分别安装不同套件,以低代码的形式即可快速完成飞桨全流程开发。


传送门:
https://github.com/PaddlePaddle/PaddleX


EdgeBoard方案介绍



EdgeBoard是百度面向嵌入式与边缘部署场景打造的AI视觉硬件方案,可无缝兼容百度大脑丰富的工具平台与开放能力,具有高性能、低成本、使用简单等三大优点,可广泛适用于智能设备打造、科研教学、安防监控、餐饮卫生监控、工业质检、交通巡检、医疗诊断、智能零售等领域。



数据集的获取



那么我们是怎样获取电瓶车数据呢?一开始我们是用Labelme标注了一部分数据,但是数据量太少了。但如果大量标注又太耗费时间了,通过观察,电瓶车与摩托车外形相当相似,因此在本项目中,我们加入了摩托车的数据集。


本项目使用的数据集来自Pascal-VOC和COCO2017,一共提取出了4718张含有摩托车的图片。数据集统一制作成VOC格式,包括两个文件夹,其中JPEGImages存储原图,Annotations存储标注文件;再以8:2的比例划分训练集和验证集。


图2 数据示例

由于Pascal-VOC和COCO2017的标记格式不同,我们需要先将它们转换成相同格式的标记文件;这里我们将COCO格式的数据集转换为VOC格式的数据集。我们设计了函数coco2voc(anno, xml_dir)实现快速转换,具体代码可以在项目链接中获取。

将Pascal-VOC和COCO2017的标记格式转换为相同格式后,里面仍然含有其他物体的标记。因此,我们需要将摩托车数据单独提取出来,提取根据xml标记文件,如果xml标记文件中含有摩托车标记,则将原图和标记文件存放到另外两个存放原图和标记文件夹下,并且将xml标记文件中不是摩托车的标记去掉,只保留摩托车的标记结果。

提取代码对应项目链接中的函数voc2sc(ann_filepath, img_filepath, img_savepath, ann_savepath, classes, sc_class)


模型训练



本项目使用的是调用API的方式,与配置化驱动的区别是只需要一行命令安装PaddleX库即可调用,无需下载和打包整个PaddleX项目。但配置基本相同,主要分为数据变换(数据增强)、数据集处理、模型准备、优化器、训练5个部分。


首先,安装并导入PaddleX库。

!pip -q install paddlex
import os
os.environ['CUDA_VISIBLE_DEVICES'] = '0'

from paddlex import transforms
import paddlex as pdx



数据增强



采用的策略是随机翻转、随机像素内容变换、图像融合、随机扩张图像等。

# 定义训练和验证时的transforms
train_transforms = transforms.Compose([
    transforms.MixupImage(mixup_epoch=-1),
    transforms.RandomDistort(),
    transforms.RandomExpand(),
    transforms.RandomCrop(),
    transforms.Resize(target_size=608, interp='RANDOM'),
    transforms.RandomHorizontalFlip(),
    transforms.Normalize(),
])

eval_transforms = transforms.Compose([
    transforms.Resize(target_size=608, interp='CUBIC'),
    transforms.Normalize()])



数据集处理



将数据增强策略应用到数据集上。

# 定义训练和验证所用的数据集
train_dataset = pdx.datasets.VOCDetection(
    data_dir='./',
    file_list='motorbike/train.txt',
    label_list='motorbike/labels.txt',
    transforms=train_transforms,
    shuffle=True)

eval_dataset = pdx.datasets.VOCDetection(
    data_dir='./',
    file_list='motorbike/val.txt',
    label_list='motorbike/labels.txt',
    transforms=eval_transforms)



模型准备



在PaddleX中有多种模型,为了适应端侧部署,选用较为轻量级的模型YOLOv3-MobileNetV1。


图3 YOLOv3-MobileNetV1网络结构图


模型训练



通过PaddleX API我们只需要几行代码就可以完成模型训练。

# 初始化模型,并进行训练
num_classes = len(train_dataset.labels)
batch_size = 64

model = pdx.det.YOLOv3(num_classes=num_classes, backbone='MobileNetV1')

model.train(
    num_epochs=200,
    train_dataset=train_dataset,
    eval_dataset=eval_dataset,
    train_batch_size=batch_size,
    learning_rate=1e-4,
    warmup_steps=len(train_dataset)//2,
    save_interval_epochs=4,
    save_dir='output/yolov3_mobilenetv1',
    metric='VOC',
    use_vdl=True,
    early_stop=True)


使用训练好的模型进行预测,结果如下图所示:
图 4 模型检测效果示例


模型导出



!paddlex --export_inference --model_dir=output/yolov3_mobilenetv1/best_model --save_dir=inference_model --fixed_input_shape=[608,608]



使用TensorRT预测时,需固定模型的输入大小,通过--fixed_input_shape来制定输入大小[w,h]。

注意事项:
  • 分类模型的固定输入大小请保持与训练时的输入大小一致;
  • 检测模型模型中YOLO系列建议保证w与h一致,且须要为32的倍数大小;RCNN类无此限制,按需设定即可;
  • 指定[w,h]时,w和h中间逗号隔开,不允许存在空格等其他字符;
  • 需要注意的,w,h设得越大,模型在预测过程中所需要的耗时和内存/显存占用越高;设得太小,会影响模型精度。



模型部署





上位机

循环读取摄像头每一帧的图片并使用轻量化推理引擎Paddle Lite工具加速预测,当检测到电瓶车且置信度较高时发送串口信号。 具体代码在AI Studio项目的detection.py中。




下位机

循环接收串口信号,当电脑端检测到串口信号时会累计次数,达到一定次数说明信号可信,进行音频报警。 具体代码放在AI Studio项目的electrobike_alarms.py中。

至此,我们已经完成了电梯电瓶车检测项目。 效果展示可见下面的链接:
https://www.bilibili.com/video/BV1PQ4y1q7f4/

本项目基于飞桨全流程开发工具PaddleX实现,大大提高了开发效率,如此 强大、 用心的 目,还不赶紧给各位 开发者一个Star的鼓励!
PaddleX Github链接:
https://github.com/PaddlePaddle/PaddleX


关注公众号,获取更多技术内容~