当前位置:首页>python>Python实现YOLOv8n 智能监控分析系统 v1.0

Python实现YOLOv8n 智能监控分析系统 v1.0

  • 2026-06-25 15:45:07
Python实现YOLOv8n 智能监控分析系统 v1.0

YOLOv8n 智能监控分析系统 v1.0

基于 YOLOv8n + PyQt5 的桌面端智能监控分析工具,支持视频分析、人物检索、车辆分析、监控录像回放,左右双画面实时对比展示。

作者信息

项目
内容
作者
杨少平
公众号
Python学在坚持
微信
ysp2338084
版本
v1.0

运行方式

pip install PyQt5 opencv-python ultralytics numpypython ysp/code/yolo_monitor.py

如果没有安装 ultralytics(YOLOv8),系统会自动切换到模拟检测模式,界面功能完整可用。

界面布局

+------------------------------------------------------------------+|  YOLOv8n 智能监控分析系统 v1.0                                     |+------------------------------------------------------------------+|  [视频源输入框] [选择文件] [摄像头] 置信度:[===] 速度:[1x]          ||  [开始分析] [暂停] [停止] 轨迹 标签              分析中...          |+---------------------------------+--------------------------------+|                                 |                                ||   原始画面       分析画面        |  [统计] [告警] [检索]           ||  +-----------+ +-----------+   |  [设置] [关于]                  ||  |           | |  ID:1 人   |   |                                ||  |  原始视频  | |  +--+     |   |  人数: 3                       ||  |  无标注    | |  |  |框   |   |  车辆: 2                       ||  |           | |  +--+     |   |  追踪ID: 5                     ||  |           | |  ~~~轨迹   |   |                                ||  +-----------+ +-----------+   |  历史趋势...                    ||                                 |                                |+---------------------------------+--------------------------------+|  [10:23:45] 开始分析: test.mp4                                    ||  [10:23:46] 入侵告警: ID3 人                                     ||  事件日志区域(最新在上)                                           |+------------------------------------------------------------------+

核心特色:

  • 左侧显示原始画面,右侧显示 AI 标注后的分析画面,实时对比
  • 右键在分析画面上拖拽可绘制禁区(红色虚线框)
  • 底部事件日志实时滚动

功能模块

视频源接入

  • 本地视频文件(MP4/AVI/MOV/FLV/MKV)
  • 网络摄像头(RTSP/RTMP 流地址)
  • USB 摄像头(输入 0 即可)
  • 倍速控制:0.5x / 1x / 2x / 4x / 8x

检测与追踪

  • YOLOv8n 实时目标检测(人物 + 车辆)
  • 基于 IoU 的多目标追踪,持续 ID 不丢失
  • 运动轨迹可视化(渐变粗细线条)
  • 置信度阈值可调(0.10 ~ 0.95)

告警功能

  • 右键拖拽绘制禁区,目标进入自动告警
  • 告警日志实时记录
  • 支持多个禁区同时生效

目标检索

  • 按追踪 ID 精确检索目标信息
  • 显示目标类型、位置、轨迹点数、状态

统计报表

  • 实时人数/车辆数统计
  • 历史趋势记录
  • 导出统计报表(TXT)

关键代码解析

关键代码一:基于 IoU 的多目标追踪器

这是整个系统的追踪核心,负责在连续帧之间维持目标的唯一 ID。

classSimpleTracker:def__init__(self, max_lost=30):        self.next_id = 1        self.tracks = {}   # id -> {"box", "cls", "lost", "trail"}        self.max_lost = max_lostdefupdate(self, detections):# 1. 对每个已有轨迹,在新检测中找IoU最大的匹配for tid, track in self.tracks.items():            best_iou, best_idx = 0-1for i, det_box in enumerate(det_boxes):                iou = self._iou(track["box"], det_box)if iou > best_iou:                    best_iou, best_idx = iou, iif best_iou > 0.3:# 匹配成功:更新位置,重置丢失计数,记录轨迹点                track["box"] = det_boxes[best_idx]                track["lost"] = 0                track["trail"].append(center_point)# 2. 未匹配的检测 -> 创建新轨迹,分配新ID# 3. 超过max_lost帧未匹配的轨迹 -> 删除    @staticmethoddef_iou(b1, b2):# 计算两个框的交并比        inter = 交集面积return inter / (面积1 + 面积2 - inter)

应用场景:

  • 商场/园区人流量统计:每个人分配唯一 ID,进出计数不重复
  • 交通路口车辆追踪:车辆穿越路口全程保持同一 ID,统计车流量
  • 安防监控:嫌疑人在画面中的完整移动轨迹回溯
  • 养老院/医院:老人活动轨迹监测,异常停留检测

IoU 阈值 0.3 是经验值,适合中等速度移动的目标。快速移动场景可降低到 0.2,静态场景可提高到 0.5。max_lost=30 表示目标消失 30 帧后才删除轨迹,支持短暂遮挡后重新匹配。


关键代码二:视频处理线程与实时标注渲染

视频处理在独立 QThread 中运行,避免阻塞 GUI,通过信号将原始帧和标注帧同时传递给主窗口。

classVideoWorker(QThread):    frame_ready = pyqtSignal(object, object, dict)  # raw, annotated, statsdefrun(self):        cap = cv2.VideoCapture(self.source)while self.running and cap.isOpened():if self.paused: continue            ret, frame = cap.read()            raw = frame.copy()                    # 保留原始帧            annotated, stats = self._process_frame(frame)  # AI分析+标注            self.frame_ready.emit(raw, annotated, stats)   # 双画面信号def_draw_annotations(self, frame, tracks, stats):for tid, t in tracks.items():            x1, y1, x2, y2 = t["box"]            color = COLORS[t["cls"]]# 目标框            cv2.rectangle(frame, (x1,y1), (x2,y2), color, 2)# 标签(ID + 类型 + 置信度)            label = f"ID:{tid}{name}{conf:.0%}"            cv2.putText(frame, label, (x1, y1-4), ...)# 轨迹线(渐变粗细,越新越粗)for i in range(1, len(trail)):                alpha = i / len(trail)                thick = max(1, int(alpha * 3))                cv2.line(frame, trail[i-1], trail[i], color, thick)# 禁区入侵检测            cx, cy = 目标中心点for zone in self.alert_zones:if 中心点在禁区内:                    stats["alerts"].append("入侵告警")# 右上角统计信息叠加(半透明黑底)        cv2.rectangle(overlay, ..., (0,0,0), -1)        frame = cv2.addWeighted(overlay, 0.6, frame, 0.40)

