在我们介绍目标物体检测算法时,前期小编的文章也分享了很多目标检测算法,比如YOLO, Faster RCNN等,喜欢目标检测的小伙伴们可以参考往期的文章学习,本期的文章代码也 在往期文章中有较多的介绍。前几天刚听说YOLO V4的出现打破了YOLO系列作者不更新目标检测算法的新闻,突然又听说YOLO V5已经出现,且检测速度与精度有了较大的提高。不得不说现在的节奏太快,一不留神,我们就错过了很多。目标检测算法YOLO V3算是当今最受大家喜欢,且检测速度与精度都有很大的优势,这里我们利用YOLO V3目标检测算法来进行人物的检测,并计算人与人之间的距离
目标检测首先我们建立一个目标检测函数来检测人物
from scipy.spatial import distance as dist import numpy as np import cv2 import os def detect_people(frame, net, ln, personIdx=0): (H, W) = frame.shape[:2] results = [] blob = cv2.dnn.blobFromImage(frame, 1 / 255.0, (416, 416), swapRB=True, crop=False) net.setInput(blob) layerOutputs = net.forward(ln) boxes = [] centroids = [] confidences = []
from scipy.spatial import distance as dist欧拉距离,主要用于质心之间的距离计算
detect_people(frame, net, ln, personIdx=0)这里接受四个参数
frame:从视频帧中提取的图片帧,用于后期的目标检测
net:基于yolo v3的目标检测算法的神经网络
ln:我们提取yolo v3输出层的神经网络,用于神经网络的前向传播的输入层,便于进行目标检测
personIdx:神经网络检测到人的目标的索引
(H, W) = frame.shape[:2]:获取视频帧图片的尺寸
blob = cv2.dnn.blobFromImage(frame, 1 / 255.0, (416, 416), swapRB=True, crop=False) net.setInput(blob) layerOutputs = net.forward(ln)此三行代码便是yolo v3目标检测算法的核心代码了,我们计算图片的blob值
放入神经网络进行预测,并把输出层进行反向传播进行目标的预测
for output in layerOutputs: for detection in output: scores = detection[5:] classID = np.argmax(scores) confidence = scores[classID] if classID == personIdx and confidence > 0.5: box = detection[0:4] * np.array([W, H, W, H]) (centerX, centerY, width, height) = box.astype(&34;) x = int(centerX - (width / 2)) y = int(centerY - (height / 2)) boxes.append([x, y, int(width), int(height)]) centroids.append((centerX, centerY)) confidences.append(float(confidence))神经网络检测完成后,所有检测结果放置在layerOutputs里面
通过for循环遍历出每个目标的置信度,我们只提取目标为人且置信度大于0.5的目标,其它目标直接忽略
box = detection[0:4] * np.array([W, H, W, H]) (centerX, centerY, width, height) = box.astype(&34;) x = int(centerX - (width / 2)) y = int(centerY - (height / 2))当检测到我们需要的目标时,我们记录其目标的中心(质心)坐标值以及目标box,并保存
idxs = cv2.dnn.NMSBoxes(boxes, confidences, 0.3, 0.3) if len(idxs) > 0: for i in idxs.flatten(): (x, y) = (boxes[i][0], boxes[i][1]) (w, h) = (boxes[i][2], boxes[i][3]) r = (confidences[i], (x, y, x + w, y + h), centroids[i]) results.append(r) return results由于人在移动过程中,很容易拍到的图片2个人有重合的区域,这里使用非极大值抑制(NMS)算法,进行目标的低置信度的筛选
最后,我们把检测到的目标box,目标质心坐标,以及置信度保存到results中便于后期的运算
初始化神经网络labelsPath = os.path.sep.join([&34;, &34;]) LABELS = open(labelsPath).read().strip().split(&34;) weightsPath = os.path.sep.join([&34;, &34;]) configPath = os.path.sep.join([&34;, &34;]) net = cv2.dnn.readNetFromDarknet(configPath, weightsPath) ln = net.getLayerNames() ln = [ln[i[0] - 1] for i in net.getUnconnectedOutLayers()] vs = cv2.VideoCapture(&34;)read the next frame from the file (grabbed, frame) = vs.read() of the stream if not grabbed: break 34;person& initialize the set of indexes that violate the minimum social ensure there are *at least* two people detections (required in extract all centroids from the results and compute the 34;euclidean& loop over the upper triangular of the distance matrix for i in range(0, D.shape[0]): for j in range(i + 1, D.shape[1]): 34; Distancing: {}&34;Frame&34;q&34;person&34;euclidean")
当检测到目标后,我们提取所有目标的质心,并计算每个质心之间的欧拉距离
for i in range(0, D.shape[0]): for j in range(i + 1, D.shape[1]): if D[i, j] < 50: violate.add(i) violate.add(j)通过for循环来判断是否存在质心距离小于设置值的质心,并记录质心的索引
for (i, (prob, bbox, centroid)) in enumerate(results): (startX, startY, endX, endY) = bbox (cX, cY) = centroid color = (0, 255, 0) if i in violate: color = (0, 0, 255)为了便于区分,当2个质心的间距小于设置值时,我们更改为红色颜色框,相反,其他的设置为绿色框
最后,实时把数据以及box显示在视频中
说在最后本期主要使用yolo v3来实时进行图片帧的人物检测,并计算质心的距离,这样的方式导致了大量计算都是在神经网络的目标检测上,因为每帧视频都要进行一次目标的检测与质心的运算
当然你的电脑配置够好的话,可以参考这样的设计
我们这里提供另外一个方式,就是质心追踪与质心运算,感兴趣的小伙伴可以参考小编的专栏
《打造属于自己的天眼目标追踪系统》
本专栏详细介绍了目标的质心追踪与目标的质心距离运算,以及其他更多的目标追踪技术,由于我们采用目标质心追踪算法,不在用大量的资源来进行神经网络的检测,更好更快的来达到了我们的目的
通过质心的目标追踪算法来搭配质心距离的计算,能够更好的运行本期的代码
本站所发布的文字与图片素材为非商业目的改编或整理,版权归原作者所有,如侵权或涉及违法,请联系我们删除
热门信息
阅读 ()
1 注册微信号怎么注册第二个阅读 ()
2 怎么把照片变成卡通头像阅读 ()
3 手机越充越少电怎么解决