目录

数据集部分

后端部分

前端部分

前后端连接

数据集部分:

在该项目当中我们采用的是传统的开源数据集SHWD(Safety helmet (hardhat) wearing detect dataset)

数据集标签为hat,person

数据集的一些想法

数据集的收集,标记对于后面的的程序设计预计模型的准确度有十分重要的影响

1.首先,我暂时对于数据集的标签并不满意,在我的想法中设置三个标签更加合理:
对于一个来说,我们应该对整个身体画出真实框并标记person,对于头部画出真实框标记hat,head或者hat,no hat。而我们暂时只是对头部进行预测如果带了安全帽,则显示标签hat,如果未带帽子我们则显示person。这一点来说首先发现如下弊端
1)对于yolo的目标检测来说,如果当人影较小时而人的头部更小,对头部的扫描并不准确,此时对全身扫描来说更能准确识别人,而且当如果图中显示的是后脑勺的话识别效果尤其的不好,而对整体扫描可以大大减少这样的问题出现。

2)针对后面的目标跟踪问题来说使用对整体作为目标相比较使用头部来说追踪更加准确,也更加好处理。现在如果你选择对person进行追踪的话,则deepsort不会追踪带安全帽的人不符合我们的设计预期,无所以暂时我们的做法是对帽子和人同时追踪并计数勉强合格,但仍然存在实际情况中的一些问题,比如视频中只有一个安全帽没人带他仍会产生技术并不符合我们的预期,对于这一问题我们暂时想到了两个方法:

Ⅰ.
第一种就是上面我们提到的对数据集的改进如果这样改进数据集以后我们就可以对识别整个身体的标签person作为跟踪对象,从而避免该问题。而且显示更加清楚否则追踪框和识别框会只出现在头部显示会导致看不清,改变之后也会更清晰。
Ⅱ .
如果让保持现在的数据集,我们可以使用训练好可以识别20种物体的训练好的yolo4模型,我们在入来两个yolo模型,一个模型参数是我们根据现在并不满意的数据集训练好的识别头和帽子的模型我们用于yolo的目标检测,另一个模型载入下载好的模型用于识别整个人体用作目标跟踪的对象这样也可以实现上述内容。我们需要将每一帧的图片最为数据依次使用sess.run()跑两个模型,对图片上的物体进行预测,再画框实现分离。不过暂时我们的还不能实现使用sess.run()用相同的数据跑不同的图。

2.对于给定视频的清晰度过低的问题我们也可以使用数据集的扩充来提高模型对模糊图片的识别能力,我们可以找一些模糊的安全帽图片,或者找一个模糊的安全帽是频将一帧一帧的抽出来图片,然后对该图片进行标注,最后训练。以我看来这种发法有利于我们模型对于模糊视频中物体的识别能力。

3.我们对识别安全帽这个问题要考虑全面,考虑安全帽容易出现的情况也要充入数据集,从而可以提高我们模型针对各种极端情况的识别效果
1)第一,我们应该参考国家安全帽标准要求,对基本的安全帽样式,颜色,形状有基本的了解,要是我们的数据集中的涵盖所有安全帽可能的样子,这样对我们识别安全帽这一领域加强了专业性

2)第二,我们我们要考虑人的活动随意性,对于正面可能容易识别,但是对于人和安全帽的侧面和后面我们也要考虑在内,这有利于提高模型识别的准确度。

4.我们是否可以使用数据集实现更高级的功能呢,我们能否训练出不仅包含我们需要检测的是否佩戴安全帽和人以外,能识别工地常见的物品,当有人未佩戴安全帽时,我们可以识别该人附近的物品,并且提示处于某物品附近的人未佩戴安全帽,请及时佩戴,以免发生危险。

综上所述,整个项目过半,给我的一大感受数据集的好坏直接影响我们整个系统的质量以及后续的一系列工作,所以在整个软件杯的过程中不断收集广泛的数据集并不断训练出更好的模型应该是我们一直的任务。

后端部分

后端部分以我来看分为两个部分

第一个是YOLO

第二个部分是deepsort

最后是二者的连接。

YOLO

模型的训练文件在 G:/软件杯/project

小技巧的设置

在train.py和train_eager.py文件下:
1、mosaic参数可用于控制是否实现Mosaic数据增强。
2、Cosine_scheduler可用于控制是否使用学习率余弦退火衰减。
3、label_smoothing可用于控制是否Label Smoothing平滑。

在train_eager.py文件下:
1、regularization参数可用于控制是否实现正则化损失。

文件下载

训练所需的yolo4_weights.h5可在百度网盘中下载。
链接: https://pan.baidu.com/s/1DNv71lDkeWff2BmnVpgHeg 提取码: myz8
yolo4_weights.h5是coco数据集的权重。
yolo4_voc_weights.h5是voc数据集的权重。

预测步骤

1、使用预训练权重

a、下载完库后解压,在百度网盘下载yolo4_weights.h5或者yolo4_voc_weights.h5,放入model_data,运行predict.py,输入

img/street.jpg

可完成预测。
b、利用video.py可进行摄像头检测。