应用场景:

  • 工厂安全监控:左侧原始画面供人工复核,右侧 AI 标注画面自动识别违规行为
  • 交通监控中心:多路视频同时分析,每路都有原始+标注双画面
  • 智慧社区:实时显示小区内人员/车辆分布,异常入侵即时告警
  • 体育赛事分析:运动员轨迹追踪,战术路线可视化

双画面设计的核心价值:原始画面保留完整证据链,标注画面提供 AI 辅助分析,两者对照可快速验证检测准确性。信号机制确保 GUI 不卡顿,即使 AI 推理耗时较长也不影响界面响应。


关键代码三:可交互的视频显示控件(禁区绘制)

自定义 QLabel 控件,支持鼠标右键拖拽绘制矩形禁区,实现"画面上直接标注"的交互体验。

classVideoLabel(QLabel):    zone_drawn = pyqtSignal(int, int, int, int)  # 绘制完成信号defmousePressEvent(self, e):if e.button() == Qt.RightButton:            self._drawing = True            self._start = e.pos()       # 记录起点defmouseMoveEvent(self, e):if self._drawing:            self._end = e.pos()         # 实时更新终点            self.update()               # 触发重绘,显示虚线框defmouseReleaseEvent(self, e):if e.button() == Qt.RightButton and self._drawing:            self._drawing = False# 计算矩形区域,发射信号            x1 = min(start.x, end.x)            y1 = min(start.y, end.y)            x2 = max(start.x, end.x)            y2 = max(start.y, end.y)if 面积足够大:                self.zone_drawn.emit(x1, y1, x2, y2)defpaintEvent(self, e):        super().paintEvent(e)           # 先绘制视频帧if self._drawing:# 叠加绘制红色虚线矩形 + 半透明红色填充            painter.setPen(QPen(红色, 2, Qt.DashLine))            painter.setBrush(QBrush(半透明红色))            painter.drawRect(QRect(start, end))

应用场景:

  • 安防部署:运维人员直接在监控画面上框选禁止进入区域,无需配置文件
  • 停车场管理:框选禁停区域,车辆进入自动告警
  • 工地安全:框选危险作业区,未佩戴安全帽人员进入即报警
  • 学校/幼儿园:框选校门口区域,统计进出人数
  • 零售门店:框选收银区/货架区,分析顾客停留热点

这种"所见即所得"的交互方式大幅降低了使用门槛,非技术人员也能快速配置监控规则。信号-槽机制将绘制结果传递给 VideoWorker 的 alert_zones 列表,后续每帧检测时自动判断目标是否进入禁区。

代码架构

yolo_monitor.py+-- SimpleTracker          # IoU多目标追踪器|   +-- update()           # 每帧更新追踪|   +-- _iou()             # 交并比计算+-- VideoWorker(QThread)   # 视频处理线程|   +-- run()              # 主循环:读帧-检测-标注-发信号|   +-- _process_frame()   # YOLOv8推理|   +-- _simulate_detect() # 无模型时的模拟检测|   +-- _draw_annotations()# 标注渲染(框+标签+轨迹+禁区+统计)+-- VideoLabel(QLabel)     # 可交互视频显示控件|   +-- set_frame()        # 显示OpenCV帧|   +-- mouse*Event()      # 右键拖拽绘制禁区|   +-- paintEvent()       # 叠加绘制虚线框+-- MonitorApp(QMainWindow)# 主窗口    +-- 顶部:视频源输入 + 参数控制    +-- 中间左:双画面(原始+标注)    +-- 中间右:5个Tab(统计/告警/检索/设置/关于)    +-- 底部:事件日志

数据流

视频源 (文件/RTSP/摄像头)    |    vVideoWorker.run() [子线程]    |    +-- cv2.VideoCapture 读帧    +-- YOLOv8n 推理 -> 检测框列表    +-- SimpleTracker.update() -> 带ID的追踪结果    +-- _draw_annotations() -> 标注帧 + 统计数据    |    vframe_ready 信号 [跨线程]    |    +-- video_left.set_frame(原始帧)    +-- video_right.set_frame(标注帧)    +-- 更新统计数字    +-- 处理告警事件 -> 日志

检测类别

COCO ID
类别
颜色
0
橙色
2
轿车
蓝色
3
摩托车
青色
5
巴士
紫色
7
卡车
绿色

右侧功能 Tab

Tab
功能
统计
实时人数/车辆数、追踪ID数、历史趋势、导出报表
告警
禁区列表管理、告警日志、清除禁区
检索
按ID检索目标详情(类型/位置/轨迹/状态)
设置
检测开关(人物/车辆)、入侵检测、聚集检测阈值、智能录像
关于
作者信息、功能说明

应用场景总结

场景
核心功能
价值
园区/社区安防
人物追踪 + 禁区入侵 + 告警
替代人工巡逻,全天候无死角
交通路口监控
车辆检测 + 车流统计 + 违停检测
实时路况分析,辅助交通调度
商场/零售
人流统计 + 热区分析 + 轨迹追踪
客流分析,优化商品陈列和动线
工厂/工地
人员检测 + 危险区域告警
安全生产监管,减少事故
停车场
车辆追踪 + 车位统计
智能停车引导,提升周转率
养老院/医院
人物追踪 + 异常行为检测
老人跌倒检测,及时救助
学校
进出人数统计 + 陌生人告警
校园安全管理

依赖

PyQt5opencv-pythonultralytics    # YOLOv8(可选,无则使用模拟模式)numpy

首次运行 ultralytics 会自动下载 yolov8n.pt 模型文件(约 6MB)。

