当前位置:   article > 正文

课堂违规行为识别系统_ff3838', 'ff9d97', 'ff701f', 'ffb21d', 'cfd231', '

ff3838', 'ff9d97', 'ff701f', 'ffb21d', 'cfd231', '48f90a', '92cc17', '3ddb8

本文写的是一个课堂识别系统 分别识别睡觉和打哈欠并对班级进行扣分处理 

代码目录:

1、yolo识别

        将训练好的模型转换为onnx 在终端运行此代码将导出的模型放在model文件夹内

python export.py --weights yolov5s.pt --include onnx

  解析yolo模型我这边使用的是opencv的dnn来解析yolo模型进行识别 下面是他的部分代码

  1. class Colors:
  2. # Ultralytics color palette https://ultralytics.com/
  3. def __init__(self):
  4. # hex = matplotlib.colors.TABLEAU_COLORS.values()
  5. hex = ('FF3838', 'FF9D97', 'FF701F', 'FFB21D', 'CFD231', '48F90A', '92CC17', '3DDB86', '1A9334', '00D4BB',
  6. '2C99A8', '00C2FF', '344593', '6473FF', '0018EC', '8438FF', '520085', 'CB38FF', 'FF95C8', 'FF37C7')
  7. self.palette = [self.hex2rgb('#' + c) for c in hex]
  8. self.n = len(self.palette)
  9. def __call__(self, i, bgr=False):
  10. c = self.palette[int(i) % self.n]
  11. return (c[2], c[1], c[0]) if bgr else c
  12. @staticmethod
  13. def hex2rgb(h): # rgb order (PIL)
  14. return tuple(int(h[1 + i:1 + i + 2], 16) for i in (0, 2, 4))
  15. colors = Colors()
  16. class yolov5():
  17. def __init__(self, onnx_path, confThreshold=0.25, nmsThreshold=0.45):
  18. # self.classes=["yawn","sleep"]
  19. self.classes = ['person', 'bicycle', 'car', 'motorcycle', 'airplane', 'bus', 'train', 'truck', 'boat',
  20. 'traffic light',
  21. 'fire hydrant', 'stop sign', 'parking meter', 'bench', 'bird', 'cat', 'dog', 'horse', 'sheep',
  22. 'cow',
  23. 'elephant', 'bear', 'zebra', 'giraffe', 'backpack', 'umbrella', 'handbag', 'tie', 'suitcase',
  24. 'frisbee',
  25. 'skis', 'snowboard', 'sports ball', 'kite', 'baseball bat', 'baseball glove', 'skateboard',
  26. 'surfboard',
  27. 'tennis racket', 'bottle', 'wine glass', 'cup', 'fork', 'knife', 'spoon', 'bowl', 'banana',
  28. 'apple',
  29. 'sandwich', 'orange', 'broccoli', 'carrot', 'hot dog', 'pizza', 'donut', 'cake', 'chair',
  30. 'couch',
  31. 'potted plant', 'bed', 'dining table', 'toilet', 'tv', 'laptop', 'mouse', 'remote', 'keyboard',
  32. 'cell phone',
  33. 'microwave', 'oven', 'toaster', 'sink', 'refrigerator', 'book', 'clock', 'vase', 'scissors',
  34. 'teddy bear',
  35. 'hair drier', 'toothbrush']
  36. self.colors = [np.random.randint(0, 255, size=3).tolist() for _ in range(len(self.classes))]
  37. num_classes = len(self.classes)
  38. self.anchors = [[10, 13, 16, 30, 33, 23], [30, 61, 62, 45, 59, 119], [116, 90, 156, 198, 373, 326]]
  39. self.nl = len(self.anchors)
  40. self.na = len(self.anchors[0]) // 2
  41. self.no = num_classes + 5
  42. self.stride = np.array([8., 16., 32.])
  43. self.inpWidth = 640
  44. self.inpHeight = 640
  45. self.net = cv2.dnn.readNetFromONNX(onnx_path)
  46. self.confThreshold = confThreshold
  47. self.nmsThreshold = nmsThreshold