2、使用自己训练的权重

a、按照训练步骤训练。
b、在yolo.py文件里面,在如下部分修改model_path和classes_path使其对应训练好的文件;model_path对应logs文件夹下面的权值文件,classes_path是model_path对应分的类

_defaults = {"model_path": 'model_data/yolo4_weight.h5',"anchors_path": 'model_data/yolo_anchors.txt',"classes_path": 'model_data/coco_classes.txt,"score" : 0.5,"iou" : 0.3,# 显存比较小可以使用416x416# 显存比较大可以使用608x608"model_image_size" : (416, 416)
}

c、运行predict.py,输入

img/street.jpg

可完成预测。
d、利用video.py可进行摄像头检测。

训练步骤

1、本文使用VOC格式进行训练。
2、训练前将标签文件放在VOCdevkit文件夹下的VOC2007文件夹下的Annotation中。
3、训练前将图片文件放在VOCdevkit文件夹下的VOC2007文件夹下的JPEGImages中。
4、在训练前利用voc2yolo4.py文件生成对应的txt。
5、再运行根目录下的voc_annotation.py,运行前需要将classes改成你自己的classes。注意不要使用中文标签,文件夹中不要有空格!

classes = ["aeroplane", "bicycle", "bird", "boat", "bottle", "bus", "car", "cat", "chair", "cow", "diningtable", "dog", "horse", "motorbike", "person", "pottedplant", "sheep", "sofa", "train", "tvmonitor"]

6、此时会生成对应的2007_train.txt,每一行对应其图片位置及其真实框的位置和对应真实框当中的类别(且该类别是由数字编号,比如有两个类别可能hat用数字0代替,person用数字1代替)。

7、在训练前需要务必在model_data下新建一个txt文档,文档中输入需要分的类,在train.py中将classes_path指向该文件,示例如下:

classes_path = 'model_data/new_classes.txt'

model_data/new_classes.txt文件内容为:

cat
dog
...

8、运行train.py即可开始训练。

deepsort就是直接调用的具体内部算法尚不清楚·

两者结合(yolo+deepsort)

第一部分将训练好的模型载入

