本文正在参加『In AidLux,To AIoT』AI应用案例征集活动
0.项目简介
第一次接触AidLux平台,整个软件的功能深深的惊艳了我,自带hello.py代码3行代码竟然能完成手机的语音自定义播报,第一感觉就是这个系统大有可为。
本项目主要实用yolov5 和deepsort算法对区域人员进行越线检测和人员计数功能,可以用于限制进出场景或者客流量统计。整套代码可以部署在手机上,通过七牛云、喵提醒工具可以实现远程查看告警功能。
完整的产品效果视频如下,当出现越线时,手机会自动收到一条提醒,并能查看监控区域的状态。
1.AidLux平台理解
AidLux是一个伟大的工具,有很广阔的应用前景,在ARM架构智能终端(Android系统手机、平板等)上能够同时运行Linux,提供了一系列AidLite API,动态调度CPU、GPU、NPU计算单元,充分释放AI算力,降低AI开发部署门槛,加速行业应用落地。Aidlux支持Android和鸿蒙系统,硬件上对高通的硬件支持更完善一些。AidLux上对Python代码可以无缝衔接,能够安装Python各种包,PC上的豆瓣源,清华源也可以直接用;它支持常用的深度学习原生框架如图1所示,基于pytorch的官方yolov5代码可以直接在AidLux上运行。但是由于平台封装的原因,封装了cvs图像包和opencv用法相近,主要展示图片或者视频的位置不同。对QT支持非常友好,代码小改后就可以直接运行,由于分辨率设置问题,展示的效果有点变形如图2所示。
图1 主流深度学习AI 框架
图2 QT演示效果
2.项目方案介绍
2.1系统功能介绍
本项目主要用到目标检测算法采用yolov5,跟踪算法采用deepsort框架下的ReID算法,对区域人员进行越线检测和人员计数功能,可以用于限制进出场景或者客流量统计。整套代码可以部署在手机上,通过七牛云、喵提醒工具可以展示远程告警功能,软件的流程如3下所示。
图3 软件流程图
2.2 关键技术介绍
本项目应用DeepSORT多目标跟踪技术,基于Tracking-by-Detection(检测加跟踪,使效果更稳定)策略,即基于yolov5的结果来进行目标跟踪。上面的视频是DeepSORT对人群进行跟踪的结果,每个bbox左上角的数字是用来标识某个人的唯一ID号。当人员自上向下和自下向上穿越模板区域都会触发计数和告警。
手机上运行FP32模型比较吃力,这个时候可以对yolov和deepsort算法进行int8量化,会发现识别的速度贼快!
图4 效果演示图
3.具体实现
3.1下载安装Aidlux软件
首先在安卓手机上下载一个Aidlux软件,Android的APP可以直接运行在鸿蒙系统中,在华为手机的应用商城中搜索“aidlux”,即可安装下载,如果有其他品牌的手机,在相关的应用商城中,都可以下载到相应的aidlux软件。将手机连入到WiFi后,点击aidlux APP就会进入到AidLux系统,里面会有各种软件提供下载。
3.2 ssh远程工具介绍
AidLux提供浏览终端和手机终端,总觉得不是很方便,通过ssh工具可以直接远程到手机做开发。注意 修改端口号为9022,不是ssh默认的22端口,内部做了地址映射。登陆用户名root,密码aidlux。
3.3Vscode远程调试
AidLux目前布支持pycharm远程调试,但是用vscode调试也不错。注意要按照一些插件,正常运行如下图所示。
3.4 安装Python包介绍
使用pip安裝軟需要的Python包,方法和PC端一样,具体命令如下:
pip install -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple
3.5模型转换介绍
AidLux使用tflite格式进行加速推理,常用的Pytorch训练的模型,使用tflite进行部署,需要完成pytorch转为tflite。目前已知两种方法:一是pytorch --> onnx --> tensorflow --> tflite,此种方法为了通道变换,会增加transpose,transpose为访存密集型算子,会导致推理效率下降;二是使用tensorflow重新定义网络结构,将权重从pytorch copy过来,此方法操作效率低,且容易出错。推理示意图如下:
3.6远程提醒工具介绍
远程提醒主要‘喵提醒’发送文本信息进行提醒,通常识别后的是图片,要想看到图片就需要采用中间文件存储七彩牛工具,将图片的告警图片先推送到七彩牛服务器上,在将图片的外网地址通过‘喵提醒’发送到手机上。具体的详细过程见大白公众号推文。之前拼接图片的代码有问题已经修改,更新了测试图片。
4 代码分析
4.1代码结构
4.2预设置区域模板
# 根据视频尺寸,填充一个polygon,供撞线计算使用 mask_image_temp = np.zeros((1080, 1920), dtype=np.uint8)
# 初始化2个撞线polygon list_pts_blue = [[204, 305], [227, 431], [605, 522], [1101, 464], [1900, 601], [1902, 495], [1125, 379], [604, 437], [299, 375], [267, 289]] ndarray_pts_blue = np.array(list_pts_blue, np.int32) polygon_blue_value_1 = cv2.fillPoly(mask_image_temp, [ndarray_pts_blue], color=1) polygon_blue_value_1 = polygon_blue_value_1[:, :, np.newaxis] # 填充第二个polygon mask_image_temp = np.zeros((1080, 1920), dtype=np.uint8) list_pts_yellow = [[181, 305], [207, 442], [603, 544], [1107, 485], [1898, 625], [1893, 701], [1101, 568], [594, 637], [118, 483], [109, 303]] ndarray_pts_yellow = np.array(list_pts_yellow, np.int32) polygon_yellow_value_2 = cv2.fillPoly(mask_image_temp, [ndarray_pts_yellow], color=2) polygon_yellow_value_2 = polygon_yellow_value_2[:, :, np.newaxis]
4.3上行和下行判断逻辑
if len(outputs) > 0: # ----------------------判断撞线---------------------- for item_bbox in outputs: x1, y1, x2, y2, track_id, label,score = item_bbox
# 撞线检测点,(x1,y1),y方向偏移比例 0.0~1.0 y1_offset = int(y1 + ((y2 - y1) * 0.6)) # 撞线的点 y = int(y1_offset) x = int(x1) if polygon_mask_blue_and_yellow[y, x] == 1: # 如果撞 蓝polygon if track_id not in list_overlapping_blue_polygon: list_overlapping_blue_polygon.append(track_id) pass # 判断 黄polygon list 里是否有此 track_id # 有此 track_id,则 认为是 外出方向 if track_id in list_overlapping_yellow_polygon: # 外出+1 up_count += 1 print(f'类别: {label} | id: {track_id} | 上行撞线 | 上行撞线总数: {up_count} | 上行id列表: {list_overlapping_yellow_polygon}') if save_abnormal_image: # save_abnormal_image = False # abnormal_count += 1 img_save_path = 'up_count_abnormal_{}.jpg'.format(up_count) cv2.imwrite(img_save_path, frame) img_name = img_save_path.split('\\')[-1] url_receive = upload_qiniuyun(img_name, img_save_path) from miaotixing_test import miaotixing_post miaotixing_result = miaotixing_post(url_receive) # 删除 黄polygon list 中的此id list_overlapping_yellow_polygon.remove(track_id) pass else: # 无此 track_id,不做其他操作 pass elif polygon_mask_blue_and_yellow[y, x] == 2: # 如果撞 黄polygon if track_id not in list_overlapping_yellow_polygon: list_overlapping_yellow_polygon.append(track_id) pass # 判断 蓝polygon list 里是否有此 track_id # 有此 track_id,则 认为是 进入方向 if track_id in list_overlapping_blue_polygon: # 进入+1 down_count += 1 if save_abnormal_image: # save_abnormal_image = False # abnormal_count += 1 img_save_path = 'down_count_abnormal_{}.jpg'.format(down_count) cv2.imwrite(img_save_path, frame) img_name = img_save_path.split('\\')[-1] url_receive = upload_qiniuyun(img_name, img_save_path) from miaotixing_test import miaotixing_post miaotixing_result = miaotixing_post(url_receive) print(f'类别: {label} | id: {track_id} | 下行撞线 | 下行撞线总数: {down_count} | 下行id列表: {list_overlapping_blue_polygon}') # 删除 蓝polygon list 中的此id list_overlapping_blue_polygon.remove(track_id) pass else: # 无此 track_id,不做其他操作 pass pass else: pass pass pass # ----------------------清除无用id---------------------- list_overlapping_all = list_overlapping_yellow_polygon + list_overlapping_blue_polygon for id1 in list_overlapping_all: is_found = False for _, _, _, _, bbox_id, _,_ in outputs: if bbox_id == id1: is_found = True break pass pass if not is_found: # 如果没找到,删除id if id1 in list_overlapping_yellow_polygon: list_overlapping_yellow_polygon.remove(id1) pass if id1 in list_overlapping_blue_polygon: list_overlapping_blue_polygon.remove(id1) pass pass list_overlapping_all.clear() pass # 清空list # outputs.clear() pass else: # 如果图像中没有任何的bbox,则清空list list_overlapping_blue_polygon.clear() list_overlapping_yellow_polygon.clear() pass pass text_draw = 'DOWN: ' + str(down_count) + \ ' , UP: ' + str(up_count) output_image_frame = cv2.putText(img=output_image_frame, text=text_draw, org=draw_text_postion, fontFace=font_draw_number, fontScale=1, color=(255, 255, 255), thickness=2
4.4 手机运行实时视频效果
5. 总结和改进
本项目重点在于如何使用AidLux系统,将多目标跟踪的全套流程在AidLux系统中跑通。目标跟踪应用的场景比较广泛,像我现在工作中做的人员徘徊行为识别,重点区域的人员进出监控,感兴趣目标行为识别,都可以用AidLux做开发。后期根据实际的需求和应用场景,只用开发具体的应用逻辑,满足实际项目的需求,目前量化部分的代码支持用小米高通的芯片就可以支持int8量化,华为平台不支持int8量化加速。
AidLux优势在于基于手机终端操作系统,可以增加AI算法,非常便于原有终端系统的功能扩张。Aidlux平台兼容性和扩展性非常,对于pytorch训练的模型,很容易就能迁移到运行。文档也比较全:ttps://aidlux.com/docs。
感谢Aidlux提供算法平台,方便继续开发出更多更好更实用的AI小应用和大家一起分享交流。
全部代码gitee链接:git@gitee.com:AI-CNN/aidlux_deepsort_simpletracker.git