本文共享自华为云社区《客流分析之根据人形检测的划区域客流计算》,作者: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.pydraw_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

能够看到,咱们运用了OpenCVpointPolygonTest 函数判别点与区域的方位关系。其间区域参数装备在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,在ModelArtsNotebook环境中练习后,再转化成对应渠道的模型格式: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. 小结

通过本教程,咱们学习了一类客流计算运用——区域内客流计算,一般用于室外安防,或室内客流热力求,通过简单改造还能够完成区域入侵检测、人员在离岗检测等运用。

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