import colorsys
import numpy as np
# from keras import backend as K
import tensorflow as tf
tf.compat.v1.disable_v2_behavior()
tf.compat.v1.disable_eager_execution()
from timeit import default_timer as timer
from PIL import Image, ImageFont, ImageDraw
from tensorflow.keras import backend as K
from tensorflow.keras.models import load_model
from tensorflow.keras.layers import Input
# from tensorflow.keras.models import load_weights
from yolo4.model import yolo_eval, Mish
from yolo4.utils import letterbox_image
import os
from keras.utils import multi_gpu_model
from yolo4.model import yolo4_body
os.environ["CUDA_VISIBLE_DEVICES"] = "1"class YOLO(object):def __init__(self):#这一模型载入是为了实现deepsort和yolo识别模型不同权重,而暂时未实现self.weights_path = './model_data/yolo4_weight.h5'#载入训练好的模型self.model_path = './model_data/yolo4_model.h5'#载入真实框尺寸self.anchors_path = './model_data/yolo_anchors.txt'#载入自定义识别类别self.classes_path = './model_data/coco_classes01.txt'self.gpu_num = 1self.score = 0.5self.iou = 0.5self.eager = False#读取txt设定的类别读取并组织成列表形式self.class_names = self._get_class()#获得真实框尺寸组织成列表self.anchors = self._get_anchors()#获得跑图工具用在跑载入的模型self.sess = tf.compat.v1.keras.backend.get_session()self.model_image_size = (608, 608)  # fixed size or (None, None)self.is_fixed_size = self.model_image_size != (None, None)self.boxes, self.scores, self.classes = self.generate()def _get_class(self):classes_path = os.path.expanduser(self.classes_path)with open(classes_path) as f:class_names = f.readlines()class_names = [c.strip() for c in class_names]return class_namesdef _get_anchors(self):anchors_path = os.path.expanduser(self.anchors_path)with open(anchors_path) as f:anchors = f.readline()anchors = [float(x) for x in anchors.split(',')]anchors = np.array(anchors).reshape(-1, 2)return anchorsdef generate(self):model_path = os.path.expanduser(self.model_path)assert model_path.endswith('.h5'), 'Keras model or weights must be a .h5 file.'# self.yolo_model= load_model(model_path, custom_objects={'Mish': Mish}, compile=False)# # self.yolo_model.load_weights(self.weights_path)num_anchors = len(self.anchors)num_classes = len(self.class_names)print(num_classes)#载入yolo4模型,如果你之前训练模型的时候存的是模型则可以直接使用load载但是如果你只是保存参数,则需要将原来模型实例化一个后再载入参数,load_weights。self.yolo_model = yolo4_body(Input(shape=(None, None, 3)), num_anchors // 3, num_classes)self.yolo_model.load_weights(self.weights_path)# self.dect_model = load_model(model_path, custom_objects={'Mish': Mish}, compile=False)print('{} model, anchors, and classes loaded.'.format(model_path))# Generate colors for drawing bounding boxes.hsv_tuples = [(x / len(self.class_names), 1., 1.)for x in range(len(self.class_names))]self.colors = list(map(lambda x: colorsys.hsv_to_rgb(*x), hsv_tuples))self.colors = list(map(lambda x: (int(x[0] * 255), int(x[1] * 255), int(x[2] * 255)),self.colors))np.random.seed(10101)  # Fixed seed for consistent colors across runs.np.random.shuffle(self.colors)  # Shuffle colors to decorrelate adjacent classes.np.random.seed(None)  # Reset seed to default.# Generate output tensor targets for filtered bounding boxes.self.input_image_shape = K.placeholder(shape=(2, ))if self.gpu_num>=2:self.yolo_model = multi_gpu_model(self.yolo_model, gpus=self.gpu_num)boxes, scores, classes = yolo_eval(self.yolo_model.output, self.anchors,len(self.class_names), self.input_image_shape,score_threshold=self.score, iou_threshold=self.iou)return boxes, scores, classes#该函数会在main函数当中调用,我们会在主函数中将输入的视频提取出每一帧为图片作为参数输入该函数当中,我们使用训练好的模型,将图片作为输入数据,对图中的目标物体做预测,产生以下信息,预测框位置,预测类别,预测置信度,根据这些数我们对图片进画框并目标跟踪def detect_image(self, image):start = timer()## 调整图片使其符合输入要求new_image_size = (self.model_image_size[1], self.model_image_size[0])boxed_image = letterbox_image(image, new_image_size)image_data = np.array(boxed_image, dtype='float32')image_data /= 255.image_data = np.expand_dims(image_data, 0)  # Add batch dimension.if self.eager:# 预测结果input_image_shape = np.expand_dims(np.array([image.size[1], image.size[0]], dtype='float32'), 0)out_boxes, out_scores, out_classes = self.yolo_model.predict([image_data, input_image_shape])else:#使用模型进行预测out_boxes, out_scores, out_classes = self.sess.run([self.boxes, self.scores, self.classes],feed_dict={self.yolo_model.input: image_data,self.input_image_shape: [image.size[1], image.size[0]],K.learning_phase(): 0})print('Found {} boxes for {}'.format(len(out_boxes), 'img'))# 设置字体font = ImageFont.truetype(font='font/simhei.ttf',size=np.floor(3e-2 * image.size[1] + 0.5).astype('int32'))thickness = (image.size[0] + image.size[1]) // 300small_pic = []for i, c in list(enumerate(out_classes)):predicted_class = self.class_names[c]box = out_boxes[i]score = out_scores[i]top, left, bottom, right = boxtop = top - 5left = left - 5bottom = bottom + 5right = right + 5top = max(0, np.floor(top + 0.5).astype('int32'))left = max(0, np.floor(left + 0.5).astype('int32'))bottom = min(image.size[1], np.floor(bottom + 0.5).astype('int32'))right = min(image.size[0], np.floor(right + 0.5).astype('int32'))# 画框框label = '{} {:.2f}'.format(predicted_class, score)draw = ImageDraw.Draw(image)label_size = draw.textsize(label, font)label = label.encode('utf-8')print(label)if top - label_size[1] >= 0:text_origin = np.array([left, top - label_size[1]])else:text_origin = np.array([left, top + 1])for i in range(thickness):draw.rectangle([left + i, top + i, right - i, bottom - i],outline=self.colors[c])draw.rectangle([tuple(text_origin), tuple(text_origin + label_size)],fill=self.colors[c])draw.text(text_origin, str(label, 'UTF-8'), fill=(0, 0, 0), font=font)del drawend = timer()print(end - start)#进行追踪return_boxes = []return_scores = []return_class_names = []count = 0# with graph.as_default():for i, c in reversed(list(enumerate(out_classes))):predicted_class = self.class_names[c]# if predicted_class != 'person':  # 确定追踪类别,追啥就是啥#     continue#显示当前屏幕内未带人数if predicted_class == 'person':  # Modify to detect other classes.count = count + 1box = out_boxes[i]score = out_scores[i]x = int(box[1])y = int(box[0])w = int(box[3] - box[1])h = int(box[2] - box[0])if x < 0:w = w + xx = 0if y < 0:h = h + yy = 0return_boxes.append([x, y, w, h])return_scores.append(score)return_class_names.append(predicted_class)return return_boxes, return_scores, return_class_names,image,countdef close_session(self):self.sess.close()

第二部分 main函数部分