-- coding: utf-8 --"""YOLOv8n 智能监控分析系统 v1.0功能:视频分析/人物检索/车辆分析/监控录像 - 左右双画面展示作者:杨少平 | 公众号:Python学在坚持运行:python yolo_monitor.py依赖:pip install PyQt5 opencv-python ultralytics numpy"""import sys, os, json, time, cv2, numpy as npfrom datetime import datetimefrom collections import defaultdict, dequefrom PyQt5.QtWidgets import (QApplication, QMainWindow, QWidget, QVBoxLayout, QHBoxLayout, QGridLayout,QLabel, QLineEdit, QPushButton, QComboBox, QSlider, QCheckBox, QSpinBox,QTabWidget, QGroupBox, QScrollArea, QSplitter, QFileDialog, QMessageBox,QListWidget, QListWidgetItem, QFrame, QStatusBar, QTextEdit, QProgressBar,QTableWidget, QTableWidgetItem, QHeaderView, QDialog, QFormLayout, QMenu)from PyQt5.QtCore import Qt, QTimer, pyqtSignal, QThread, QPoint, QRectfrom PyQt5.QtGui import QFont, QColor, QImage, QPixmap, QPainter, QPen, QBrushAPP_VERSION = "v1.0"PERSON_CLASSES = [0]  # COCO: personVEHICLE_CLASSES = [2357]  # car, motorcycle, bus, truck==================== 简易追踪器 ====================class SimpleTracker:"""基于IoU的多目标追踪器"""def init(self, max_lost=30):self.next_id = 1self.tracks = {}  # id -> {"box":, "cls":, "lost":, "trail": deque}self.max_lost = max_lostdef update(self, detections):    """detections: list of (x1,y1,x2,y2,conf,cls)"""    if not detections:        for tid in list(self.tracks):            self.tracks[tid]["lost"] += 1            if self.tracks[tid]["lost"] > self.max_lost:                del self.tracks[tid]        return {}    det_boxes = [d[:4for d in detections]    det_cls = [int(d[5]) for d in detections]    det_conf = [d[4for d in detections]    matched = {}    used_det = set()    # 匹配已有轨迹    for tid, track in list(self.tracks.items()):        best_iou, best_idx = 0, -1        for i, db in enumerate(det_boxes):            if i in used_det: continue            iou = self._iou(track["box"], db)            if iou > best_iou:                best_iou, best_idx = iou, i        if best_iou > 0.3 and best_idx >= 0:            self.tracks[tid]["box"] = det_boxes[best_idx]            self.tracks[tid]["cls"] = det_cls[best_idx]            self.tracks[tid]["conf"] = det_conf[best_idx]            self.tracks[tid]["lost"] = 0            cx = int((det_boxes[best_idx][0] + det_boxes[best_idx][2]) / 2)            cy = int((det_boxes[best_idx][1] + det_boxes[best_idx][3]) / 2)            self.tracks[tid]["trail"].append((cx, cy))            matched[tid] = self.tracks[tid]            used_det.add(best_idx)        else:            self.tracks[tid]["lost"] += 1            if self.tracks[tid]["lost"] > self.max_lost:                del self.tracks[tid]    # 新目标    for i in range(len(det_boxes)):        if i not in used_det:            cx = int((det_boxes[i][0] + det_boxes[i][2]) / 2)            cy = int((det_boxes[i][1] + det_boxes[i][3]) / 2)            self.tracks[self.next_id] = {                "box": det_boxes[i], "cls": det_cls[i], "conf": det_conf[i],                "lost"0"trail": deque([(cx, cy)], maxlen=100)            }            matched[self.next_id] = self.tracks[self.next_id]            self.next_id += 1    return matched@staticmethoddef _iou(b1, b2):    x1 = max(b1[0], b2[0]); y1 = max(b1[1], b2[1])    x2 = min(b1[2], b2[2]); y2 = min(b1[3], b2[3])    inter = max(0, x2-x1) * max(0, y2-y1)    a1 = (b1[2]-b1[0])*(b1[3]-b1[1])    a2 = (b2[2]-b2[0])*(b2[3]-b2[1])    return inter / (a1+a2-inter+1e-6)==================== 视频处理线程 ====================class VideoWorker(QThread):frame_ready = pyqtSignal(objectobjectdict)  # raw_frame, annotated_frame, statsfinished = pyqtSignal()def __init__(self):    super().__init__()    self.source = None    self.running = False    self.paused = False    self.speed = 1.0    self.model = None    self.tracker = SimpleTracker()    self.conf_thresh = 0.4    self.show_trails = True    self.show_labels = True    self.alert_zones = []  # list of (x1,y1,x2,y2) 禁区    self.alert_lines = []  # list of (x1,y1,x2,y2) 警戒线    self.events = []  # 事件日志    self.person_count_history = deque(maxlen=300)    self.vehicle_count_history = deque(maxlen=300)def set_source(self, source):    self.source = source    self.tracker = SimpleTracker()def load_model(self):    try:        from ultralytics import YOLO        self.model = YOLO("yolov8n.pt")        return True    except Exception as e:        print(f"模型加载失败: {e}")        return Falsedef run(self):    if not self.source: return    cap = cv2.VideoCapture(self.source)    if not cap.isOpened():        self.finished.emit(); return    self.running = True    while self.running and cap.isOpened():        if self.paused:            time.sleep(0.05); continue        ret, frame = cap.read()        if not ret:            break        raw = frame.copy()        annotated, stats = self._process_frame(frame)        self.frame_ready.emit(raw, annotated, stats)        # 控制速度        delay = max(1int(30 / self.speed))        time.sleep(delay / 1000.0)    cap.release()    self.running = False    self.finished.emit()def _process_frame(self, frame):    stats = {"persons"0"vehicles"0"alerts": []}    if self.model is None:        # 无模型时用模拟检测        return self._simulate_detect(frame, stats)    results = self.model(frame, conf=self.conf_thresh, verbose=False)    detections = []    if results and len(results) > 0:        boxes = results[0].boxes        if boxes is not None:            for box in boxes:                x1, y1, x2, y2 = box.xyxy[0].cpu().numpy()                conf = float(box.conf[0])                cls = int(box.cls[0])                detections.append((x1, y1, x2, y2, conf, cls))    tracks = self.tracker.update(detections)    return self._draw_annotations(frame, tracks, stats)def _simulate_detect(self, frame, stats):    """无模型时的模拟检测(演示用)"""    h, w = frame.shape[:2]    import random    fake_dets = []    for _ in range(random.randint(14)):        cx, cy = random.randint(w//43*w//4), random.randint(h//43*h//4)        bw, bh = random.randint(3080), random.randint(60150)        cls = random.choice([00027])  # 偏向人        fake_dets.append((cx-bw, cy-bh, cx+bw, cy+bh, 0.85, cls))    tracks = self.tracker.update(fake_dets)    return self._draw_annotations(frame, tracks, stats)def _draw_annotations(self, frame, tracks, stats):    person_count = 0    vehicle_count = 0    NAMES = {0"人"2"轿车"3"摩托"5"巴士"7"卡车"}    COLORS = {0: (0,120,255), 2: (255,100,0), 3: (0,200,200), 5: (200,0,200), 7: (0,200,0)}    # 绘制禁区    for z in self.alert_zones:        cv2.rectangle(frame, (z[0],z[1]), (z[2],z[3]), (0,0,255), 2)        cv2.putText(frame, "ALERT ZONE", (z[0],z[1]-5), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0,0,255), 1)    # 绘制警戒线    for l in self.alert_lines:        cv2.line(frame, (l[0],l[1]), (l[2],l[3]), (0,255,255), 2)    for tid, t in tracks.items():        x1, y1, x2, y2 = [int(v) for v in t["box"]]        cls = t["cls"]        conf = t.get("conf"0)        color = COLORS.get(cls, (200200200))        name = NAMES.get(cls, f"cls{cls}")        if cls in PERSON_CLASSES: person_count += 1        if cls in VEHICLE_CLASSES: vehicle_count += 1        # 目标框        cv2.rectangle(frame, (x1, y1), (x2, y2), color, 2)        # 标签        if self.show_labels:            label = f"ID:{tid}{name}{conf:.0%}"            (tw, th), _ = cv2.getTextSize(label, cv2.FONT_HERSHEY_SIMPLEX, 0.51)            cv2.rectangle(frame, (x1, y1-th-6), (x1+tw+4, y1), color, -1)            cv2.putText(frame, label, (x1+2, y1-4), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255,255,255), 1)        # 轨迹        if self.show_trails and len(t["trail"]) > 1:            pts = list(t["trail"])            for i in range(1len(pts)):                alpha = i / len(pts)                thick = max(1int(alpha * 3))                cv2.line(frame, pts[i-1], pts[i], color, thick)        # 禁区入侵检测        cx, cy = (x1+x2)//2, (y1+y2)//2        for z in self.alert_zones:            if z[0] <= cx <= z[2and z[1] <= cy <= z[3]:                cv2.putText(frame, "!! INTRUSION !!", (x1, y1-20), cv2.FONT_HERSHEY_SIMPLEX, 0.6, (0,0,255), 2)                stats["alerts"].append(f"入侵告警: ID{tid}{name}")    # 统计信息叠加    stats["persons"] = person_count    stats["vehicles"] = vehicle_count    self.person_count_history.append(person_count)    self.vehicle_count_history.append(vehicle_count)    h, w = frame.shape[:2]    overlay = frame.copy()    cv2.rectangle(overlay, (w-2200), (w, 80), (0,0,0), -1)    frame = cv2.addWeighted(overlay, 0.6, frame, 0.40)    cv2.putText(frame, f"Person: {person_count}", (w-21025), cv2.FONT_HERSHEY_SIMPLEX, 0.6, (0,200,255), 2)    cv2.putText(frame, f"Vehicle: {vehicle_count}", (w-21050), cv2.FONT_HERSHEY_SIMPLEX, 0.6, (0,255,100), 2)    cv2.putText(frame, datetime.now().strftime("%H:%M:%S"), (w-21073), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (200,200,200), 1)    return frame, statsdef stop(self):    self.running = False==================== 视频显示控件 ====================class VideoLabel(QLabel):"""可显示视频帧的QLabel,支持鼠标绘制区域"""zone_drawn = pyqtSignal(intintintint)def __init__(self, title=""):    super().__init__()    self.setAlignment(Qt.AlignCenter)    self.setMinimumSize(320240)    self.setStyleSheet("background:#1a1a2e;border:1px solid #333;border-radius:4px;")    self.setText(title or "等待视频...")    self.setFont(QFont("Microsoft YaHei"12))    self._drawing = False    self._start = QPoint()    self._end = QPoint()def set_frame(self, frame):    if frame is Nonereturn    h, w, ch = frame.shape    bytes_per_line = ch * w    img = QImage(frame.data, w, h, bytes_per_line, QImage.Format_BGR888)    scaled = QPixmap.fromImage(img).scaled(self.size(), Qt.KeepAspectRatio, Qt.SmoothTransformation)    self.setPixmap(scaled)def mousePressEvent(self, e):    if e.button() == Qt.RightButton:        self._drawing = True        self._start = e.pos()def mouseMoveEvent(self, e):    if self._drawing:        self._end = e.pos()        self.update()def mouseReleaseEvent(self, e):    if e.button() == Qt.RightButton and self._drawing:        self._drawing = False        self._end = e.pos()        x1, y1 = min(self._start.x(), self._end.x()), min(self._start.y(), self._end.y())        x2, y2 = max(self._start.x(), self._end.x()), max(self._start.y(), self._end.y())        if abs(x2-x1) > 10 and abs(y2-y1) > 10:            self.zone_drawn.emit(x1, y1, x2, y2)def paintEvent(self, e):    super().paintEvent(e)    if self._drawing:        p = QPainter(self)        p.setPen(QPen(QColor(25500180), 2, Qt.DashLine))        p.setBrush(QBrush(QColor(2550040)))        p.drawRect(QRect(self._start, self._end))        p.end()==================== 主窗口 ====================class MonitorApp(QMainWindow):def init(self):super().init()self.setWindowTitle(f"🎯 YOLOv8n 智能监控分析系统 {APP_VERSION}")self.setMinimumSize(1200750)self.resize(1400850)self.worker = VideoWorker()self.worker.frame_ready.connect(self._on_frame)self.worker.finished.connect(self._on_finished)self.event_log = []self._build()def _build(self):    central = QWidget()    self.setCentralWidget(central)    main_lay = QVBoxLayout(central)    main_lay.setContentsMargins(6666)    main_lay.setSpacing(6)    # ---- 顶部控制栏 ----    top = QHBoxLayout()    self.ed_source = QLineEdit()    self.ed_source.setPlaceholderText("视频源: 文件路径 / RTSP地址 / 摄像头编号(0)")    self.ed_source.setMinimumWidth(300)    top.addWidget(self.ed_source)    btn_file = QPushButton("📂 选择文件")    btn_file.clicked.connect(self._select_file)    top.addWidget(btn_file)    btn_cam = QPushButton("📷 摄像头")    btn_cam.clicked.connect(lambdaself.ed_source.setText("0"))    top.addWidget(btn_cam)    top.addWidget(QLabel("置信度:"))    self.sl_conf = QSlider(Qt.Horizontal)    self.sl_conf.setRange(1095)    self.sl_conf.setValue(40)    self.sl_conf.setMaximumWidth(100)    self.lbl_conf = QLabel("0.40")    self.sl_conf.valueChanged.connect(lambda v: (self.lbl_conf.setText(f"{v/100:.2f}"), setattr(self.worker, 'conf_thresh', v/100)))    top.addWidget(self.sl_conf)    top.addWidget(self.lbl_conf)    top.addWidget(QLabel("速度:"))    self.cb_speed = QComboBox()    self.cb_speed.addItems(["0.5x""1x""2x""4x""8x"])    self.cb_speed.setCurrentIndex(1)    self.cb_speed.currentTextChanged.connect(lambda t: setattr(self.worker, 'speed'float(t.replace('x',''))))    top.addWidget(self.cb_speed)    main_lay.addLayout(top)    # ---- 播放控制 ----    ctrl = QHBoxLayout()    self.btn_start = QPushButton("▶ 开始分析")    self.btn_start.setStyleSheet("padding:8px 20px;background:#388e3c;color:#fff;border:none;border-radius:4px;font-size:13px;font-weight:bold;")    self.btn_start.clicked.connect(self._start)    self.btn_pause = QPushButton("⏸ 暂停")    self.btn_pause.setStyleSheet("padding:8px 16px;background:#ff9800;color:#fff;border:none;border-radius:4px;")    self.btn_pause.clicked.connect(self._pause)    self.btn_stop = QPushButton("⏹ 停止")    self.btn_stop.setStyleSheet("padding:8px 16px;background:#d32f2f;color:#fff;border:none;border-radius:4px;")    self.btn_stop.clicked.connect(self._stop)    self.chk_trails = QCheckBox("轨迹")    self.chk_trails.setChecked(True)    self.chk_trails.stateChanged.connect(lambda s: setattr(self.worker, 'show_trails', s == Qt.Checked))    self.chk_labels = QCheckBox("标签")    self.chk_labels.setChecked(True)    self.chk_labels.stateChanged.connect(lambda s: setattr(self.worker, 'show_labels', s == Qt.Checked))    ctrl.addWidget(self.btn_start)    ctrl.addWidget(self.btn_pause)    ctrl.addWidget(self.btn_stop)    ctrl.addWidget(self.chk_trails)    ctrl.addWidget(self.chk_labels)    ctrl.addStretch()    self.lbl_status = QLabel("⏹ 就绪")    self.lbl_status.setStyleSheet("font-size:13px;font-weight:bold;color:#888;")    ctrl.addWidget(self.lbl_status)    main_lay.addLayout(ctrl)    # ---- 中间:左右双画面 + 右侧Tab ----    mid_splitter = QSplitter(Qt.Horizontal)    # 左右视频画面    video_widget = QWidget()    video_lay = QHBoxLayout(video_widget)    video_lay.setContentsMargins(0000)    video_lay.setSpacing(4)    self.video_left = VideoLabel("📹 原始画面")    self.video_left.setStyleSheet("background:#1a1a2e;color:#555;border:1px solid #333;border-radius:4px;")    self.video_right = VideoLabel("🎯 分析画面")    self.video_right.setStyleSheet("background:#1a1a2e;color:#555;border:1px solid #333;border-radius:4px;")    self.video_right.zone_drawn.connect(self._add_zone)    video_lay.addWidget(self.video_left)    video_lay.addWidget(self.video_right)    mid_splitter.addWidget(video_widget)    # 右侧功能Tab    right_tabs = QTabWidget()    right_tabs.setMaximumWidth(360)    right_tabs.setMinimumWidth(280)    right_tabs.addTab(self._build_stats_tab(), "📊 统计")    right_tabs.addTab(self._build_alert_tab(), "🚨 告警")    right_tabs.addTab(self._build_search_tab(), "🔍 检索")    right_tabs.addTab(self._build_settings_tab(), "⚙ 设置")    right_tabs.addTab(self._build_about_tab(), "ℹ️ 关于")    mid_splitter.addWidget(right_tabs)    mid_splitter.setStretchFactor(01)    mid_splitter.setStretchFactor(10)    main_lay.addWidget(mid_splitter, 1)    # ---- 底部事件日志 ----    self.log_list = QListWidget()    self.log_list.setMaximumHeight(120)    self.log_list.setStyleSheet("font-size:11px;background:#f8f8f8;")    main_lay.addWidget(self.log_list)    self.statusBar().showMessage(f"YOLOv8n 智能监控分析系统 {APP_VERSION} | 就绪")# ---- 右侧Tab构建 ----def _build_stats_tab(self):    w = QWidget(); lay = QVBoxLayout(w); lay.setContentsMargins(8,8,8,8)    lay.addWidget(QLabel("📊 实时统计"))    self.lbl_person = QLabel("👤 人数: 0"); self.lbl_person.setStyleSheet("font-size:18px;font-weight:bold;color:#0078d4;"); lay.addWidget(self.lbl_person)    self.lbl_vehicle = QLabel("🚗 车辆: 0"); self.lbl_vehicle.setStyleSheet("font-size:18px;font-weight:bold;color:#e65100;"); lay.addWidget(self.lbl_vehicle)    self.lbl_tracks = QLabel("🔢 追踪ID: 0"); self.lbl_tracks.setStyleSheet("font-size:14px;color:#555;"); lay.addWidget(self.lbl_tracks)    lay.addWidget(QFrame(frameShape=QFrame.HLine))    lay.addWidget(QLabel("📈 历史趋势"))    self.stats_text = QTextEdit(); self.stats_text.setReadOnly(True); self.stats_text.setMaximumHeight(150)    self.stats_text.setFont(QFont("Consolas"9)); lay.addWidget(self.stats_text)    lay.addWidget(QFrame(frameShape=QFrame.HLine))    btn_export = QPushButton("📥 导出统计报表")    btn_export.setStyleSheet("padding:6px;background:#1976d2;color:#fff;border:none;border-radius:3px;")    btn_export.clicked.connect(self._export_stats)    lay.addWidget(btn_export)    lay.addStretch()    return wdef _build_alert_tab(self):    w = QWidget(); lay = QVBoxLayout(w); lay.setContentsMargins(8,8,8,8)    lay.addWidget(QLabel("🚨 告警设置"))    lay.addWidget(QLabel("右键在分析画面上拖拽绘制禁区"))    self.alert_list = QListWidget(); lay.addWidget(self.alert_list)    btn_row = QHBoxLayout()    btn_clear = QPushButton("清除所有禁区")    btn_clear.clicked.connect(self._clear_zones)    btn_row.addWidget(btn_clear)    lay.addLayout(btn_row)    lay.addWidget(QFrame(frameShape=QFrame.HLine))    lay.addWidget(QLabel("告警日志:"))    self.alert_log = QListWidget(); self.alert_log.setStyleSheet("font-size:11px;"); lay.addWidget(self.alert_log, 1)    return wdef _build_search_tab(self):    w = QWidget(); lay = QVBoxLayout(w); lay.setContentsMargins(8,8,8,8)    lay.addWidget(QLabel("🔍 目标检索"))    g = QFormLayout()    self.search_type = QComboBox(); self.search_type.addItems(["人物""车辆""全部"])    g.addRow("目标类型:"self.search_type)    self.search_id = QLineEdit(); self.search_id.setPlaceholderText("输入追踪ID")    g.addRow("追踪ID:"self.search_id)    lay.addLayout(g)    btn = QPushButton("🔍 检索")    btn.setStyleSheet("padding:6px;background:#d32f2f;color:#fff;border:none;border-radius:3px;")    btn.clicked.connect(self._do_search)    lay.addWidget(btn)    self.search_result = QTextEdit(); self.search_result.setReadOnly(True)    self.search_result.setFont(QFont("Consolas"9)); lay.addWidget(self.search_result, 1)    return wdef _build_settings_tab(self):    w = QWidget(); lay = QVBoxLayout(w); lay.setContentsMargins(8,8,8,8)    lay.addWidget(QLabel("⚙ 检测设置"))    g = QFormLayout()    self.chk_person = QCheckBox("检测人物"); self.chk_person.setChecked(True); g.addRow(self.chk_person)    self.chk_vehicle = QCheckBox("检测车辆"); self.chk_vehicle.setChecked(True); g.addRow(self.chk_vehicle)    self.chk_intrusion = QCheckBox("入侵检测"); self.chk_intrusion.setChecked(True); g.addRow(self.chk_intrusion)    self.chk_crowd = QCheckBox("人群聚集检测"); self.chk_crowd.setChecked(True); g.addRow(self.chk_crowd)    self.sp_crowd = QSpinBox(); self.sp_crowd.setRange(250); self.sp_crowd.setValue(5)    g.addRow("聚集阈值:"self.sp_crowd)    self.chk_record = QCheckBox("智能录像(检测到目标时录制)"); g.addRow(self.chk_record)    lay.addLayout(g)    lay.addStretch()    return wdef _build_about_tab(self):    w = QWidget(); lay = QVBoxLayout(w); lay.setContentsMargins(12,20,12,12); lay.setAlignment(Qt.AlignTop)    t = QLabel(f"🎯 YOLOv8n 智能监控\n{APP_VERSION}"); t.setStyleSheet("font-size:16px;font-weight:bold;color:#d32f2f;"); lay.addWidget(t)    lay.addSpacing(10)    for k, v in [("作者""杨少平"), ("公众号""Python学在坚持"), ("微信""ysp2338084")]:        r = QHBoxLayout()        r.addWidget(QLabel(k+":")); l = QLabel(v); l.setStyleSheet("font-weight:bold;"); l.setTextInteractionFlags(Qt.TextSelectableByMouse); r.addWidget(l); r.addStretch()        lay.addLayout(r)    lay.addSpacing(10)    desc = QLabel("功能: YOLOv8n实时检测 | 人物/车辆追踪\n区域入侵告警 | 轨迹可视化 | 统计报表\n支持: 本地视频/RTSP流/USB摄像头")    desc.setStyleSheet("color:#666;font-size:11px;"); desc.setWordWrap(True); lay.addWidget(desc)    lay.addStretch()    return w# ---- 核心操作 ----def _select_file(self):    path, _ = QFileDialog.getOpenFileName(self"选择视频""""视频文件 (*.mp4 *.avi *.mov *.flv *.mkv);;所有文件 (*)")    if path: self.ed_source.setText(path)def _start(self):    src = self.ed_source.text().strip()    if not src:        QMessageBox.warning(self"提示""请输入视频源"); return    # 尝试转为摄像头编号    try: src = int(src)    except ValueError: pass    self.worker.set_source(src)    if self.worker.model is None:        self._log("正在加载YOLOv8n模型...")        if not self.worker.load_model():            self._log("⚠ 模型加载失败,使用模拟检测模式")    self.worker.start()    self.lbl_status.setText("▶ 分析中...")    self.lbl_status.setStyleSheet("font-size:13px;font-weight:bold;color:#388e3c;")    self._log(f"开始分析: {src}")def _pause(self):    self.worker.paused = not self.worker.paused    if self.worker.paused:        self.btn_pause.setText("▶ 继续")        self.lbl_status.setText("⏸ 已暂停"); self.lbl_status.setStyleSheet("font-size:13px;font-weight:bold;color:#ff9800;")    else:        self.btn_pause.setText("⏸ 暂停")        self.lbl_status.setText("▶ 分析中..."); self.lbl_status.setStyleSheet("font-size:13px;font-weight:bold;color:#388e3c;")def _stop(self):    self.worker.stop()    self.lbl_status.setText("⏹ 已停止"); self.lbl_status.setStyleSheet("font-size:13px;font-weight:bold;color:#d32f2f;")    self._log("分析已停止")def _on_frame(self, raw, annotated, stats):    self.video_left.set_frame(raw)    self.video_right.set_frame(annotated)    self.lbl_person.setText(f"👤 人数: {stats['persons']}")    self.lbl_vehicle.setText(f"🚗 车辆: {stats['vehicles']}")    self.lbl_tracks.setText(f"🔢 追踪ID: {len(self.worker.tracker.tracks)}")    for alert in stats.get("alerts", []):        ts = datetime.now().strftime("%H:%M:%S")        self.alert_log.insertItem(0f"[{ts}{alert}")        self._log(f"🚨 {alert}")def _on_finished(self):    self.lbl_status.setText("⏹ 完成"); self.lbl_status.setStyleSheet("font-size:13px;font-weight:bold;color:#888;")    self._log("视频分析完成")def _add_zone(self, x1, y1, x2, y2):    self.worker.alert_zones.append((x1, y1, x2, y2))    self.alert_list.addItem(f"禁区 #{len(self.worker.alert_zones)}: ({x1},{y1})-({x2},{y2})")    self._log(f"添加禁区: ({x1},{y1})-({x2},{y2})")def _clear_zones(self):    self.worker.alert_zones.clear()    self.alert_list.clear()    self._log("已清除所有禁区")def _do_search(self):    tid = self.search_id.text().strip()    if not tid:        self.search_result.setPlainText("请输入追踪ID"); return    try:        tid = int(tid)    except ValueError:        self.search_result.setPlainText("ID必须是数字"); return    track = self.worker.tracker.tracks.get(tid)    if track:        NAMES = {0:"人",2:"轿车",3:"摩托",5:"巴士",7:"卡车"}        lost = track["lost"]        status = "活跃" if lost == 0 else f"丢失{lost}帧"        self.search_result.setPlainText(            f"ID: {tid}\n类型: {NAMES.get(track['cls'], '未知')}\n"            f"位置: {[int(v) for v in track['box']]}\n"            f"轨迹点数: {len(track['trail'])}\n"            f"状态: {status}"        )    else:        self.search_result.setPlainText(f"未找到ID={tid}的目标")def _export_stats(self):    path, _ = QFileDialog.getSaveFileName(self"导出统计""stats.txt""文本文件 (*.txt)")    if path:        with open(path, "w", encoding="utf-8"as f:            f.write(f"YOLOv8n 监控统计报表\n生成时间: {datetime.now()}\n\n")            f.write(f"当前追踪目标数: {len(self.worker.tracker.tracks)}\n")            f.write(f"人数历史: {list(self.worker.person_count_history)[-20:]}\n")            f.write(f"车辆历史: {list(self.worker.vehicle_count_history)[-20:]}\n\n")            f.write("事件日志:\n")            for e in self.event_log[-100:]:                f.write(f"  {e}\n")        QMessageBox.information(self"成功"f"已导出到 {path}")def _log(self, msg):    ts = datetime.now().strftime("%H:%M:%S")    entry = f"[{ts}{msg}"    self.event_log.append(entry)    self.log_list.insertItem(0, entry)    if self.log_list.count() > 500:        self.log_list.takeItem(self.log_list.count() - 1)def closeEvent(self, e):    self.worker.stop()    self.worker.wait(2000)    e.accept()==================== 启动 ====================if name == "main":app = QApplication(sys.argv)app.setStyle("Fusion")app.setFont(QFont("Microsoft YaHei"10))win = MonitorApp()win.show()sys.exit(app.exec_())

