AI项目二十三:危险区域识别系统

若该文为原创文章,转载请注明原文出处。

一、介绍

在IPC监控视频中,很多IPC现在支持区域检测,当在区域内检测到有人闯入时,发送报警并联动报警系统,以保障生命和财产安全具有重大意义。它能够在第一时间检测到人员进入危险区域的行为,并发出及时警告,从而防止潜在事故的发生。

简单说是,在地图上标记出禁区(多边形),用计算机视觉技术监控进入禁区的物体。

现在很多摄像头模组,都自带了移动侦测功能,比如海思,君正,RK等。

以前有在RV1126上实现过类似的,现在想在RK3568上实现。

记录下PC端测试情况。

检测流程:

1、使用YOLOV5识别人物

2、使用ByteTrack实现多目标跟踪

3、使用射线法判断点是否在区域内

二、环境搭建

环境搭建参考AI项目二十二:行人属性识别-CSDN博客

项目结构

ByteTrack是git下载的源码

fonts存放了字体文件

weights存放yolov5s.pt模型

yolov5是git下载的源码

main.py主程序

mask_face.py是人脸遮挡代码

track.py是多目标根据和闯入识别代码

三、代码解析

代码功能不多,直接附上源码

main.py

import cv2
import torch
import numpy as np
from PIL import Image, ImageDraw, ImageFont
print("0")
from mask_face import mask_face
print("2")
from track import PersonTrackprint("1")
def cv2_add_chinese_text(img, text, position, text_color=(0, 255, 0), tex_size=30):img = Image.fromarray(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))draw = ImageDraw.Draw(img)font_style = ImageFont.truetype("./fonts/MSYH.ttc", tex_size, encoding="utf-8")draw.text(position, text, text_color, font=font_style)return cv2.cvtColor(np.asarray(img), cv2.COLOR_RGB2BGR)
print("2")
class BreakInDetection:def __init__(self):self.yolov5_model = torch.hub.load('yolov5', 'custom', path='./weights/yolov5s.pt', source='local')self.yolov5_model.conf = 0.7self.tracker = PersonTrack()@staticmethoddef yolo_pd_to_numpy(yolo_pd):box_list = yolo_pd.to_numpy()detections = []for box in box_list:l, t = int(box[0]), int(box[1])r, b = int(box[2]), int(box[3])conf = box[4]detections.append([l, t, r, b, conf])return np.array(detections, dtype=float)def plot_detection(self, person_track_dict, penalty_zone_point_list, frame, frame_idx):print(frame_idx)break_in_num = 0for track_id, detection in person_track_dict.items():l, t, r, b = detection.ltrbtrack_id = detection.track_idprint(track_id, detection.is_break_in)if detection.is_break_in:box_color = (0, 0, 255)id_color = (0, 0, 255)break_in_num += 1else:box_color = (0, 255, 0)id_color = (255, 0, 0)frame[t:b, l:r] = mask_face(frame[t:b, l:r])# 人体框cv2.rectangle(frame, (l, t), (r, b), box_color, 1)cv2.putText(frame, f'id-{track_id}', (l + 2, t - 3), cv2.FONT_HERSHEY_PLAIN, 3, id_color, 2)# 绘制禁区pts = np.array(penalty_zone_point_list, np.int32)pts = pts.reshape((-1, 1, 2))cv2.polylines(frame, [pts], True, (0, 0, 255), 2)cover = np.zeros((frame.shape[0], frame.shape[1], 3), np.uint8)cover = cv2.fillPoly(cover, [pts], (0, 0, 255))frame = cv2.addWeighted(frame, 0.9, cover, 0.3, 0)frame = cv2_add_chinese_text(frame, f'禁区', (600, 450), (255, 0, 0), 30)# 统计区info_frame_h, info_frame_w = 200, 400info_frame = np.zeros((info_frame_h, info_frame_w, 3), np.uint8)if_l, if_t = 100, 100if_r, if_b = if_l + info_frame_w, if_t + info_frame_hframe_part = frame[if_t:if_b, if_l:if_r]mixed_frame = cv2.addWeighted(frame_part, 0.6, info_frame, 0.7, 0)frame[if_t:if_b, if_l:if_r] = mixed_frameframe = cv2_add_chinese_text(frame, f'统计', (if_l + 150, if_t + 10), (255, 0, 0), 40)frame = cv2_add_chinese_text(frame, f'当前闯入禁区 {break_in_num} 人', (if_l + 60, if_t + 80), (255, 0, 0), 35)return framedef detect(self):cap = cv2.VideoCapture('./video.mp4')video_w = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))video_h = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))fps = round(cap.get(cv2.CAP_PROP_FPS))print(fps)video_writer = cv2.VideoWriter('./video_result.mp4', cv2.VideoWriter_fourcc(*'H264'), fps, (video_w, video_h))frame_idx = 0while cap.isOpened():frame_idx += 1success, frame = cap.read()if not success:print("Ignoring empty camera frame.")breakresults = self.yolov5_model(frame[:, :, ::-1])pd = results.pandas().xyxy[0]person_pd = pd[pd['name'] == 'person']person_det_boxes = self.yolo_pd_to_numpy(person_pd)if len(person_det_boxes) > 0:person_track_dict, penalty_zone_point_list = self.tracker.update_track(person_det_boxes, frame)frame = self.plot_detection(person_track_dict, penalty_zone_point_list, frame, frame_idx)cv2.imshow('Break in Detection', frame)video_writer.write(frame)if cv2.waitKey(1) & 0xFF == ord("q"):breakcap.release()cv2.destroyAllWindows()print("3")
if __name__ == '__main__':BreakInDetection().detect()