from __future__ import division, print_function, absolute_import
import sys
#sys.path.remove('/opt/ros/kinetic/lib/python2.7/dist-packages')
import os
import datetime
from timeit import time
import warnings
import cv2
import numpy as np
import argparse
from PIL import Image
from yolo import YOLOfrom deep_sort import preprocessing
from deep_sort import nn_matching
from deep_sort.detection import Detection
from deep_sort.tracker import Tracker
from tools import generate_detections as gdet
from deep_sort.detection import Detection as ddet
from collections import deque
from keras import backend
import tensorflow as tf
from tensorflow.compat.v1 import InteractiveSession
# config = tf.ConfigProto()
config = tf.compat.v1.ConfigProto()
config.gpu_options.allow_growth = True
session = InteractiveSession(config=config)
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtGui import *
from PyQt5.QtCore import *
from PyQt5.QtWidgets import QInputDialog, QLineEdit, QDialog
from PyQt5.QtWidgets import QApplication
from probar import *
ap = argparse.ArgumentParser()
ap.add_argument("-i", "--input",help="path to input video", default = "./test_video/test.mp4")
ap.add_argument("-c", "--class",help="name of class", default = "person")
args = vars(ap.parse_args())pts = [deque(maxlen=30) for _ in range(9999)]
warnings.filterwarnings('ignore')# initialize a list of colors to represent each possible class label
np.random.seed(100)
COLORS = np.random.randint(0, 255, size=(200, 3),dtype="uint8")
#list = [[] for _ in range(100)]def mainback(self,input,yolo):# QtCore.QCoreApplication.setAttribute(QtCore.Qt.AA_EnableHighDpiScaling)# app = QApplication(sys.argv)#展开等待界面wait()#开始计时start = time.time()max_cosine_distance = 0.3nn_budget = Nonenms_max_overlap = 1.0counter = []#deep_sort#载入deepsort所用模型model_filename = 'model_data/market1501.pb'encoder = gdet.create_box_encoder(model_filename,batch_size=1)#设置查找目标find_objects = ['person']#调用追踪函数metric = nn_matching.NearestNeighborDistanceMetric("cosine", max_cosine_distance, nn_budget)tracker = Tracker(metric)#可以从设置参数中获得input,也可以从函数调用时直接传入writeVideo_flag = True#处理视频成一帧一帧video_capture = cv2.VideoCapture(input)if writeVideo_flag:# Define the codec and create VideoWriter objectw = int(video_capture.get(3))h = int(video_capture.get(4))fourcc = cv2.VideoWriter_fourcc(*'MJPG')out = cv2.VideoWriter('./output/output.avi', fourcc, 15, (w, h))list_file = open('detection_rslt.txt', 'w')frame_index = -1fps = 0.0#循环处理每一帧的图片while True:#获取每一帧图片为三维列表的形式ret, frame = video_capture.read()  # frame shape 640*480*3if ret != True:breakt1 = time.time()image = Image.fromarray(frame[..., ::-1])  # bgr to rgb#将获取的每一帧图片进行YOLO识别检测并画出框框,并使用deepsort对目标对象进行追踪boxs, confidence, class_names,frame,record= yolo.detect_image(image)frame = np.array(frame)# RGBtoBGR满足opencv显示格式frame = cv2.cvtColor(frame, cv2.COLOR_RGB2BGR)fps = (fps + (1. / (time.time() - t1))) / 100print("fps= %.2f" % (fps))#处理在图片上显示帧数frame = cv2.putText(frame, "fps= %.2f" % (fps), (0, 40), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 2)# cv2.imshow("video", frame)c = cv2.waitKey(1) & 0xffif c == 27:capture.release()breakfeatures = encoder(frame,boxs)# score to 1.0 here).detections = [Detection(bbox, 1.0, feature) for bbox, feature in zip(boxs, features)]# Run non-maxima suppression.boxes = np.array([d.tlwh for d in detections])scores = np.array([d.confidence for d in detections])indices = preprocessing.non_max_suppression(boxes, nms_max_overlap, scores)detections = [detections[i] for i in indices]# Call the trackertracker.predict()tracker.update(detections)i = int(0)indexIDs = []c = []boxes = []for det in detections:bbox = det.to_tlbr()cv2.rectangle(frame,(int(bbox[0]), int(bbox[1])), (int(bbox[2]), int(bbox[3])),(255,255,255), 2)#print(class_names)#print(class_names[p])for track in tracker.tracks:if not track.is_confirmed() or track.time_since_update > 1:continue#boxes.append([track[0], track[1], track[2], track[3]])indexIDs.append(int(track.track_id))counter.append(int(track.track_id))bbox = track.to_tlbr()color = [int(c) for c in COLORS[indexIDs[i] % len(COLORS)]]#print(frame_index)list_file.write(str(frame_index)+',')list_file.write(str(track.track_id)+',')cv2.rectangle(frame, (int(bbox[0]), int(bbox[1])), (int(bbox[2]), int(bbox[3])),(color), 3)b0 = str(bbox[0])#.split('.')[0] + '.' + str(bbox[0]).split('.')[0][:1]b1 = str(bbox[1])#.split('.')[0] + '.' + str(bbox[1]).split('.')[0][:1]b2 = str(bbox[2]-bbox[0])#.split('.')[0] + '.' + str(bbox[3]).split('.')[0][:1]b3 = str(bbox[3]-bbox[1])list_file.write(str(b0) + ','+str(b1) + ','+str(b2) + ','+str(b3))#print(str(track.track_id))list_file.write('\n')#list_file.write(str(track.track_id)+',')cv2.putText(frame,str(track.track_id),(int(bbox[0]), int(bbox[1] -50)),0, 5e-3 * 150, (color),2)if len(class_names) > 0:class_name = class_names[0]cv2.putText(frame, str(class_names[0]),(int(bbox[0]), int(bbox[1] -20)),0, 5e-3 * 150, (color),2)i += 1#bbox_center_point(x,y)center = (int(((bbox[0])+(bbox[2]))/2),int(((bbox[1])+(bbox[3]))/2))#track_id[center]pts[track.track_id].append(center)thickness = 5#center pointcv2.circle(frame,  (center), 1, color, thickness)# draw motion pathfor j in range(1, len(pts[track.track_id])):if pts[track.track_id][j - 1] is None or pts[track.track_id][j] is None:continuethickness = int(np.sqrt(64 / float(j + 1)) * 2)cv2.line(frame,(pts[track.track_id][j-1]), (pts[track.track_id][j]),(color),thickness)#cv2.putText(frame, str(class_names[j]),(int(bbox[0]), int(bbox[1] -20)),0, 5e-3 * 150, (255,255,255),2)count = len(set(counter))#将所有行人数和和当前行人数和帧数显示在图片之上cv2.putText(frame, "Total Pedestrian Counter: "+str(count),(int(20), int(120)),0, 5e-3 * 200, (0,255,0),2)cv2.putText(frame, "Current Pedestrian Counter: "+str(i),(int(20), int(80)),0, 5e-3 * 200, (0,255,0),2)cv2.putText(frame, "FPS: %f"%(fps),(int(20), int(40)),0, 5e-3 * 200, (0,255,0),3)# cv2.namedWindow("YOLO4_Deep_SORT", 0);# cv2.resizeWindow('YOLO4_Deep_SORT', 1024, 768);# cv2.imshow('YOLO4_Deep_SORT', frame)#将所有行人数和和当前行人数和帧数显示在前端面板之上self.lcdNumber.setProperty("intValue", count)self.lcdNumber_2.setProperty("intValue", record)#将处理后的图片显示在面板上img = QImage(frame, frame.shape[1], frame.shape[0], frame.shape[1]*3,QImage.Format_RGB888)pix = QPixmap.fromImage(img)pix = pix.scaled(691,501, Qt.KeepAspectRatio, Qt.SmoothTransformation)self.label_4.setPixmap(pix)# show = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)## showImage = QImage(show.data, show.shape[1], show.shape[0], QImage.Format_RGB888)## self.label_4.setPixmap(QPixmap.fromImage(showImage))if writeVideo_flag:# save a frameout.write(frame)frame_index = frame_index + 1fps  = ( fps + (1./(time.time()-t1)) ) / 2out.write(frame)frame_index = frame_index + 1# Press Q to stop!if cv2.waitKey(1) & 0xFF == ord('q'):breakprint(" ")print("[Finish]")end = time.time()video_capture.release()