最新文章

随机文章

基本 文件 流程 错误 SQL 调试
  1. 请求信息 : 2026-07-04 08:10:42 HTTP/2.0 GET : https://f.mffb.com.cn/a/489042.html
  2. 运行时间 : 0.114618s [ 吞吐率:8.72req/s ] 内存消耗:5,205.45kb 文件加载:140
  3. 缓存信息 : 0 reads,0 writes
  4. 会话信息 : SESSION_ID=36f9e2ee503960c93f6b5e3675f71988
  1. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/public/index.php ( 0.79 KB )
  2. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/autoload.php ( 0.17 KB )
  3. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/composer/autoload_real.php ( 2.49 KB )
  4. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/composer/platform_check.php ( 0.90 KB )
  5. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/composer/ClassLoader.php ( 14.03 KB )
  6. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/composer/autoload_static.php ( 4.90 KB )
  7. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/helper.php ( 8.34 KB )
  8. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-validate/src/helper.php ( 2.19 KB )
  9. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/helper.php ( 1.47 KB )
  10. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/stubs/load_stubs.php ( 0.16 KB )
  11. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Exception.php ( 1.69 KB )
  12. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-container/src/Facade.php ( 2.71 KB )
  13. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/deprecation-contracts/function.php ( 0.99 KB )
  14. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/polyfill-mbstring/bootstrap.php ( 8.26 KB )
  15. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/polyfill-mbstring/bootstrap80.php ( 9.78 KB )
  16. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/var-dumper/Resources/functions/dump.php ( 1.49 KB )
  17. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-dumper/src/helper.php ( 0.18 KB )
  18. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/var-dumper/VarDumper.php ( 4.30 KB )
  19. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/App.php ( 15.30 KB )
  20. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-container/src/Container.php ( 15.76 KB )
  21. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/psr/container/src/ContainerInterface.php ( 1.02 KB )
  22. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/provider.php ( 0.19 KB )
  23. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Http.php ( 6.04 KB )
  24. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/helper/Str.php ( 7.29 KB )
  25. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Env.php ( 4.68 KB )
  26. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/common.php ( 0.03 KB )
  27. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/helper.php ( 18.78 KB )
  28. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Config.php ( 5.54 KB )
  29. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/app.php ( 0.95 KB )
  30. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/cache.php ( 0.78 KB )
  31. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/console.php ( 0.23 KB )
  32. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/cookie.php ( 0.56 KB )
  33. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/database.php ( 2.48 KB )
  34. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/facade/Env.php ( 1.67 KB )
  35. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/filesystem.php ( 0.61 KB )
  36. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/lang.php ( 0.91 KB )
  37. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/log.php ( 1.35 KB )
  38. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/middleware.php ( 0.19 KB )
  39. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/route.php ( 1.89 KB )
  40. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/session.php ( 0.57 KB )
  41. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/trace.php ( 0.34 KB )
  42. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/view.php ( 0.82 KB )
  43. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/event.php ( 0.25 KB )
  44. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Event.php ( 7.67 KB )
  45. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/service.php ( 0.13 KB )
  46. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/AppService.php ( 0.26 KB )
  47. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Service.php ( 1.64 KB )
  48. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Lang.php ( 7.35 KB )
  49. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/lang/zh-cn.php ( 13.70 KB )
  50. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/initializer/Error.php ( 3.31 KB )
  51. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/initializer/RegisterService.php ( 1.33 KB )
  52. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/services.php ( 0.14 KB )
  53. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/service/PaginatorService.php ( 1.52 KB )
  54. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/service/ValidateService.php ( 0.99 KB )
  55. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/service/ModelService.php ( 2.04 KB )
  56. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-trace/src/Service.php ( 0.77 KB )
  57. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Middleware.php ( 6.72 KB )
  58. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/initializer/BootService.php ( 0.77 KB )
  59. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/Paginator.php ( 11.86 KB )
  60. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-validate/src/Validate.php ( 63.20 KB )
  61. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/Model.php ( 23.55 KB )
  62. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/Attribute.php ( 21.05 KB )
  63. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/AutoWriteData.php ( 4.21 KB )
  64. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/Conversion.php ( 6.44 KB )
  65. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/DbConnect.php ( 5.16 KB )
  66. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/ModelEvent.php ( 2.33 KB )
  67. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/RelationShip.php ( 28.29 KB )
  68. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/contract/Arrayable.php ( 0.09 KB )
  69. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/contract/Jsonable.php ( 0.13 KB )
  70. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/contract/Modelable.php ( 0.09 KB )
  71. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Db.php ( 2.88 KB )
  72. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/DbManager.php ( 8.52 KB )
  73. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Log.php ( 6.28 KB )
  74. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Manager.php ( 3.92 KB )
  75. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/psr/log/src/LoggerTrait.php ( 2.69 KB )
  76. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/psr/log/src/LoggerInterface.php ( 2.71 KB )
  77. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Cache.php ( 4.92 KB )
  78. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/psr/simple-cache/src/CacheInterface.php ( 4.71 KB )
  79. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/helper/Arr.php ( 16.63 KB )
  80. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/cache/driver/File.php ( 7.84 KB )
  81. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/cache/Driver.php ( 9.03 KB )
  82. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/contract/CacheHandlerInterface.php ( 1.99 KB )
  83. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/Request.php ( 0.09 KB )
  84. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Request.php ( 55.78 KB )
  85. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/middleware.php ( 0.25 KB )
  86. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Pipeline.php ( 2.61 KB )
  87. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-trace/src/TraceDebug.php ( 3.40 KB )
  88. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/middleware/SessionInit.php ( 1.94 KB )
  89. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Session.php ( 1.80 KB )
  90. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/session/driver/File.php ( 6.27 KB )
  91. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/contract/SessionHandlerInterface.php ( 0.87 KB )
  92. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/session/Store.php ( 7.12 KB )
  93. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Route.php ( 23.73 KB )
  94. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/RuleName.php ( 5.75 KB )
  95. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/Domain.php ( 2.53 KB )
  96. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/RuleGroup.php ( 22.43 KB )
  97. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/Rule.php ( 26.95 KB )
  98. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/RuleItem.php ( 9.78 KB )
  99. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/route/app.php ( 1.72 KB )
  100. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/facade/Route.php ( 4.70 KB )
  101. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/dispatch/Controller.php ( 4.74 KB )
  102. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/Dispatch.php ( 10.44 KB )
  103. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/controller/Index.php ( 4.81 KB )
  104. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/BaseController.php ( 2.05 KB )
  105. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/facade/Db.php ( 0.93 KB )
  106. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/connector/Mysql.php ( 5.44 KB )
  107. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/PDOConnection.php ( 52.47 KB )
  108. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/Connection.php ( 8.39 KB )
  109. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/ConnectionInterface.php ( 4.57 KB )
  110. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/builder/Mysql.php ( 16.58 KB )
  111. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/Builder.php ( 24.06 KB )
  112. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/BaseBuilder.php ( 27.50 KB )
  113. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/Query.php ( 15.71 KB )
  114. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/BaseQuery.php ( 45.13 KB )
  115. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/TimeFieldQuery.php ( 7.43 KB )
  116. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/AggregateQuery.php ( 3.26 KB )
  117. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/ModelRelationQuery.php ( 20.07 KB )
  118. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/ParamsBind.php ( 3.66 KB )
  119. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/ResultOperation.php ( 7.01 KB )
  120. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/WhereQuery.php ( 19.37 KB )
  121. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/JoinAndViewQuery.php ( 7.11 KB )
  122. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/TableFieldInfo.php ( 2.63 KB )
  123. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/Transaction.php ( 2.77 KB )
  124. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/log/driver/File.php ( 5.96 KB )
  125. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/contract/LogHandlerInterface.php ( 0.86 KB )
  126. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/log/Channel.php ( 3.89 KB )
  127. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/event/LogRecord.php ( 1.02 KB )
  128. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/Collection.php ( 16.47 KB )
  129. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/facade/View.php ( 1.70 KB )
  130. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/View.php ( 4.39 KB )
  131. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Response.php ( 8.81 KB )
  132. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/response/View.php ( 3.29 KB )
  133. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Cookie.php ( 6.06 KB )
  134. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-view/src/Think.php ( 8.38 KB )
  135. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/contract/TemplateHandlerInterface.php ( 1.60 KB )
  136. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-template/src/Template.php ( 46.61 KB )
  137. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-template/src/template/driver/File.php ( 2.41 KB )
  138. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-template/src/template/contract/DriverInterface.php ( 0.86 KB )
  139. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/runtime/temp/067d451b9a0c665040f3f1bdd3293d68.php ( 11.98 KB )
  140. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-trace/src/Html.php ( 4.42 KB )
  1. CONNECT:[ UseTime:0.000647s ] mysql:host=127.0.0.1;port=3306;dbname=f_mffb;charset=utf8mb4
  2. SHOW FULL COLUMNS FROM `fenlei` [ RunTime:0.000818s ]
  3. SELECT * FROM `fenlei` WHERE `fid` = 0 [ RunTime:0.000353s ]
  4. SELECT * FROM `fenlei` WHERE `fid` = 63 [ RunTime:0.000289s ]
  5. SHOW FULL COLUMNS FROM `set` [ RunTime:0.000478s ]
  6. SELECT * FROM `set` [ RunTime:0.000193s ]
  7. SHOW FULL COLUMNS FROM `article` [ RunTime:0.000568s ]
  8. SELECT * FROM `article` WHERE `id` = 489042 LIMIT 1 [ RunTime:0.000652s ]
  9. UPDATE `article` SET `lasttime` = 1783123842 WHERE `id` = 489042 [ RunTime:0.024138s ]
  10. SELECT * FROM `fenlei` WHERE `id` = 66 LIMIT 1 [ RunTime:0.004013s ]
  11. SELECT * FROM `article` WHERE `id` < 489042 ORDER BY `id` DESC LIMIT 1 [ RunTime:0.000563s ]
  12. SELECT * FROM `article` WHERE `id` > 489042 ORDER BY `id` ASC LIMIT 1 [ RunTime:0.008395s ]
  13. SELECT * FROM `article` WHERE `id` < 489042 ORDER BY `id` DESC LIMIT 10 [ RunTime:0.001846s ]
  14. SELECT * FROM `article` WHERE `id` < 489042 ORDER BY `id` DESC LIMIT 10,10 [ RunTime:0.000994s ]
  15. SELECT * FROM `article` WHERE `id` < 489042 ORDER BY `id` DESC LIMIT 20,10 [ RunTime:0.004498s ]
0.116176s