mask_face.py

import cv2
import mediapipe as mpface_detection = mp.solutions.face_detection.FaceDetection(model_selection=1, min_detection_confidence=0.3)def mask_face(frame):frame.flags.writeable = Falseframe = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)results = face_detection.process(frame)frame_h, frame_w = frame.shape[:2]frame.flags.writeable = Trueframe = cv2.cvtColor(frame, cv2.COLOR_RGB2BGR)if results.detections:for detection in results.detections:face_box = detection.location_data.relative_bounding_boxxmin, ymin, face_w, face_h = face_box.xmin, face_box.ymin, face_box.width, face_box.heightl, t = int(xmin*frame_w), int(ymin*frame_h)r, b = l+int(face_w*frame_w), t+int(face_h*frame_h)cv2.rectangle(frame, (l, t), (r, b), (203, 192, 255), -1)return frame

track.py 

from dataclasses import dataclass
import numpy as np
from collections import deque
import cv2
import paddleclas
import sys
sys.path.append('./ByteTrack/')
from yolox.tracker.byte_tracker import BYTETracker, STrack@dataclass(frozen=True)
class BYTETrackerArgs:track_thresh: float = 0.25track_buffer: int = 30match_thresh: float = 0.8aspect_ratio_thresh: float = 3.0min_box_area: float = 1.0mot20: bool = Falseclass Detection(object):def __init__(self, ltrb, track_id, is_break_in):self.track_id = track_idself.ltrb = ltrbself.is_break_in = is_break_in  # 是否闯入self.track_list = deque(maxlen=30)def update(self, ltrb, is_break_in):self.ltrb = ltrbself.is_break_in = is_break_inl, t, r, b = ltrbself.track_list.append(((l+r)//2, b))class PersonTrack(object):def __init__(self):self.byte_tracker = BYTETracker(BYTETrackerArgs())self.detection_dict = {}# 禁区多边形point1 = (400, 440)point2 = (460, 579)point3 = (920, 600)point4 = (960, 450)self.penalty_zone_point_list = [point1, point2, point3, point4]def is_point_in_polygon(self, vertices, point):"""判断点是否在多边形内:param vertices: 多边形顶点坐标列表 [(x1, y1), (x2, y2), ..., (xn, yn)]:param point: 需要判断的点坐标 (x, y):return: True or False"""n = len(vertices)inside = Falsep1x, p1y = vertices[0]for i in range(1, n + 1):p2x, p2y = vertices[i % n]if point[1] > min(p1y, p2y):if point[1] <= max(p1y, p2y):if point[0] <= max(p1x, p2x):if p1y != p2y:xints = (point[1] - p1y) * (p2x - p1x) / (p2y - p1y) + p1xif p1x == p2x or point[0] <= xints:inside = not insidep1x, p1y = p2x, p2yreturn insidedef update_track(self, boxes, frame):tracks = self.byte_tracker.update(output_results=boxes,img_info=frame.shape,img_size=frame.shape)new_detection_dict = {}for track in tracks:l, t, r, b = track.tlbr.astype(np.int32)track_id = track.track_id# 判断人是否闯入detect_point = ((l + r)//2, b)is_break_in = self.is_point_in_polygon(self.penalty_zone_point_list, detect_point)if track_id in self.detection_dict:detection = self.detection_dict[track_id]detection.update((l, t, r, b), is_break_in)else:detection = Detection((l, t, r, b), track_id, is_break_in)new_detection_dict[track_id] = detectionself.detection_dict = new_detection_dictreturn self.detection_dict, self.penalty_zone_point_list