前端部分(前端部分并不是本人设计)

页面展示

登录界面

主页面

设计

基本控件对应

页面对应

Ui_MainWindow() 主界面

Ui_Dialog1 警告界面

Ui_Dialog2 登录界面

Ui_Dialog3 设置界面

主页面控件设置

基本格式
self.label = QtWidgets.QLabel(self.centralwidget)#初始化一个控件对象
self.label.setGeometry(QtCore.QRect(160, 80, 691, 501))#设置对象面板中位置,标签位置定义方式是(x,y,w,h)
font = QtGui.QFont()#创建格式对象
font.setFamily("黑体")#设置格式对象
font.setPointSize(9)
self.label.setFont(font)#设置字体大小
self.label.setText("") #标签上写字
self.label.setPixmap(QtGui.QPixmap("image/off.png"))#标签上插图
self.label.setScaledContents(True)#使图根据标签大小缩放
self.label.setStyleSheet("color: rgb(88, 101, 208);")
self.label.setObjectName("label")#设置标签控件名称
self.label.raise_() #在面板上显示设置好的标签
控件对应
控件 控件类型 控件标号
开始 pushButton self.pushButton
结束 label self.label_11
警告级别 label self.label_a
共检测人数 label self.label_6
当前人数 label self.label_65
未佩戴人数 label self.label_7
安全帽智能检测系统 label self.label_5
共检测人数框 lcdNumber self.lcdNumber
当前人数框 lcdNumber self.lcdNumber_1
未佩戴人数框 lcdNumber self.lcdNumber_2
一级警报 label self.label_b
二级警报 label self.label_c
三级警报 label self.label_d
日期显示框 dateTimeEdit self.dateTimeEdit
时间显示框 dateTimeEdit self.dateTimeEdit1

登录设计

初始化登录界面的类之后使用登录界面的登录按钮点击触发主界面展示

