|
|
@ -1,8 +1,13 @@ |
|
|
|
from flask import Flask, request, jsonify |
|
|
|
from pymongo import MongoClient |
|
|
|
from ultralytics import YOLO |
|
|
|
from PIL import Image |
|
|
|
import base64 |
|
|
|
from io import BytesIO |
|
|
|
from bson import ObjectId |
|
|
|
import hashlib |
|
|
|
import json |
|
|
|
import os |
|
|
|
from flask import Flask, request |
|
|
|
from flask_socketio import SocketIO, emit, join_room, leave_room |
|
|
|
import time |
|
|
@ -20,6 +25,12 @@ clients = [] |
|
|
|
adminSid = "" |
|
|
|
# 初始化考试状态 |
|
|
|
studentStatus = {} |
|
|
|
current_dir = os.path.dirname(os.path.abspath(__file__)) |
|
|
|
weights = os.path.join(current_dir, "exam.pt") |
|
|
|
print(89744, weights) |
|
|
|
model = YOLO(weights) |
|
|
|
frame_rate_divider = 300 # 设置帧率除数 |
|
|
|
frame_count = 0 # 初始化帧计数器 |
|
|
|
|
|
|
|
|
|
|
|
def dealStudentStatus(): |
|
|
@ -60,12 +71,50 @@ def handle_video_frame(message): |
|
|
|
# 广播视频帧给老师 |
|
|
|
global adminSid |
|
|
|
global studentStatus |
|
|
|
global model |
|
|
|
global frame_rate_divider |
|
|
|
global frame_count |
|
|
|
|
|
|
|
# print(f"Received video frame from {message['userId']}") |
|
|
|
socketio.emit( |
|
|
|
"teacherVideo" + message["userId"], message, to=adminSid, namespace="/ws/video" |
|
|
|
) |
|
|
|
if studentStatus[message["userId"]]: |
|
|
|
print(f"学生{message['userId']}已作弊", f"{studentStatus[message['userId']]}") |
|
|
|
if frame_count % frame_rate_divider == 0: |
|
|
|
# 这里省略了实际的base64数据 |
|
|
|
base64_str = message["data"] |
|
|
|
# 解码base64字符串 |
|
|
|
_, img_data = base64_str.split(",") |
|
|
|
img_data = base64.b64decode(img_data) |
|
|
|
# 将字节流转换为PIL图像对象 |
|
|
|
image = Image.open(BytesIO(img_data)) |
|
|
|
results = model.predict(source=image, iou=0.5, conf=0.25) |
|
|
|
det = results[0] |
|
|
|
checkVedioResult(det) |
|
|
|
frame_count += 1 # 更新帧计数器 |
|
|
|
frame_count %= frame_rate_divider # 更新帧计数器 |
|
|
|
# print(99777,frame_count) |
|
|
|
# if studentStatus[message["userId"]]: |
|
|
|
# print(f"学生{message['userId']}已作弊", f"{studentStatus[message['userId']]}") |
|
|
|
|
|
|
|
|
|
|
|
def checkVedioResult(det): |
|
|
|
# 如果有有效的检测结果 |
|
|
|
# {"cheating": "疑似作弊", "good": "良好", "normal": "正常"} |
|
|
|
if det is not None and len(det): |
|
|
|
results = [] # 初始化结果列表 |
|
|
|
for res in det.boxes: |
|
|
|
for box in res: |
|
|
|
# 提前计算并转换数据类型 |
|
|
|
class_id = int(box.cls.cpu()) |
|
|
|
bbox = box.xyxy.cpu().squeeze().tolist() |
|
|
|
bbox = [int(coord) for coord in bbox] # 转换边界框坐标为整数 |
|
|
|
result = { |
|
|
|
"bbox": bbox, # 边界框 |
|
|
|
"score": box.conf.cpu().squeeze().item(), # 置信度 |
|
|
|
"class_id": class_id, # 类别ID |
|
|
|
} |
|
|
|
results.append(result) # 将结果添加到列表 |
|
|
|
print(587744, results) |
|
|
|
|
|
|
|
|
|
|
|
@socketio.on("talk", namespace="/ws/video") |
|
|
@ -241,6 +290,7 @@ def insert_data(): |
|
|
|
"banji": userJson["banji"], |
|
|
|
"xueshengxingming": userJson["xueshengxingming"], |
|
|
|
"xuehao": userJson["xuehao"], |
|
|
|
"kaoshengtupian": userJson["kaoshengtupian"], |
|
|
|
"mima": md5_encrypt(userJson["mima"]), |
|
|
|
"chengji": userJson["chengji"], |
|
|
|
"zuobiqingkuang": userJson["zuobiqingkuang"], |
|
|
@ -310,6 +360,7 @@ def update_data(): |
|
|
|
"banji": userJson["banji"], |
|
|
|
"xueshengxingming": userJson["xueshengxingming"], |
|
|
|
"xuehao": userJson["xuehao"], |
|
|
|
"kaoshengtupian": userJson["kaoshengtupian"], |
|
|
|
"chengji": userJson["chengji"], |
|
|
|
"zuobiqingkuang": userJson["zuobiqingkuang"], |
|
|
|
"kaoshileixing": userJson["kaoshileixing"], |
|
|
|