竞赛 深度学习疫情社交安全距离检测算法 - python opencv cnn

文章目录

  • 0 前言
  • 1 课题背景
  • 2 实现效果
  • 3 相关技术
    • 3.1 YOLOV4
    • 3.2 基于 DeepSort 算法的行人跟踪
  • 4 最后

0 前言

🔥 优质竞赛项目系列,今天要分享的是

🚩 **基于深度学习疫情社交安全距离检测算法 **

该项目较为新颖,适合作为竞赛课题方向,学长非常推荐!

🥇学长这里给一个题目综合评分(每项满分5分)

  • 难度系数:3分
  • 工作量:3分
  • 创新点:5分

🧿 更多资料, 项目分享:

https://gitee.com/dancheng-senior/postgraduate

1 课题背景

安全的社交距离是公共预防传染病毒的途径之一。所以,在人群密集的区域进行社交距离的安全评估是十分重要的。社交距离的测量旨在保持个体之间的物理距离和减少相互接触的人群来减缓或阻止病毒传播,在抗击病毒和预防大流感中发挥重要作用。但时刻保持安全距离具有一定的难度,特别是在校园,工厂等场所,在这种情况下,开发智能摄像头等技术尤为关键。将人工智能,深度学习集成至安全摄像头对行人进行社交距离评估。现阶段针对疫情防范的要求,主要采用人工干预和计算机处理技术。人工干预存在人力资源要求高,风险大,时间成本高等等缺点。计算机处理等人工智能技术的发展,对社交安全距离的安全评估具有良好的效果。

2 实现效果

通过距离分类人群的高危险和低危险距离。

在这里插入图片描述
相关代码

import argparse
from utils.datasets import *
from utils.utils import *def detect(save_img=False):out, source, weights, view_img, save_txt, imgsz = \opt.output, opt.source, opt.weights, opt.view_img, opt.save_txt, opt.img_sizewebcam = source == '0' or source.startswith('rtsp') or source.startswith('http') or source.endswith('.txt')# Initializedevice = torch_utils.select_device(opt.device)if os.path.exists(out):shutil.rmtree(out)  # delete output folderos.makedirs(out)  # make new output folderhalf = device.type != 'cpu'  # half precision only supported on CUDA# Load modelgoogle_utils.attempt_download(weights)model = torch.load(weights, map_location=device)['model'].float()  # load to FP32# torch.save(torch.load(weights, map_location=device), weights)  # update model if SourceChangeWarning# model.fuse()model.to(device).eval()if half:model.half()  # to FP16# Second-stage classifierclassify = Falseif classify:modelc = torch_utils.load_classifier(name='resnet101', n=2)  # initializemodelc.load_state_dict(torch.load('weights/resnet101.pt', map_location=device)['model'])  # load weightsmodelc.to(device).eval()# Set Dataloadervid_path, vid_writer = None, Noneif webcam:view_img = Truetorch.backends.cudnn.benchmark = True  # set True to speed up constant image size inferencedataset = LoadStreams(source, img_size=imgsz)else:save_img = Truedataset = LoadImages(source, img_size=imgsz)# Get names and colorsnames = model.names if hasattr(model, 'names') else model.modules.namescolors = [[random.randint(0, 255) for _ in range(3)] for _ in range(len(names))]# Run inferencet0 = time.time()img = torch.zeros((1, 3, imgsz, imgsz), device=device)  # init img_ = model(img.half() if half else img) if device.type != 'cpu' else None  # run oncefor path, img, im0s, vid_cap in dataset:img = torch.from_numpy(img).to(device)img = img.half() if half else img.float()  # uint8 to fp16/32img /= 255.0  # 0 - 255 to 0.0 - 1.0if img.ndimension() == 3:img = img.unsqueeze(0)# Inferencet1 = torch_utils.time_synchronized()pred = model(img, augment=opt.augment)[0]# Apply NMSpred = non_max_suppression(pred, opt.conf_thres, opt.iou_thres,fast=True, classes=opt.classes, agnostic=opt.agnostic_nms)t2 = torch_utils.time_synchronized()# Apply Classifierif classify:pred = apply_classifier(pred, modelc, img, im0s)# List to store bounding coordinates of peoplepeople_coords = []# Process detectionsfor i, det in enumerate(pred):  # detections per imageif webcam:  # batch_size >= 1p, s, im0 = path[i], '%g: ' % i, im0s[i].copy()else:p, s, im0 = path, '', im0ssave_path = str(Path(out) / Path(p).name)s += '%gx%g ' % img.shape[2:]  # print stringgn = torch.tensor(im0.shape)[[1, 0, 1, 0]]  #  normalization gain whwhif det is not None and len(det):# Rescale boxes from img_size to im0 sizedet[:, :4] = scale_coords(img.shape[2:], det[:, :4], im0.shape).round()# Print resultsfor c in det[:, -1].unique():n = (det[:, -1] == c).sum()  # detections per classs += '%g %ss, ' % (n, names[int(c)])  # add to string# Write resultsfor *xyxy, conf, cls in det:if save_txt:  # Write to filexywh = (xyxy2xywh(torch.tensor(xyxy).view(1, 4)) / gn).view(-1).tolist()  # normalized xywhwith open(save_path[:save_path.rfind('.')] + '.txt', 'a') as file:file.write(('%g ' * 5 + '\n') % (cls, *xywh))  # label formatif save_img or view_img:  # Add bbox to imagelabel = '%s %.2f' % (names[int(cls)], conf)if label is not None:if (label.split())[0] == 'person':people_coords.append(xyxy)# plot_one_box(xyxy, im0, line_thickness=3)plot_dots_on_people(xyxy, im0)# Plot lines connecting peopledistancing(people_coords, im0, dist_thres_lim=(200,250))# Print time (inference + NMS)print('%sDone. (%.3fs)' % (s, t2 - t1))# Stream resultsif view_img:cv2.imshow(p, im0)if cv2.waitKey(1) == ord('q'):  # q to quitraise StopIteration# Save results (image with detections)if save_img:if dataset.mode == 'images':cv2.imwrite(save_path, im0)else:if vid_path != save_path:  # new videovid_path = save_pathif isinstance(vid_writer, cv2.VideoWriter):vid_writer.release()  # release previous video writerfps = vid_cap.get(cv2.CAP_PROP_FPS)w = int(vid_cap.get(cv2.CAP_PROP_FRAME_WIDTH))h = int(vid_cap.get(cv2.CAP_PROP_FRAME_HEIGHT))vid_writer = cv2.VideoWriter(save_path, cv2.VideoWriter_fourcc(*opt.fourcc), fps, (w, h))vid_writer.write(im0)if save_txt or save_img:print('Results saved to %s' % os.getcwd() + os.sep + out)if platform == 'darwin':  # MacOSos.system('open ' + save_path)print('Done. (%.3fs)' % (time.time() - t0))