代码需要注意的是:

一、区域位置

二、显示参数位置

这几个参数需要根据视频的大小,去调整位置,不然会报错。

三、检测点是否在区域内

转成C语言直接部署到RK3568上。

后续将部署到RK3568,参考git和讯为电子多目标检测已实现。

如有侵权,或需要完整代码,请及时联系博主。

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

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

相关文章

Python酷库之旅-比翼双飞情侣库(16)

目录 一、xlwt库的由来 1、背景和需求 2、项目启动 3、功能特点 4、版本兼容性 5、与其他库的关系 6、示例和应用 7、发展历史 二、xlwt库优缺点 1、优点 1-1、简单易用 1-2、功能丰富 1-3、兼容旧版Excel 1-4、社区支持 1-5、稳定性 2、缺点 2-1、不支持.xls…

[创业之路-116] :制造业企业的必备管理神器-ERP-为什么?传统制造业的转型-数字化、智能化下的需求,ERP是管理面和资金面的数字化、智能化的需要

目录 一、时代背景&#xff1a;制造业企业与智能制造 1.1 传统的制造业 1、概念 2、特点 3、面临的挑战&#xff1a;内卷严重 4、发展趋势 1.2 制造业的转型&#xff1a;数字化 1.3 制造业的转型&#xff1a;智能化 1.4 制造业的转型&#xff1a;无人工厂 1、智能化 …

每日一题——8行Python代码实现PAT乙级1029 旧键盘(举一反三+思想解读+逐步优化)五千字好文

一个认为一切根源都是“自己不够强”的INTJ 个人主页&#xff1a;用哲学编程-CSDN博客专栏&#xff1a;每日一题——举一反三Python编程学习Python内置函数 Python-3.12.0文档解读 目录 ​编辑我的写法 代码分析 时间复杂度分析 空间复杂度分析 改进建议 方法 1&#…

leetcode33:搜索旋转数组

题目链接&#xff1a;33. 搜索旋转排序数组 - 力扣&#xff08;LeetCode&#xff09; class Solution { public:int search(vector<int>& nums, int target) {int n (int)nums.size();if(!n){return -1;}if(n 1){return nums[0] target ? 0 : -1;}int left 0, …

Java开发笔记Ⅲ (一些零碎记录)

一些报错处理 找不到注入的对象 可以在 dao 层 的接口上添加 Repository 注解 common 模块报错 Unable to find main class 由于common中只有一些常量与工具类&#xff0c;不需要主类&#xff0c;故出现该错误时只需删除pom文件中的build标签即可解决 网关模块报错 Failed…

正则表达式常用表示

视频教程&#xff1a;10分钟快速掌握正则表达式 正则表达式在线测试工具&#xff08;亲测好用&#xff09;&#xff1a;测试工具 正则表达式常用表示 限定符 a*&#xff1a;a出现0次或多次a&#xff1a;a出现1次或多次a?&#xff1a;a出现0次或1次a{6}&#xff1a;a出现6次a…

网络安全:探索云安全的最佳实践

文章目录 网络安全&#xff1a;探索云安全的最佳实践引言云安全简介云安全面临的挑战云安全的最佳实践数据加密身份和访问管理定期安全审计 结语 网络安全&#xff1a;探索云安全的最佳实践 引言 在我们之前的文章中&#xff0c;我们讨论了网络安全的多个方面&#xff0c;包括…

2021数学建模A题目–“FAST”主动反射面的形状调节

A 题——“FAST”主动反射面的形状调节 思路&#xff1a;该题主要是通过利用伸缩杆调整FAST反射面&#xff0c;给出合适的调整方案 程序获取 第一题问题思路与结果&#xff1a; 当待观测天体S位于基准球面正上方&#xff0c;结合考虑反射面板调节因素&#xff0c;确定理想抛物…

等保2.0中,如何理解和实施安全管理中心的支持作用?

等保2.0&#xff0c;即《信息安全技术 网络安全等级保护基本要求》的第二版&#xff0c;是中国关于网络安全保护的一项重要标准。它强调了一个中心和三重防护的概念&#xff0c;其中的“一个中心”指的就是安全管理中心&#xff08;Security Management Center,简称SMC&#xf…

代理四川公司疑难商标办理商标异议复审办理

