前端开发入门到精通的在线学习网站

网站首页 > 资源文章 正文

27.基于PP-YOLOv2模型——实现高密度环境下的人数检测项目

qiguaw 2025-02-16 22:34:03 资源文章 41 ℃ 0 评论

一、项目简介

随着网络技术的发展,视频监控也在各个场所和单位进行全方位的安装,实现安防监控的目的。基于高密度环境下的人数检测项目,充分利用视频监控的现有硬件资源,实现各种高密度场所的实时人数统计难的问题。

二、项目方案

1、背景与目标

随着时代的发展,普通的监视视频已经无法满足日常监督管理的需要了。为了更好地利用监控资源,提出基于高密度环境下的人数检测:

1)辅助统计(班级考勤)

2)大型活动的人数统计

3)检测人口密度(安全隐患)

等等各场人员活动场所,从而比较高效实时了解各种场所的人数情况。

2、现状

传统情况下一般都是通过手动人工来实现人数统计的,比较繁琐麻烦,效率低下。

3、问题与方案

高密度环境中的人数检测,由于存在大量的遮挡、合并、分离,实现准确的人数检测是一个富有挑战性的研究问题,基于高密环境下的人数检测项目,可以很好解决了高密度环境下的人数统计任务。

基于高密度环境下的人数检测项目,通过大量人头数据对人头的特征提取,从而实现人头的目标检测。在高密度人群中区分人的特征只有头部。当摄像机架设一定高度时,行人头部遮挡较少,对检测比较有利。

头部检测的优势在于:头部具有结构化的一些特征,相对于肤色、发色而言,受光线、噪声、阴影等影响较小。不足在于:头部的特征变化多样,不同的装束、肤色、方向都会有较大的差别。

由于监控视频的普及,结合人工智能计算视觉相关算法,很容易实现人数统计任务,项目也很容易推广,并在此基础上扩展其他的相关应用,解决实际工作与生活中的问题。

三、实现方法与过程

1、数据集说明

SCUT-HEAD是一个大规模的头部检测数据集(来源于互联网)。数据集包括4405张标有111251个头部的图像。该数据集由两部分组成。A部分包括从某大学教室的监控视频中抽出的2000张图像,其中有67321个头像的注释。B部分包括从互联网上抓取的2405张图片,有43930个头像被标注。我们用xmin、ymin、xmax和ymax坐标标记了每个可见的头像,并确保注释覆盖整个头像,包括被遮挡的部分,但没有额外的背景。PartA和PartB都被分为训练和测试部分。数据集遵循Pascal VOC的标准。



2、算法与网络模型

飞桨的PP-YOLO2模型,相较2020年发布的PP-YOLO,v2版本在COCO 2017 test-dev上的精度提升了3.6个百分点,由45.9%提升到了49.5%;在640*640的输入尺寸下,FPS达到68.9FPS。PP-YOLOv2在同等速度下,精度超越YOLOv5。

3、模型训练

import paddlex as pdx
from paddlex import transforms as T

train_transforms = T.Compose([
    T.MixupImage(mixup_epoch=-1), T.RandomDistort(),
    T.RandomExpand(im_padding_value=[123.675, 116.28, 103.53]), T.RandomCrop(),
    T.RandomHorizontalFlip(), T.BatchRandomResize(
        target_sizes=[
            320, 352, 384, 416, 448, 480, 512, 544, 576, 608, 640, 672, 704,
            736, 768
        ],
        interp='RANDOM'), T.Normalize(
            mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225])
])

eval_transforms = T.Compose([
    T.Resize(
        target_size=640, interp='CUBIC'), T.Normalize(
            mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225])
])

train_dataset = pdx.datasets.VOCDetection(
    data_dir='head',
    file_list='head/train_list.txt',
    label_list='head/labels.txt',
    transforms=train_transforms,
    shuffle=True)

eval_dataset = pdx.datasets.VOCDetection(
    data_dir='head',
    file_list='head/val_list.txt',
    label_list='head/labels.txt',
    transforms=eval_transforms,
    shuffle=False)