3 相关技术

3.1 YOLOV4

YOLOv4使用卷积网络 CSPDarknet-53 特征提取,网络结构模型如图 2 所示。在每个 Darknet-53的残块行加上 CSP(Cross
Stage Partial)结构13,将基础层划分为两部分,再通过跨层次结构的特征融合进行合并。并采用 FPN( feature pyramid
networks)结构加强特征金字塔,最后用不同层的特征的高分辨率来提取不同尺度特征图进行对象检测。最终网络输出 3
个不同尺度的特征图,在三个不同尺度特征图上分别使用 3 个不同的先验框(anchors)进行预测识别,使得远近大小目标均能得到较好的检测。
在这里插入图片描述
YOLOv4 的先验框尺寸是经PASCALL_VOC,COCO
数据集包含的种类复杂而生成的,并不一定完全适合行人。本研究旨在研究行人之间的社交距离,针对行人目标检测,利用聚类算法对 YOLOv4
的先验框微调,首先将行人数据集 F 依据相似性分为i个对象,即在这里插入图片描述,其中每个对象都具有 m
个维度的属性。聚类算法的目的是 i 个对象依据相似性聚集到指定的 j 个类簇,每个对象属于且仅属于一个其到类簇中心距离最小的类簇中心。初始化 j 个 聚 类
中 心C c c c   1 2 , ,..., j,计算每一个对象到每一个聚类中心的欧式距离,见公式
在这里插入图片描述
之后,依次比较每个对象到每个聚类中心的距离,将对象分配至距离最近的簇类中心的类簇中,
得到 在这里插入图片描述个类簇S s s s  1 2 ,
,..., l,聚类算法中定义了类簇的原型,类簇中心就是类簇内所有对象在各个维度的均值,其公式见
在这里插入图片描述
相关代码