申请商标注册或者办理其他商标事宜&#xff0c;可以自行办理&#xff0c;也可以委托依法设立的商标代理机构办理。外国人或者外国企业在中国申请商标注册和办理其他商标事宜的&#xff0c;应当委托依法设立的商标代理机构办理&#xff0c;按照被代理人的委托办理商标注册申请或…

【串口通信-USART】

串口通信 前言一、串行通信和并行通信二、波特率三、USRAT如何实现USART 四、通信的时候共地五、奇偶校验位总结 前言 大三上时候的笔记⇨32入门-串口通信-发送和接收数据&#x1f31f;更加偏向32部分的吧。 大三上左右的时候写过串口通信的笔记&#xff0c;那时候虽然青涩啥也…

物联网协议应用

目录 前言一、WIFI简介二、NTP协议2.1 NTP简介2.2 NTP实现 三、HTTP协议3.1 HTTP协议简介3.2 HTTP服务器 四、MQTT协议4.1 MQTT协议简介4.1.1 MQTT通信模型4.1.2 MQTT协议实现原理4.1.3 MQTT 控制报文 4.2 移植MQTT协议 前言 本文主要介绍一下物联网协议如NTP协议、HTTP协议和M…

Go Gin框架

一、Gin介绍 Gin是一个用Go编写的HTTPweb框架。它是一个类似于martini但拥有更好性能的API框架, 优于httprouter&#xff0c;速度提高了近 40 倍。点击此处访问Gin官方中文文档。 二、安装 1、安装Gin go get -u github.com/gin-gonic/gin 2、代码中引入 import "githu…

整数转换00

题目链接 整数转换 题目描述 注意点 A&#xff0c;B范围在[-2147483648, 2147483647]之间 解答思路 比较A、B每一个数位是否相同&#xff0c;如果不同则res 1比较每一位的方法是&#xff1a;将数字右移i位&#xff0c;再将其与1进行’&操作&#xff0c;就可以得到数字…

《逆贫大叔》:一部穿越时光的温情史诗

《逆贫大叔》&#xff1a;一部穿越时光的温情史诗 在历史的长河中&#xff0c;有些故事能够穿越时光的尘埃&#xff0c;直击人心。《逆贫大叔》就是这样一部作品&#xff0c;它不仅是一部电视剧&#xff0c;更是一段历史的缩影&#xff0c;一次心灵的触动。 背景设定&#xff1…

HTML静态网页成品作业(HTML+CSS)——企业摄影网介绍网页(3个页面)

&#x1f389;不定期分享源码&#xff0c;关注不丢失哦 文章目录 一、作品介绍二、作品演示三、代码目录四、网站代码HTML部分代码 五、源码获取 一、作品介绍 &#x1f3f7;️本套采用HTMLCSS&#xff0c;未使用Javacsript代码&#xff0c;共有3个页面。 二、作品演示 三、代…

金融科技在资产管理领域的创新实践

一、引言 随着科技的飞速发展&#xff0c;金融科技&#xff08;FinTech&#xff09;逐渐渗透到金融行业的各个领域&#xff0c;资产管理作为金融行业的核心之一&#xff0c;也迎来了金融科技带来的深刻变革。金融科技不仅改变了资产管理的传统模式&#xff0c;也极大地提高了资…

iOS ------ 对象的本质

一&#xff0c;OC对象本质&#xff0c;用clang编译main.m OC对象结构都是通过基础的C/C结构体实现的&#xff0c;我们通过创建OC文件及对象&#xff0c;将OC对象转化为C文件来探寻OC对象的本质。 代码&#xff1a; interface HTPerson : NSObject property(nonatomic,strong)…

MySQL全解(基础)-(MySQL的安装与配置,数据库基础操作(CRUD,聚合,约束,联合查询),索引,事务)

MySQL安装与配置 1.数据库介绍 存储数据用文件就可以了&#xff0c;为什么还要弄个数据库? 文件保存数据有以下几个缺点&#xff1a; 文件的安全性问题 文件不利于数据查询和管理 文件不利于存储海量数据 文件在程序中控制不方便数据库存储介质&#xff1a; 磁盘 内存 为了…

Python酷库之旅-比翼双飞情侣库(15)

目录 一、xlrd库的由来 二、xlrd库优缺点 1、优点 1-1、支持多种Excel文件格式 1-2、高效性 1-3、开源性 1-4、简单易用 1-5、良好的兼容性 2、缺点 2-1、对.xlsx格式支持有限 2-2、功能相对单一 2-3、更新和维护频率低 2-4、依赖外部资源 三、xlrd库的版本说明 …