判断传人的文件是视频还是图片或者实时识别:

  1. def mult_test(onnx_path, img_dir, save_root_path, video=False):
  2. model = yolov5(onnx_path)
  3. if video:
  4. cap = cv2.VideoCapture(0)
  5. frame_height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
  6. frame_width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
  7. fps = cap.get(cv2.CAP_PROP_FPS) # 视频平均帧率
  8. size = (frame_height, frame_width) # 尺寸和帧率和原视频相同
  9. fourcc = cv2.VideoWriter_fourcc(*'XVID')
  10. out = cv2.VideoWriter('zi.mp4', fourcc, fps, size)
  11. while cap.isOpened():
  12. ok, frame = cap.read()
  13. if not ok:
  14. break
  15. frame,rr = model.detect(frame)
  16. out.write(frame)
  17. cv2.imshow('result', frame)
  18. c = cv2.waitKey(1) & 0xFF
  19. if c == 27 or c == ord('q'):
  20. break
  21. cap.release()
  22. out.release()
  23. cv2.destroyAllWindows()
  24. else:
  25. if not os.path.exists(save_root_path):
  26. os.mkdir(save_root_path)
  27. for root, dir, files in os.walk(img_dir):
  28. for file in files:
  29. image_path = os.path.join(root, file)
  30. save_path = os.path.join(save_root_path, file)
  31. if "mp4" in file or 'avi' in file:
  32. cap = cv2.VideoCapture(image_path)
  33. frame_height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
  34. frame_width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
  35. fps = cap.get(cv2.CAP_PROP_FPS)
  36. size = (frame_width, frame_height)
  37. fourcc = cv2.VideoWriter_fourcc(*'XVID')
  38. out = cv2.VideoWriter(save_path, fourcc, fps, size)
  39. while cap.isOpened():
  40. ok, frame = cap.read()
  41. if not ok:
  42. break
  43. frame,rr= model.detect(frame)
  44. out.write(frame)
  45. cap.release()
  46. out.release()
  47. print(" finish: ", file)
  48. elif 'jpg' or 'png' in file:
  49. srcimg = cv2.imread(image_path)
  50. srcimg ,rr= model.detect(srcimg)
  51. print(" finish: ", file)
  52. cv2.imwrite(save_path, srcimg)

2、目标跟踪 

目标跟踪我使用的是deepsort算法

  1. def detect(self, srcimg):
  2. results=[]
  3. im = srcimg.copy()
  4. im, ratio, wh = self.letterbox(srcimg, self.inpWidth, stride=self.stride, auto=False)
  5. # Sets the input to the network
  6. blob = cv2.dnn.blobFromImage(im, 1 / 255.0, swapRB=True, crop=False)
  7. self.net.setInput(blob)
  8. outs = self.net.forward(self.net.getUnconnectedOutLayersNames())[0]
  9. # NMS
  10. pred = self.non_max_suppression(outs, self.confThreshold, agnostic=False)
  11. # print(box[1])
  12. result_list = []
  13. # print(pred)
  14. # draw box
  15. for i in pred[0]:
  16. left = int((i[0] - wh[0]) / ratio[0])
  17. top = int((i[1] - wh[1]) / ratio[1])
  18. width = int((i[2] - wh[0]) / ratio[0])
  19. height = int((i[3] - wh[1]) / ratio[1])
  20. # 假设 left、top、width、height 分别为在640尺寸图片上得到的框的坐标
  21. # ratio 为 原始图片尺寸 / 640
  22. # print(img11[0]/640)
  23. # x, y, w, h = int((i[0] - wh[0]) / ratio[0]), int((i[1] - wh[1]) / ratio[1]), int((i[2]) / ratio[0]), int(
  24. # (i[3]) / ratio[1])
  25. conf = i[4]##置信度
  26. classId = i[5]##id
  27. cv2.rectangle(srcimg, (int(left), int(top)), (int(width), int(height)), colors(classId, True), 2,
  28. lineType=cv2.LINE_AA)
  29. label = '%.2f' % conf
  30. label = '%s:%s' % (self.classes[int(classId)], label)
  31. # Display the label at the top of the bounding box
  32. labelSize, baseLine = cv2.getTextSize(label, cv2.FONT_HERSHEY_SIMPLEX, 0.5, 1)
  33. top = max(top, labelSize[1])
  34. cv2.putText(srcimg, label, (int(left - 20), int(top - 10)), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 255),
  35. thickness=1, lineType=cv2.LINE_AA)
  36. result = torch.Tensor([left,top,width,height, conf, classId]).unsqueeze(0) # 转换为张量并添加一个维度
  37. # print(result)
  38. result_list.append(result)
  39. if len(result_list) == 0:
  40. # 创建一个空的 Tensor 对象,或者使用已有的非空 Tensor 对象
  41. tensor = torch.Tensor()
  42. result_list.append(tensor)
  43. results.append(torch.cat(result_list, dim=0).cpu().detach())
  44. # print([result.tolist() for result in results[0]])
  45. # print(results)
  46. return results