def check_anchors(dataset, model, thr=4.0, imgsz=640):# Check anchor fit to data, recompute if necessaryprint('\nAnalyzing anchors... ', end='')m = model.module.model[-1] if hasattr(model, 'module') else model.model[-1]  # Detect()shapes = imgsz * dataset.shapes / dataset.shapes.max(1, keepdims=True)wh = torch.tensor(np.concatenate([l[:, 3:5] * s for s, l in zip(shapes, dataset.labels)])).float()  # whdef metric(k):  # compute metricr = wh[:, None] / k[None]x = torch.min(r, 1. / r).min(2)[0]  # ratio metricbest = x.max(1)[0]  # best_xreturn (best > 1. / thr).float().mean()  #  best possible recallbpr = metric(m.anchor_grid.clone().cpu().view(-1, 2))print('Best Possible Recall (BPR) = %.4f' % bpr, end='')if bpr < 0.99:  # threshold to recomputeprint('. Attempting to generate improved anchors, please wait...' % bpr)na = m.anchor_grid.numel() // 2  # number of anchorsnew_anchors = kmean_anchors(dataset, n=na, img_size=imgsz, thr=thr, gen=1000, verbose=False)new_bpr = metric(new_anchors.reshape(-1, 2))if new_bpr > bpr:  # replace anchorsnew_anchors = torch.tensor(new_anchors, device=m.anchors.device).type_as(m.anchors)m.anchor_grid[:] = new_anchors.clone().view_as(m.anchor_grid)  # for inferencem.anchors[:] = new_anchors.clone().view_as(m.anchors) / m.stride.to(m.anchors.device).view(-1, 1, 1)  # lossprint('New anchors saved to model. Update model *.yaml to use these anchors in the future.')else:print('Original anchors better than new anchors. Proceeding with original anchors.')print('')  # newline

3.2 基于 DeepSort 算法的行人跟踪

YOLOv4中完成行人目标检测后生成边界框(Bounding box,Bbox),Bbox 含有包含最小化行人边框矩形的坐标信息,本研究引入
DeepSort 算法[18]完成对行人的质点进行跟踪,目的是为了在运动矢量分析时算行人安全社交距离中。首先,对行人进行质点化计算。其质点计算公式如
在这里插入图片描述
确定行人质点后,利用 DeepSort 算法实现对多个目标的精确定位与跟踪,其核心算法流程如图所示:
在这里插入图片描述
相关代码

class TrackState:'''单个轨迹的三种状态'''Tentative = 1 #不确定态Confirmed = 2 #确定态Deleted = 3 #删除态class Track:def __init__(self, mean, covariance, track_id, class_id, conf, n_init, max_age,feature=None):'''mean:位置、速度状态分布均值向量,维度(8×1)convariance:位置、速度状态分布方差矩阵,维度(8×8)track_id:轨迹IDclass_id:轨迹所属类别hits:轨迹更新次数(初始化为1),即轨迹与目标连续匹配成功次数age:轨迹连续存在的帧数(初始化为1),即轨迹出现到被删除的连续总帧数time_since_update:轨迹距离上次更新后的连续帧数(初始化为0),即轨迹与目标连续匹配失败次数state:轨迹状态features:轨迹所属目标的外观语义特征,轨迹匹配成功时添加当前帧的新外观语义特征conf:轨迹所属目标的置信度得分_n_init:轨迹状态由不确定态到确定态所需连续匹配成功的次数_max_age:轨迹状态由不确定态到删除态所需连续匹配失败的次数'''   self.mean = meanself.covariance = covarianceself.track_id = track_idself.class_id = int(class_id)self.hits = 1self.age = 1self.time_since_update = 0self.state = TrackState.Tentativeself.features = []if feature is not None:self.features.append(feature) #若不为None,初始化外观语义特征self.conf = confself._n_init = n_initself._max_age = max_agedef increment_age(self):'''预测下一帧轨迹时调用'''self.age += 1 #轨迹连续存在帧数+1self.time_since_update += 1 #轨迹连续匹配失败次数+1def predict(self, kf):'''预测下一帧轨迹信息'''self.mean, self.covariance = kf.predict(self.mean, self.covariance) #卡尔曼滤波预测下一帧轨迹的状态均值和方差self.increment_age() #调用函数,age+1,time_since_update+1def update(self, kf, detection, class_id, conf):'''更新匹配成功的轨迹信息'''self.conf = conf #更新置信度得分self.mean, self.covariance = kf.update(self.mean, self.covariance, detection.to_xyah()) #卡尔曼滤波更新轨迹的状态均值和方差self.features.append(detection.feature) #添加轨迹对应目标框的外观语义特征self.class_id = class_id.int() #更新轨迹所属类别self.hits += 1 #轨迹匹配成功次数+1self.time_since_update = 0 #匹配成功时,轨迹连续匹配失败次数归0if self.state == TrackState.Tentative and self.hits >= self._n_init:self.state = TrackState.Confirmed #当连续匹配成功次数达标时轨迹由不确定态转为确定态def mark_missed(self):'''将轨迹状态转为删除态'''if self.state == TrackState.Tentative:self.state = TrackState.Deleted #当级联匹配和IOU匹配后仍为不确定态elif self.time_since_update > self._max_age:self.state = TrackState.Deleted #当连续匹配失败次数超标'''该部分还存在一些轨迹坐标转化及状态判定函数,具体可参考代码来源'''