class parentWindow(QMainWindow):def __init__(self):QMainWindow.__init__(self)self.main_ui = Ui_MainWindow()self.main_ui.setupUi(self)class childWindow1(QDialog):def __init__(self):QDialog.__init__(self)self.child1=Ui_Dialog1()self.child1.setupUi(self)class childWindow2(QDialog):def __init__(self):QDialog.__init__(self)self.child2=Ui_Dialog2()self.child2.setupUi(self)class childWindow3(QDialog):def __init__(self):QDialog.__init__(self)self.child3=Ui_Dialog3()self.child3.setupUi(self)if __name__=='__main__':app=QApplication(sys.argv)#初始化各个窗口child2 = childWindow2()window=parentWindow()child1=childWindow1()child3= childWindow3()#获得登录界面登录按钮btn = child2.child2.pushButton#将登录按钮点击触发和主界面显示事件连接btn.clicked.connect(window.show)#通过toolButton将两个窗体关联btn=window.main_ui.pushButton_3btn.clicked.connect(child1.show)btn = window.main_ui.pushButton_8btn.clicked.connect(child2.show)btn = window.main_ui.pushButton_5btn.clicked.connect(child3.show)#显示登录界面child2.show()sys.exit(app.exec_())

时间设计

#面板类初始化
#开始周期工作
self.timer = QTimer()
##这个通过调用槽函数来刷新时间
self.timer.timeout.connect(self.showTime)
#每隔一秒刷新一次,这里设置为1000ms
self.timer.start(1000)
#接下来是设置面板一打开是所显示的时间
#设置日期牌
self.dateTimeEdit = QtWidgets.QDateTimeEdit(self.centralwidget)
#设置时间牌
self.dateTimeEdit1 = QtWidgets.QDateTimeEdit(self.centralwidget)
#设置日期牌位置
self.dateTimeEdit.setGeometry(QtCore.QRect(870, 50, 111, 21))
#设置日期牌获得当前时间
self.dateTimeEdit.setDateTime(QtCore.QDateTime.currentDateTime())
#设置日期牌的显示格式只要当前时间的日期部分
self.dateTimeEdit.setDisplayFormat("yyyy/MM/dd")
#设置日期牌的名称
self.dateTimeEdit.setObjectName("dateTimeEdit")
#设置时间牌位置
self.dateTimeEdit1.setGeometry(QtCore.QRect(870, 70, 111, 21))
#设置时间牌获得当前时间
self.dateTimeEdit1.setDateTime(QtCore.QDateTime.currentDateTime())
#设置时间牌的显示格式只要当前时间的时间部分
self.dateTimeEdit1.setDisplayFormat("hh:mm:ss")
#设置时间牌的名称
self.dateTimeEdit1.setObjectName("dateTimeEdit1")
#在面板上显示时间牌和日期牌
self.dateTimeEdit.raise_()
self.dateTimeEdit1.raise_()#面板类内的函数
def showTime(self):#与上述一致初始化的在面板上的时间一致,不过是每一秒调用一次,产生动态显示time = QDateTime.currentDateTime()self.dateTimeEdit.setGeometry(QtCore.QRect(870, 50, 111, 21))self.dateTimeEdit.setDateTime(QtCore.QDateTime.currentDateTime())self.dateTimeEdit.setDisplayFormat("yyyy/MM/dd")self.dateTimeEdit.setObjectName("dateTimeEdit")self.dateTimeEdit1.setGeometry(QtCore.QRect(870, 70, 111, 21))self.dateTimeEdit1.setDateTime(QtCore.QDateTime.currentDateTime())self.dateTimeEdit1.setDisplayFormat("hh:mm:ss")self.dateTimeEdit1.setObjectName("dateTimeEdit1")self.dateTimeEdit.raise_()self.dateTimeEdit1.raise_()

警告设计

再次采用了在面板上设置不同图片的方式实现报警

 非警报状态                警报状态

我们在主面板上设置了label_a,label_b,label_c作为三个警报灯,初始的时候的都设置为非警报状态的图片

#设置“警告级别”的标题
self.label_a = QtWidgets.QLabel(self.centralwidget)
self.label_a.setGeometry(QtCore.QRect(880,100, 80, 20))
self.label_a.setFont(font)
self.label_a.setStyleSheet("color: rgb(88, 101, 208);")
self.label_a.setObjectName("label_a")#设置标签并贴上非警报状态的标签
#设置居中
self.label_b = QtWidgets.QLabel(self.centralwidget)
#设置标签位置
self.label_b.setGeometry(QtCore.QRect(900, 130, 40, 50))
#设置标签字体
self.label_b.setFont(font)
#设置标签图片
self.label_b.setPixmap(QtGui.QPixmap("image/off.png"))
#设置图片自适应标签大小缩放
self.label_b.setScaledContents(True)
self.label_b.setStyleSheet("color: rgb(88, 101, 208);")
#设置标签名称
self.label_b.setObjectName("label_b")self.label_c = QtWidgets.QLabel(self.centralwidget)
self.label_c.setGeometry(QtCore.QRect(880, 190, 40, 50))
self.label_c.setFont(font)
self.label_c.setPixmap(QtGui.QPixmap("image/off.png"))
self.label_c.setScaledContents(True)
self.label_c.setStyleSheet("color: rgb(88, 101, 208);")
self.label_c.setObjectName("label_c")self.label_d = QtWidgets.QLabel(self.centralwidget)
self.label_d.setGeometry(QtCore.QRect(930, 190, 40, 50))
self.label_d.setFont(font)
self.label_d.setPixmap(QtGui.QPixmap("image/off.png"))
self.label_d.setScaledContents(True)
self.label_d.setStyleSheet("color: rgb(88, 101, 208);")
self.label_d.setObjectName("label_d")