将yolo检测到的目标框的信息(每一帧)传给deepsort进行处理判断是否是同一个对象如果是新对象id+1

  1. 在每一帧中,目标跟踪模块将通过目标检测器获得的边界框作为输入,并在当前帧中建立与前一帧中目标的关联。这样可以实现目标的连续跟踪。DeepSORT使用一种称为卡尔曼滤波器的方法来对目标位置进行预测和更新。卡尔曼滤波器使用一个动态模型来估计目标的运动轨迹,并根据观测结果进行修正。

  2. ID关联: DeepSORT通过将目标的外观特征与运动信息相结合,将当前帧中的目标与已经被跟踪的目标进行关联。它使用深度神经网络来提取目标的外观特征,并计算不同目标之间的相似度。通过计算相似度,DeepSORT能够判断当前帧中的目标是否与之前跟踪的目标相匹配,从而实现目标的ID关联。

3、qt界面

qt界面部分代码:

  1. class MainWindow(QWidget):
  2. def __init__(self):
  3. super().__init__()
  4. self.num=0
  5. self.setWindowTitle("课堂行为检测系统V1")
  6. self.setup_ui()
  7. self.image=None
  8. self.media_player = QMediaPlayer(self)
  9. self.resize(800, 600)
  10. def setup_ui(self):
  11. """设置主窗口布局"""
  12. layout = QVBoxLayout(self)
  13. # 添加标题标签
  14. label = QLabel("<html><head/><body><p><span style=\" font-size:20pt; color:#00007f;\">课堂行为检测系统V1</span></p></body></html>")
  15. label.setAlignment(Qt.AlignHCenter)
  16. layout.addWidget(label)
  17. # 添加视频播放部件和文本编辑部件
  18. video_layout = QHBoxLayout()
  19. self.video_widget = QVideoWidget(self)
  20. video_layout.addWidget(self.video_widget, 3)
  21. self.label2 = QLabel(self)
  22. self.label2.hide()
  23. self.label2.setFixedSize(640,640)
  24. video_layout.addWidget(self.label2, 2)
  25. self.text_edit = QPlainTextEdit(self)
  26. video_layout.addWidget(self.text_edit, 2)
  27. self.text_edit.setPlaceholderText("识别到的数量")
  28. layout.addLayout(video_layout)
  29. # 添加按钮部件
  30. button_layout = QHBoxLayout()
  31. layout.addLayout(button_layout)
  32. self.open_file_button = QPushButton("传入文件")
  33. self.open_file_button.clicked.connect(self.open_file_dialog)
  34. button_layout.addWidget(self.open_file_button)
  35. self.start_detection_button = QPushButton("开始检测")
  36. self.start_detection_button.clicked.connect(self.start_detection)
  37. button_layout.addWidget(self.start_detection_button)
  38. self.start_realtime_detection_button = QPushButton("实时检测")
  39. self.start_realtime_detection_button.clicked.connect(self.start_realtime_detection)
  40. button_layout.addWidget(self.start_realtime_detection_button)
  41. self.stop_detection_button = QPushButton("停止检测")
  42. self.stop_detection_button.clicked.connect(self.stop_detection)
  43. button_layout.addWidget(self.stop_detection_button)
  44. self.stop_start_playing=QPushButton("播放")
  45. self.stop_start_playing.clicked.connect(self.play)
  46. button_layout.addWidget(self.stop_start_playing)

点击转入文件会将文件传入到input文件夹内 点击识别会将视频识别后存放在output文件夹内并进行播放 目标跟踪会转回目标数量 进行班级扣分处理发现睡觉和打哈欠一共有3个人所以班级扣除分数3分  并且页面内也加入实时识别功能 可以加入教室摄像头进行班级识别

教室违规行为识别系统

本文制作不易 有些地方写的不好还请见谅  

                                                如果觉得写的还好请给博主个小星星⭐️每一个小星星都是让博主努力的动力

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家自动化/article/detail/470018
推荐阅读
相关标签
  

闽ICP备14008679号