700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > python使用Yolov3实现电子围栏功能 检测目标是否进入指定区域

python使用Yolov3实现电子围栏功能 检测目标是否进入指定区域

时间:2021-11-08 07:20:46

相关推荐

python使用Yolov3实现电子围栏功能 检测目标是否进入指定区域

这是一道小学升初中的测试题。题目给定了一个视频,要求我们检测出里面的人,并且判断是否有人在翻越围墙,是则给出警报信息,同时要求我们要播放视频。

这道题的思路很简单,可以这样来做。首先给定出报警区域,检测视频中行人位置,判断是否在报警区域内。检测行人有多种方法,其中,yolo算法应该是效果最好的一种方法了,用yolo算法需要下载以下几个文件,我放在百度网盘中,大家可以自行提取。

链接:/s/1wvHFpRkpuL4uuHWw707n6Q

提取码:3kja

yolo算法的代码大同小异,在这个基础上加入我们所需要的视频处理等模块就可以了。其中,视频播放可以选择实时播放,也可以选择将视频处理后的每一帧保存起来,最后组合成视频进行播放。我个人推荐后者,因为用yolo跑起来数据处理量还是挺大的,电脑性能不好的话跑起来很卡的。代码如下(如果中途想停止播放,可以敲击键盘“q”回车)。

# -*- coding: utf-8 -*-"""Created on Sun Dec 19 16:55:32 @author: 2540817538(有问题请联系此QQ)python3.8.8"""import cv2 as cvimport numpy as npfrom matplotlib.path import Pathdef yolo_detect(img):m=Path([(0,338),(869,333),(0,443),(870,425)])#警报区域#报警区域的划定可以参考我另一篇水文《python获取图像中像素点坐标》n=Path([(968,319),(1522,341),(1521,530),(958,469)])#这里的m,n是将4个坐标点顺序连起来组成的四边形所围成的区域confidence_thre=0.5#置信度(概率/打分)阈值,即保留概率大于这个值的边界框,默认为0.5nms_thre=0.3#非极大值抑制的阈值,默认为0.3LABELS = open('C:/Users/25408/Desktop/coco.names').read().strip().split("\n") # 加载类别标签文件(H, W) = img.shape[:2]#获取图片维度net = cv.dnn.readNetFromDarknet('C:/Users/25408/Desktop/yolov3.cfg','C:/Users/25408/Desktop/yolov3.weights')# 加载模型配置和权重文件ln = net.getLayerNames() # 获取YOLO输出层的名字ln = [ln[i[0] - 1] for i in net.getUnconnectedOutLayers()]#如果这里报错的话,请把i[0]的[0]去掉,变成iblob = cv.dnn.blobFromImage(img, 1 / 255.0, (416, 416), swapRB=True, crop=False)# 将图片构建成一个blob,设置图片尺寸,然后执行一次 YOLO前馈网络计算,最终获取边界框和相应概率net.setInput(blob)layerOutputs = net.forward(ln)boxes = []# 初始化边界框,置信度(概率)以及类别confidences = []classIDs = []i=0for output in layerOutputs:# 迭代每个输出层,总共三个for detection in output: # 迭代每个检测scores = detection[5:]# 提取类别ID和置信度classID = np.argmax(scores)confidence = scores[classID]if confidence > confidence_thre: # 只保留置信度大于某值的边界框box = detection[0:4] * np.array([W, H, W, H])# 将边界框的坐标还原至与原图片相匹配,返回边界框的中心坐标以及边界框的宽度和高度(centerX, centerY, width, height) = box.astype("int")x = int(centerX - (width / 2))y = int(centerY - (height / 2))boxes.append([x, y, int(width), int(height)])#更新边界框,置信度(概率)以及类别confidences.append(float(confidence))classIDs.append(classID)idxs = cv.dnn.NMSBoxes(boxes, confidences, confidence_thre, nms_thre) # 使用非极大值抑制方法抑制弱、重叠边界框if len(idxs) > 0: # 确保至少一个边界框for i in idxs.flatten(): # 迭代每个边界框color=(255,0,0)(x, y) = (boxes[i][0], boxes[i][1])(w, h) = (boxes[i][2], boxes[i][3])#报警条件if (m.contains_point((int(x+w/2), int(y+h/2))) or n.contains_point((int(x+w/2), int(y+h/2)))) and (LABELS[classIDs[i]]=='person'):color=(0,0,255)#m.contain_point(x,y)可以判断点(x,y)是否在m区域内cv.putText(img, "Catch the thief!", (680,425), cv.FONT_HERSHEY_COMPLEX, 2.0, (0, 0, 255), 5)#警报信息cv.rectangle(img, (x, y), (x + w, y + h), color, 2)# 绘制边界框以及添加类别标签和置信度text = '{}: {:.3f}'.format(LABELS[classIDs[i]], confidences[i])(text_w, text_h), baseline = cv.getTextSize(text, cv.FONT_HERSHEY_SIMPLEX, 0.5, 2)cv.rectangle(img, (x, y - text_h - baseline), (x + text_w, y), color, -1)cv.putText(img, text, (x, y - 5), cv.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 0), 2)return imgdef main():cap=cv.VideoCapture('C:/Users/25408/Desktop/sp1.mp4')# 注意更改视频路径i=0while True:success,frame = cap.read()# 读取视频流if success :if(i%1==0):#每隔固定帧处理一次frame=yolo_detect(frame)cv.namedWindow('asd', cv.WINDOW_NORMAL) cv.imshow('asd', frame)i+=1key = cv.waitKey(5) & 0xFF#手动停止方法if key == ord('q'):print ('停止播放')breakelse:print ('播放完成')breakcap.release()cv.destroyAllWindows()if __name__=="__main__":main()

运行效果(这里就截一张图展示就好):

我使用的视频如下,大家可以下载用来测试代码,记得要更改视频路径。

链接:/s/15FZAnQOHhxACHJEGjGItDw

提取码:alz8

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。