然后我们通过前后端的连接,通过判断为佩戴帽子人数对其三个灯设置不同亮的转态在相同标签处贴上警报状态的图片

当人数达到警报级别时灯的改变

if(record > 0 and record <= 5):#当未佩戴帽子的人数为(0,5]时,一级警报只有第一个为警报状态,其余为非警报状态self.label_b.setPixmap(QtGui.QPixmap("image/on.png"))self.label_c.setPixmap(QtGui.QPixmap("image/off.png"))self.label_d.setPixmap(QtGui.QPixmap("image/off.png"))
if(record > 5 and record <= 10):#当未佩戴帽子的人数为(5,10]时,二级警报前两个为警报状态,最后一个为非警报状态self.label_b.setPixmap(QtGui.QPixmap("image/on.png"))self.label_c.setPixmap(QtGui.QPixmap("image/on.png"))self.label_d.setPixmap(QtGui.QPixmap("image/off.png"))
if (record > 10):#当未佩戴帽子的人数为十个以上时,三级警报级警报全为警报状态self.label_b.setPixmap(QtGui.QPixmap("image/on.png"))self.label_c.setPixmap(QtGui.QPixmap("image/on.png"))self.label_d.setPixmap(QtGui.QPixmap("image/on.png"))

要注意的是这里边每一种情况都都需要对每一个灯都需要重置转态,即重贴预想的标签,对应等级只调整对应级数的灯,会导致从高级向低级状态改变时灯无法关闭

对于灯的问题,多整几张不同状态下的图,换图就行了,自己绘制肯定是没有问题,但如果用PS做好图片当然是最简单的办法,而且效率肯定比自己绘制高,因为绘制是需要大量的计算,没有太复杂的计算,就是内个层加渐变。

暂时界面如此还需更多的设计

但是从点击开始之后的文件导入知道现实在面板上是本人实现

    #在面板上设置一个按钮,并将按钮的点击事件和打开文件想连self.pushButton.clicked.connect(self.openfile)def openfile(self):#设置打开文件页面的初始化位置path = "G:\\软件杯"#设置打开文件页面,并返回带有文件路径的结果#(['G:/软件杯/deep_sort_yolov4_fix/test_video/cut.mp4'], 'All Files (*)')openfile_name = QFileDialog.getOpenFileNames(None, "请选择要添加的文件", path, "Text Files (*.xls);;All Files (*)")#获取返回结果中的路径字符串形式path_list = openfile_name[0]path_name = path_list[0]#调用函数,产生等待界面,进行目标检测并追踪并且返回到主面板上mainback(self,path_name,YOLO())

前后端的连接问题:

作为我进行前后端的连接也遇到了许多的问题,我的基本思路有两种:

1.第一个是把各种从后端处理到的数据输出来然后贴在前端的面板上,我发现得返回的结果是一帧一帧的图片和每个图片对应的检测结果再循环当中一轮一轮输出结果传到前端比较费劲,所谓以我转移将后端结果输出到前端显示的方法,选用第二种方法

2.第二种方法就是我将设置好样式的面板实例化后输入到后端,直接在后端实时的将结果直接贴在面板之上就实现了将后端结果在前端展示,从而实现前后端的连接

连接函数如下:

mainback(self,path_name,YOLO())

1)参数:YOLO()
原本这是后端的main.py的主函数,直接使用主函数调用,需要传入一个YOLO对象所以我们mainback函数仍需该参数YOLO()

 if __name__ == '__main__':main(YOLO())

2)参数: self

我们需要把主面板传入到后端当中,所以需要一个传入主面板的对象就主面板类的引用,而我们的mainback函数正好位于按钮的点击触发时间当中,二点击触犯函数位于主面板的类当中,所以此时self就是对主面板的引用,所以具有该类的一切属性,所以我我们可以直接将self最为主面板对象传入后端,并且在该面板对象上添加我们需要输出的后端结果

3)参数:path_name
G:\软件杯\deep_sort_yolov4_fix\main.py
作为后端的起始程序,正常直接调用的的时候我们需要输入追踪类别,视频位置等信息
即如下:

python main.py -c person -i test_vedio/test.avi

我们可以直接在命令行输入上述语句运行程序,并且可以在前端使用下面语句调用后端程序(str=上面的命令行语句组成字符串):

os.system(str)
subprocess.run(str)

这种调用只能实现在前端运行后端程序,但是并不能实现前后端的连接,如果想进行数据连接需要使用函数调用的方式,如果仅仅是视频地址信息可以传入,但是如何传入面板和yolo对象暂时不会实现所以采用函数的方式实现相同的目的。所以需要传入我们想识别的视频,而视频的地址在我们选择文件夹函数的结果中可以提取到,所以我们需要将它通过函数参数的形式传入后端。