4 最后

🧿 更多资料, 项目分享:

https://gitee.com/dancheng-senior/postgraduate

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/181519.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

数据结构—字符串

文章目录 7.字符串(1).字符串及其ADT#1.基本概念#2.ADT (2).字符串的基本操作#1.求子串substr#2.插入字符串insert#3.其他操作 (3).字符串的模式匹配#1.简单匹配(Brute-Force方法)#2.KMP算法I.kmp_match()II.getNext() #3.还有更多 小结附录&#xff1a;我自己写的string 7.字符…

幂等性(防重复提交)

文章目录 1. 实现原理2.使用示例3. Idempotent注解4. debug过程 主要用途&#xff1a;防止用户快速双击某个按钮&#xff0c;而前端没有禁用&#xff0c;导致发送两次重复请求。 1. 实现原理 幂等性要求参数相同的方法在一定时间内&#xff0c;只能执行一次。本质上是基于red…

【qemu逃逸】华为云2021-qemu_zzz

前言 虚拟机用户名&#xff1a;root 无密码 设备逆向 经过逆向分析&#xff0c;可得实例结构体大致结构如下&#xff1a; 其中 self 指向的是结构体本身&#xff0c;cpu_physical_memory_rw 就是这个函数的函数指针。arr 应该是 PCI 设备类结构体没啥用&#xff0c;就直接用…

5.3有效的括号(LC20-E)

算法&#xff1a; 题目中&#xff1a;左括号必须以正确的顺序闭合。意思是&#xff0c;最后出现的左括号&#xff08;对应着栈中的最后一个元素&#xff09;&#xff0c;应该先找到对应的闭合符号&#xff08;右括号&#xff09; 比如:s"( [ ) ]"就是False&#xf…

1.UML面向对象类图和关系

文章目录 4种静态结构图类图类的表示类与类之间的关系依赖关系(Dependency)关联关系(Association)聚合(Aggregation)组合(Composition)实现(Realization)继承/泛化(Inheritance/Generalization)常用的UML工具reference欢迎访问个人网络日志🌹🌹知行空间🌹🌹 4种静态结构…

spring boot导入导出excel,集成EasyExcel

一、安装依赖 <dependency><groupId>com.alibaba</groupId><artifactId>easyexcel</artifactId><version>3.3.2</version></dependency>二、新建导出工具类 package com.example.springbootclickhouse.utils;import javax.s…

Zinx框架-游戏服务器开发003:架构搭建-需求分析及TCP通信方式的实现

文章目录 1 项目总体架构2 项目需求2.1 服务器职责2.2 消息的格式和定义 3 基于Tcp连接的通信方式3.1 通道层实现GameChannel类3.1.1 TcpChannel类3.1.2 Tcp工厂类3.1.3 创建主函数&#xff0c;添加Tcp的监听套接字3.1.4 代码测试 3.2 消息类的结构设计和实现3.2.1 消息的定义3…

基于EPICS stream模块的直流电源的IOC控制程序实例

本实例程序实现了对优利德UDP6720系列直流电源的网络控制和访问&#xff0c;先在此介绍这个项目中使用的硬件&#xff1a; 1、UDP6721直流电源&#xff1a;受控设备 2、moxa串口服务器5150&#xff1a;将UDP6721直流电源设备串口连接转成网络连接 3、香橙派Zero3&#xff1a;运…

