• 基于人形检测的划区域客流统计


    摘要:通过本教程,我们学习了一类客流统计应用——区域内客流统计,通常用于室外安防,或室内客流热力图,经过简单改造还可以实现区域入侵检测、人员在离岗检测等应用。

    本文分享自华为云社区《客流分析之基于人形检测的划区域客流统计》,作者:HiLens_feige 。

    在智慧园区、智慧门店等商业场景中,划区域的客流统计是一类常见的AI应用,本文介绍基于人形检测的划区域客流统计:采用人形框检测行人并进行跟踪,若人形框中心点位于事先划定的区域中,增加客流计数;区域内外的人形将使用不同颜色的框表示,画面中也会实时显示客流数量。

    准备工作

    本文将使用华为云ModelArts进行人形检测模型的训练,并使用ModelBox框架进行应用开发,使用前开发者需要完成如下准备工作:

    1. 参考 此教程 完成设备的注册;
    2. 参考 此教程 完成ModelBox SDK的安装。

     

    技能开发

    这个应用对应的ModelBox版本已经做成模板放在华为云OBS中,可以用sdk中的solution.bat工具下载,接下来我们给出该应用在ModelBox中的完整开发过程:

    1)下载模板

    执行.\solution.bat -l可看到当前公开的技能模板:

    复制代码
    PS ███> .\solution.bat -l
    ...
    Solutions name:
    mask_det_yolo3
    ...
    passenger_flow_person_det_yolo7
    复制代码

    结果中的passenger_flow_person_det_yolo7即为基于人形检测的划区域客流统计应用模板,可使用如下命令下载模板:

    PS ███> .\solution.bat -s passenger_flow_person_det_yolo7
    ...

    solution.bat工具的参数中,-l 代表list,即列出当前已有的模板名称;-s 代表solution-name,即下载对应名称的模板。下载下来的模板资源,将存放在ModelBox核心库的solution目录下。

    2)创建工程

    在ModelBox sdk目录下使用create.bat创建passenger_flow_count工程

    PS ███> .\create.bat -t server -n passenger_flow_count -s passenger_flow_person_det_yolo7
    sdk version is modelbox-xxx
    success: create passenger_flow_count in ███\modelbox\workspace

    create.bat工具的参数中,-t 表示创建事务的类别,包括工程(server)、Python功能单元(Python)、推理功能单元(infer)等;-n 代表name,即创建事务的名称;-s 代表solution-name,表示将使用后面参数值代表的模板创建工程,而不是创建空的工程。

    workspace目录下将创建出passenger_flow_count工程,工程内容如下所示:

    复制代码
    passenger_flow_count
    |--bin
    │  |--main.bat:应用执行入口
    │  |--mock_task.toml:应用在本地执行时的输入输出配置,此应用默认使用本地视频文件为输入源,最终结果输出到另一本地视频文件,可根据需要修改
    |--CMake:存放一些自定义CMake函数
    |--data:存放应用运行所需要的图片、视频、文本、配置等数据
    │  |--passenger_flow.mp4:客流统计测试用视频文件
    │  |--simsun.ttc:中文字体库
    |--dependence
    │  |--modelbox_requirements.txt:应用运行依赖的外部库在此文件定义,本应用依赖pillow、lap、scipy等工具包
    |--etc
    │  |--flowunit:应用所需的功能单元存放在此目录
    │  │  |--cpp:存放C++功能单元编译后的动态链接库,此应用没有C++功能单元
    │  │  |--draw_passenger_bbox:客流画图功能单元
    │  │  |--object_tracker:目标跟踪功能单元
    │  │  |--yolov7_post:人形检测使用的是YOLO7模型,此处即为后处理功能单元
    |--flowunit_cpp:存放C++功能单元的源代码,此应用没有C++功能单元
    |--graph:存放流程图
    │  |--passenger_flow_count.toml:默认流程图,使用本地视频文件作为输入源
    │  |--modelbox.conf:modelbox相关配置
    |--hilens_data_dir:存放应用输出的结果文件、日志、性能统计信息
    |--model:推理功能单元目录
    │  |--person_det:人形检测推理功能单元
    │  │  |--person_det.toml:人形检测推理功能单元的配置文件
    │  │  |--person_det.onnx:人形检测onnx模型
    |--build_project.sh:应用构建脚本
    |--CMakeLists.txt
    |--rpm:打包rpm时生成的目录,将存放rpm包所需数据
    |--rpm_copyothers.sh:rpm打包时的辅助脚本
    复制代码

    3)查看流程图

    passenger_flow_count工程graph目录下存放流程图,默认的流程图passenger_flow_count.toml与工程同名,其内容为(以Windows版ModelBox为例):

    复制代码
    [driver]
    # 功能单元的扫描路径,包含在[]中,多个路径使用,分隔
    # ${HILENS_APP_ROOT} 表示当前应用的实际路径
    # ${HILENS_MB_SDK_PATH} 表示ModelBox核心库的实际路径
    dir = [
     "${HILENS_APP_ROOT}/etc/flowunit",
     "${HILENS_APP_ROOT}/etc/flowunit/cpp",
     "${HILENS_APP_ROOT}/model",
     "${HILENS_MB_SDK_PATH}/flowunit",
    ]
    skip-default = true
    [profile]
    # 通过配置profile和trace开关启用应用的性能统计
    profile = false                       # 是否记录profile信息,每隔60s记录一次统计信息
    trace = false                         # 是否记录trace信息,在任务执行过程中和结束时,输出统计信息
    dir = "${HILENS_DATA_DIR}/mb_profile" # profile/trace信息的保存位置
    [flow]
    desc = "passenger detection using person detection with yolov7 for local video or rtsp video stream" # 应用的简单描述
    [graph]
    format = "graphviz" # 流程图的格式,当前仅支持graphviz
    graphconf = """digraph passenger_flow_count {
        node [shape=Mrecord]
     queue_size = 4
     batch_size = 1
        # 定义节点,即功能单元及其属性
        input1[type=input,flowunit=input,device=cpu,deviceid=0]
     data_source_parser[type=flowunit, flowunit=data_source_parser, device=cpu, deviceid=0]
     video_demuxer[type=flowunit, flowunit=video_demuxer, device=cpu, deviceid=0]
     video_decoder[type=flowunit, flowunit=video_decoder, device=cpu, deviceid=0, pix_fmt="rgb"]
     resize[type=flowunit flowunit=resize device=cpu deviceid="0" image_width=416, image_height=320]
     color_transpose[type=flowunit flowunit=packed_planar_transpose device=cpu deviceid="0"]
     normalize[type=flowunit flowunit=normalize device=cpu deviceid=0 standard_deviation_inverse="0.003921568, 0.003921568, 0.003921568"]
     person_det[type=flowunit flowunit=person_det device=cpu deviceid="0"]
        yolov7_post[type=flowunit flowunit=yolov7_post device=cpu deviceid="0"]
     object_tracker[type=flowunit, flowunit=object_tracker, device=cpu, deviceid=0]
     draw_passenger_bbox[type=flowunit, flowunit=draw_passenger_bbox, device=cpu, deviceid=0]
     video_out[type=flowunit flowunit=video_out device=cpu deviceid="0"]
        # 定义边,即功能间的数据传递关系
        input1:input -> data_source_parser:in_data
     data_source_parser:out_video_url -> video_demuxer:in_video_url
     video_demuxer:out_video_packet -> video_decoder:in_video_packet
     video_decoder:out_video_frame -> resize:in_image
     resize:out_image -> color_transpose:in_image
     color_transpose:out_image -> normalize:in_data
     normalize:out_data -> person_det:input
     person_det:output -> yolov7_post:in_feat
        yolov7_post:out_data -> object_tracker:in_bbox
     object_tracker:out_track -> draw_passenger_bbox:in_track
     video_decoder:out_video_frame -> draw_passenger_bbox:in_image
     draw_passenger_bbox:out_image -> video_out:in_video_frame
    }"""
    复制代码

    整个应用逻辑比较简单,视频解码后做图像预处理,接着是人形检测,模型后处理得到人形框,送入跟踪算法进行实时跟踪与区域内外判断,最后将跟踪信息画到图像输出到视频中。

    4)核心逻辑

    本应用的核心逻辑是跟踪与区域判断,跟踪逻辑在 object_tracker 功能单元中,使用的是 JDE(Towards Real-Time Multi-Object Tracking)算法,算法介绍可参考论文,本应用使用的是简化版本,未使用人形reid特征值做匹配。

    区域判断在 draw_passenger_bbox 功能单元draw_passenger_bbox.py的 draw_tracking_object 函数中:

    复制代码
        def draw_tracking_object(self, img_data, tracking_objects):
     '''在图中画出跟踪对象的检测框和过线的行人数据'''
            thickness = 2
     GRAY = (117, 117, 117)
     GREEN = (0, 255, 0)
     YELLO = (255, 255, 0)
            # 画出区域边界线
            cv2.polylines(img_data, [self.area], True, YELLO, 3)
     flow_count = 0
     for track in tracking_objects:
                # 人形框的中心点
     c_x = int((track["bbox"][0] + track["bbox"][2]) / 2)
     c_y = int((track["bbox"][1] + track["bbox"][3]) / 2)
                # 判断人形框的中心点是否在区域内
                flag = cv2.pointPolygonTest(self.area, (c_x, c_y), False)
     if flag > 0:
                    # 区域内人形框用绿色,同时客流计数增加
     flow_count += 1
                    cv2.rectangle(img_data, (track["bbox"][0], track["bbox"][1]),
     (track["bbox"][2], track["bbox"][3]), GREEN, 2)
     else:
                    # 区域内人形框用灰色
                    cv2.rectangle(img_data, (track["bbox"][0], track["bbox"][1]),
     (track["bbox"][2], track["bbox"][3]), GRAY, thickness)
            # 左上角显示实时的客流数量
     img_data = self.put_chi_text(
     img_data, '客流计数:%d' % flow_count, (50, 20), YELLO, 50)
     return img_data
    复制代码

    可以看到,我们使用了OpenCV的 pointPolygonTest 函数判断点与区域的位置关系。其中区域参数配置在draw_passenger_bbox.toml文件中,配置的是划定区域的4个顶点坐标,围成一个封闭的四边形:

    复制代码
    ...
    # 自定义的配置项
    [config]
    area = ["0", "325", "1280", "25", "1280", "360", "0", "720"]  # 客流统计的划定区域
    ...
    复制代码

    5)模型训练

    本应用中包含模型推理部分,ModelBox内置了主流的推理引擎,如TensorFlow,TensorRT,LibTorch,Ascend ACL,MindSpore,以及Windows版本中所用的ONNXRuntime。在开发推理功能单元时,只需要准备模型文件,并配置对应的toml文件,即可完成推理功能单元的开发,无需掌握推理引擎的开发接口。

    passenger_flow_person_det_yolo7模板中内置了人形检测模型,这个模型基于yolov7与yolov5-lite,训练数据集用的是开源的CUHK-SYSU,在ModelArts的Notebook环境中训练后,再转换成对应平台的模型格式:onnx格式可以用在Windows设备上,RK系列设备上需要转换为rknn格式。

    模型的训练与转换教程已经开放在AI Gallery中,其中包含训练数据、训练代码、模型转换脚本,以及详细的指导文档。开发者如果希望尝试自己训练模型,或者对模板中提供的模型效果不满意,可以进入 【ModelBox】行人检测模型训练 页面,点击右上角的Run in ModelArts按钮,跟随教程一步步操作,也可以修改其中的代码、更换新的数据集训练出自己的模型。

    6)三方依赖库

    本应用中的画图功能单元依赖 pillow工具包以实现中文输出,ModelBox应用不需要手动安装三方依赖库,只需要配置在 dependence\modelbox_requirements.txt ,应用在编译时会自动安装。另外,中文输出还需要对应的字体库,存放在 data 目录下,画图功能单元初始化时将从此目录加载资源。

    7)查看输入输出配置

    查看任务配置文件bin/mock_task.toml,可以看到其中的任务输入和任务输出配置为如下内容::

    复制代码
    [input]
    type = "url"
    url = "${HILENS_APP_ROOT}/data/passenger_flow.mp4"  # 表示输入源为本地视频文件
    [output]
    type = "local"
    url = "${HILENS_APP_ROOT}/hilens_data_dir/passenger_flow_result.mp4"  # 表示输出为本地视频文件
    复制代码

    即,使用本地视频文件data/passenger_flow.mp4作为输入,统计过线客流后,画图输出到本地视频文件data/passenger_flow_result.mp4中。

    8)用启动脚本执行应用

    启动应用前执行.\build_project.sh进行工程构建,该脚本将编译自定义的C++功能单元(本应用不涉及)、将应用运行时会用到的配置文件转码为Unix格式(防止执行过程中的格式错误)、安装第三方依赖库:

    PS ███> .\build_project.sh
    ...
    PS ███>

    然后执行.\bin\main.bat运行应用:

    PS ███> .\bin\main.bat
    ...

    运行结束后在hilens_data_dir目录下生成了passenger_flow_result.mp4文件,可以打开查看:

    可以看到,黄色线段包围的即客流统计的区域,区域外人使用灰色框标记,区域内的使用绿色框,画面左上角实时显示总的过线客流数量。

    3. 小结

    通过本教程,我们学习了一类客流统计应用——区域内客流统计,通常用于室外安防,或室内客流热力图,经过简单改造还可以实现区域入侵检测、人员在离岗检测等应用。

     

    点击关注,第一时间了解华为云新鲜技术~

  • 相关阅读:
    Java中级编程大师班<第一篇:初识数据结构与算法(1)>
    仿东郊到家小程序源码 同城按摩源码 家政小程序源码 美容理疗小程序源码+公众号H5+APP源码
    Zemax基础知识7--衍射知识(一)
    LC-1726. 同积元组(哈希、哈希+数学)
    自然语言处理实战项目17-基于多种NLP模型的诈骗电话识别方法研究与应用实战
    Ubuntu20配置Mysql常用操作
    卷积神经网络(CNN)网络结构及模型原理介绍
    Web下的拒绝服务漏洞(DoS)
    IO和进程day07(IPC、管道、信号)
    含文档+PPT+源码等]精品基于Java的社区团购系统SSM[包运行成功]计算机毕业设计Java毕设
  • 原文地址:https://www.cnblogs.com/huaweiyun/p/17188937.html