目标检测—安全帽检测实践相关推荐

  1. AI人脸检测/口罩检测/安全帽检测智能分析网关告警推送功能开发

    智能分析网关是可支持AI视频智能分析功能,包括人体检测.人脸检测.区域入侵检测.安全帽检测.口罩检测等,可广泛应用于客流统计.安防监控.周界防范.企业安全生产.公共防疫等场景.目前我们仍在进一步拓展更 ...

  2. AI人脸检测/安全帽检测智能分析网关告警消息配置——微信告警消息配置

    AI智能分析网关内置多种深度学习算法,可支持对接入的多路视频流进行智能检测.智能识别等,包括人脸检测与识别.车辆检测与识别.车牌识别.烟火识别.安全帽识别.区域入侵检测等.将智能分析网关与EasyCV ...

  3. 青源LIVE第22期|旷视刘松涛:YOLOX,高性能目标检测的最新实践

    在目标检测领域中,YOLO系列以其一贯以来的高速度.高精度和算子简单.易部署的特性,在工业界中得到广泛的好评和应用. 近两年来,学术界在Anchor Free和样本匹配(Label Assignmen ...

  4. 【目标检测】YOLO v5 安全帽检测识别项目模型

    提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 YOLO v5安全帽检测模型 前言 相关连接: 一.计算机配置 pytorch安装 pycocotools的安装 二.YOLO v5下 ...

  5. 基于Faster-rcnn的安全帽检测(使用Colab进行训练)

    基于Faster-rcnn的安全帽检测(使用Colab进行训练) 前言 源码与数据集下载 数据预处理 数据集目录结构 划分训练.验证.测试集 运行步骤 补充说明 项目根目录 数据可视化 训练 模型 参 ...

  6. 基于YOLOv5的智慧工地实现---安全帽检测(2)

    基于YOLOv5的智慧工地安全帽检测 代码下载地址:下载地址 Smart_Construction 该项目是使用 YOLOv5 v2.x 的程序来训练在智能工地安全领域中头盔目标检测的应用 指标 yo ...

  7. 基于YOLOV3的安全帽检测

    " 作为目标检测的鸿篇巨制YOLOV3,用来做安全帽检测非常合适" 01 - Yolov3简介 Yolo_v3使用了darknet-53的前面的52层(没有全连接层),yolo_v ...

  8. 【深度学习】搭建人工智能服务网站(安全帽检测)

    电力图像分类最典型的场景就是安全帽佩戴识别. 针对电网作业现场人员行为的图像数据,采用目标检测.图像识别等人工智能技术,对电网作业现场人员是否规范佩戴安全帽进行检测识别.通过计算平均精确率.漏检率.误 ...

  9. 厂区佩戴安全帽检测算法 yolov5

    佩戴安全帽检测算法通过 yolov5网络模型对现场画面进行实时监测.YOLOv5是一种单阶段目标检测算法,该算法在YOLOv4的基础上添加了一些新的改进思路,使其速度与精度都得到了极大的性能提升.在模 ...

最新文章

  1. AI in RTC 创新挑战赛 | 超分辨率挑战开始了!
  2. oracle 自治数据库 培训,Oracle数据库掌门人,Andrew Mendelsohn 谈自治数据库
  3. 利用python爬虫(part11)--XpathHelper为啥不能全信之JS要闹哪般
  4. alert回调_你知道javascript函数的回调怎么用吗?
  5. Java基础:int和Integer的区别
  6. python将excel表按地方拆分_Python将一个Excel拆分为多个Excel
  7. 管理低代码公民开发人员的8个技巧
  8. 《深入理解 Spring Cloud 与微服务构建》第八章 声明式调用 Feign
  9. paip.提升用户体验-----c++ gcc 命令在notepad++扩展中的配置..
  10. 企业全面运营管理沙盘模拟心得_任景锋-企业全面运营管理沙盘模拟
  11. ubuntu 设置静态路由_ubuntu 配置静态路由
  12. 电商平台的数据库设计
  13. Unity中XChart饼图如何增加调色盘颜色选项
  14. 使用结构化思维,让工作有条不紊
  15. 商用计算机品牌,请问什么牌子的笔记本比较好啊?要商用的
  16. html页面生成easyui,Easyui 为网页创建边框布局_EasyUI 教程
  17. java图片双缓存_Java 双缓冲技术消除图片闪动
  18. SQL查询 — 自连接的用法
  19. 如何正确高效使用搜索引擎
  20. 引用或者打开JS文件乱码问题

热门文章

  1. 论return 0的高级写法 bushi​​​​​​​)
  2. backtrader回测框架实例
  3. 支付宝SDK官方下载地址
  4. 计算机收藏夹位于哪个磁盘,电脑浏览器收藏夹保存在哪里
  5. 运维自动化之ANSIBLE
  6. 邮件服务器问题--邮件积压、传递延迟解决方法
  7. unity-shader-ShaderGraph可视化shader
  8. selenium新浪邮箱注册句柄切换实战
  9. seata-tcc简单使用
  10. 《Python深度学习》第一章笔记