# 初始化模型,并进行训练
num_classes = len(train_dataset.labels)
model = pdx.det.PPYOLOv2(num_classes=num_classes, backbone='ResNet50_vd_dcn')

#训练
model.train(
    num_epochs=170,
    train_dataset=train_dataset,
    train_batch_size=8,
    eval_dataset=eval_dataset,
    pretrain_weights='COCO',
    learning_rate=0.005 / 12,
    warmup_steps=1000,
    warmup_start_lr=0.0,
    lr_decay_epochs=[105, 135, 150],
    save_interval_epochs=5,
    save_dir='output/ppyolov2_r50vd_dcn-head')

4、模型部署与预测

# 输出推理模型
# paddlex -export_inference --model_dir best_model --save_dir inference
import paddlex as pdx
import cv2
import os
import random
import datetime
import collections as c
#启用GPU
os.environ["CUDA_VISIBLE_DEVICES"]="0,1" 

basedir="head"

#创建推理预测
predictor=pdx.deploy.Predictor("output/ppyolov2_r50vd_dcn-head/inference_model",use_gpu=True)

lst=[] #存放K次预测的值
def videodetect(camid:str):
    '''
    Channels:	录像机32通道,01主流码
    transportmode:multicas多播,unicast单播
    '''
    url = "rtsp://***:***@192.168.1.1:554/Streaming/Channels/"+camid+"01?transportmode=multicas"
    cap=cv2.VideoCapture(url)
    k=0
    while cap.isOpened:
        ret,frame=cap.read()
        (h,w)= frame.shape[:-1] #获取图片大小
        frame=cv2.resize(frame, (int(w/2), int(h/2)))#缩小图像
        k=k+1
        #预测k=100次,取预测值出现最多的数目
        if k<100:
            result=predictor.predict(frame)
            count=0 #每次计数清零
            #根据预测结果阈值统计人头数
            for res in result:
                if res["score"]>=0.5:
                    count=count+1
            lst.append(count)#存放k次预测的值到列表中
            # visimg=pdx.det.visualize(frame,result,threshold=0.5,save_dir=None)
            # cv2.imshow("result",visimg)
            cv2.putText(frame,"person:"+str(count),(10,50),cv2.FONT_HERSHEY_SIMPLEX ,0.6,(255,0,0),2) 
        else:
            break
        #显示实时画面以预测结果
        cv2.imshow("result",frame)
        if cv2.waitKey(1)==ord("q"):
            break

    cap.release()
    cv2.destroyAllWindows()

    #统计100次中出现最多次数的预测值
    c=c.Counter(lst)
		n=c.most.common(1))[0]
    print("person:",n)
    #保存最后一帧图像,并显示人数
    cv2.putText(frame,"person:"+str(n),(10,50),cv2.FONT_HERSHEY_SIMPLEX ,0.8,(0,0,255),2)
    filename=datetime.datetime.now().strftime("%Y%m%d%H%M%S")+".jpg"
    cv2.imwrite("capcam/"+filename,frame)
    return n

idnum={}
#轮巡ID=01-32的摄像头
camidlst=[str(i).rjust(2,"0") for i in range(1,33)]
print(camidlst)
for camid in camidlst[:5]:
    n=videodetect(camid)
    idnum[camid]=n

#写入文本文件
logname=datetime.datetime.now().strftime("%Y%m%d%H%M%S")+".txt"
with open("capcam/"+logname,"w") as f:
    f.write(json.dumps(idnum))
print(idnum)


四、应用前景

如检测人流密度估算,曾经常有一些大的场合中人数太多造成安全隐患,若加入人数检测,如果超过一定人数则通知疏散。则可有效防控安全隐患

从人头目标检测实现人数统计我们联想到,在人脸没有遮挡情况也可以通过人脸识别来进行人数统计与识别,还可以通过视频监控检测睡觉、玩手机、抽烟等各种行为目标检测,更好的应到实际工作管理当中。

Tags:

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表