最近又考了两个Oracle认证,交一下作业

从Oracle 10g 开始考Oracle的认证&#xff0c;现在已经有15个Oracle的认证了&#xff0c;最近又考了两个Oracle认证&#xff0c;分别是云和AI的。是现在正时髦的技术&#xff0c;又恰恰是我的短板&#xff0c;以考促学&#xff0c;正好系统地学习这两门知识。这两个证书的培训和…

内存学习(2):内存分类与常用概念2(SDRAM与DDR)

SDRAM与DDR的简单概念介绍 SDRAM 定义&#xff1a; 同步动态随机存取内存&#xff08;Synchronous Dynamic Random-Access Memory&#xff0c;简称SDRAM&#xff09;是有一个同步接口的动态随机存取内存DRAM&#xff08;可以参考前文&#xff09;。可以理解为是一种利用同步…

浅谈自动化测试框架开发

在自动化测试项目中&#xff0c;为了实现更多功能&#xff0c;我们需要引入不同的库、框架。 首先&#xff0c;你需要将常用的这些库、框架都装上。 pip install requests pip install selenium pip install appium pip install pytest pip install pytest-rerunfailures pip …

数据结构-顺序表

1.线性表 线性表&#xff08;linear list&#xff09;是n个具有相同特性的数据元素的有限序列。 线性表是一种在实际中广泛使用的数据结构&#xff0c;常见的线性表&#xff1a;顺序表、链表、栈、队列、字符串... 线性表在逻辑上是线性结构&#xff0c;也就说是连续的一条直线…

初识rust

调试下rust 的执行流程 参考&#xff1a; 认识 Cargo - Rust语言圣经(Rust Course) 新建一个hello world 程序&#xff1a; fn main() {println!("Hello, world!"); }用IDA 打开exe&#xff0c;并加载符号&#xff1a; 根据字符串找到主程序入口&#xff1a; 双击…

python模块的介绍和导入

python模块的介绍和导入 概念 在Python中&#xff0c;每个Python代码文件都是一个模块。写程序时&#xff0c;我们可以将代码分散在不同的模块(文件)中&#xff0c;然后在一个模块中引用另一个模块的内容。 导入格式 1、在一个模块中引用(导入)另一个模块可以使用import语句…

web前端——HTML+CSS实现九宫格

web前端——HTMLCSS实现九宫格 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>Document</title&…

大数据毕业设计选题推荐-无线网络大数据平台-Hadoop-Spark-Hive

✨作者主页&#xff1a;IT毕设梦工厂✨ 个人简介&#xff1a;曾从事计算机专业培训教学&#xff0c;擅长Java、Python、微信小程序、Golang、安卓Android等项目实战。接项目定制开发、代码讲解、答辩教学、文档编写、降重等。 ☑文末获取源码☑ 精彩专栏推荐⬇⬇⬇ Java项目 Py…

【JavaEE】JVM 剖析

JVM 1. JVM 的内存划分2. JVM 类加载机制2.1 类加载的大致流程2.2 双亲委派模型2.3 类加载的时机 3. 垃圾回收机制3.1 为什么会存在垃圾回收机制?3.2 垃圾回收, 到底实在做什么?3.3 垃圾回收的两步骤第一步: 判断对象是否是"垃圾"第二步: 如何回收垃圾 1. JVM 的内…

Linux MMC子系统 - 3.eMMC 5.1常用命令说明(1)

By: Ailson Jack Date: 2023.11.05 个人博客&#xff1a;http://www.only2fire.com/ 本文在我博客的地址是&#xff1a;http://www.only2fire.com/archives/162.html&#xff0c;排版更好&#xff0c;便于学习&#xff0c;也可以去我博客逛逛&#xff0c;兴许有你想要的内容呢。…

SpringBoot 将 jar 包和 lib 依赖分离,dockerfile 构建镜像

前言 Spring Boot 是一个非常流行的 Java 开发框架&#xff0c;它提供了很多便利的功能&#xff0c;例如自动配置、快速开发等等。 在使用 Spring Boot 进行开发时&#xff0c;我们通常会使用 Maven 或 Gradle 进行项目构建。 本文将为您介绍如何使用 Maven 将 Spring Boot …