數(shù)系統(tǒng)設(shè)計(jì)與實(shí)現(xiàn))
YOLOv8PyQt5 密集人群人體檢測識別計(jì)數(shù)系統(tǒng)設(shè)計(jì)與實(shí)現(xiàn)這次我們來看一個(gè)非常典型的深度學(xué)習(xí)落地場景在商場、景區(qū)、地鐵站這類人流密集區(qū)域如何用 YOLOv8 配合 PyQt5 搭建一套人體檢測與計(jì)數(shù)系統(tǒng)。這類系統(tǒng)在智能安防、客流統(tǒng)計(jì)、區(qū)域擁擠預(yù)警里應(yīng)用很多難點(diǎn)主要集中在三塊——模型能不能在小目標(biāo)密集場景下保持精度、視頻流能不能實(shí)時(shí)處理、以及檢測結(jié)果能不能在桌面端應(yīng)用里直觀展示。下面我直接把這套系統(tǒng)的設(shè)計(jì)思路、訓(xùn)練流程、PyQt5 界面實(shí)現(xiàn)和性能優(yōu)化方案拆開寫清楚。如果你正準(zhǔn)備做畢業(yè)設(shè)計(jì)、課程項(xiàng)目或者想在公司內(nèi)部快速搭一個(gè)人體計(jì)數(shù) Demo這篇文章可以直接照著做。1. 核心能力速覽先看這套系統(tǒng)的關(guān)鍵能力能力項(xiàng)說明檢測模型YOLOv8支持 nano/small/medium/large/x 多版本界面框架PyQt5支持實(shí)時(shí)視頻顯示、檢測結(jié)果疊加、計(jì)數(shù)統(tǒng)計(jì)核心功能人體檢測、目標(biāo)計(jì)數(shù)、視頻/圖片/攝像頭輸入、檢測結(jié)果導(dǎo)出硬件要求訓(xùn)練推薦 NVIDIA GPU純推理可 CPU有 GPU 速度更快顯存占用與模型大小、輸入分辨率直接相關(guān)需按實(shí)際配置測試支持平臺Windows / Linux啟動方式Python 命令行啟動 PyQt5 應(yīng)用API 能力可封裝為檢測接口供其他程序調(diào)用批量任務(wù)支持批量圖片檢測和視頻逐幀檢測適合場景客流統(tǒng)計(jì)、擁擠預(yù)警、安防監(jiān)控、畢設(shè)/課設(shè)項(xiàng)目YOLOv8 是 Ultralytics 團(tuán)隊(duì)在 2023 年初發(fā)布的目標(biāo)檢測框架相比 YOLOv5 最大的變化是采用了 Anchor-Free 檢測頭并且把分類、檢測、分割、姿態(tài)估計(jì)統(tǒng)一到了一個(gè)框架里。配合 PyQt5 做桌面界面不需要瀏覽器直接打包成 exe 就能在 Windows 上跑這對安防領(lǐng)域的實(shí)際部署來說非常方便。2. 適用場景與使用邊界這套系統(tǒng)能解決的問題總結(jié)下來是三類靜態(tài)圖片中的人體檢測與計(jì)數(shù)。比如上傳一張商場入口的抓拍圖系統(tǒng)自動標(biāo)出每個(gè)人并顯示總數(shù)。視頻文件或?qū)崟r(shí)攝像頭中的人體檢測與計(jì)數(shù)。比如接入監(jiān)控?cái)z像頭 RTSP 流實(shí)時(shí)統(tǒng)計(jì)畫面里的人數(shù)變化。批量圖片的處理。比如一次性處理一整天抓拍的幾百張圖片輸出每張圖片的人數(shù)和檢測結(jié)果圖。適合的人群也很明確。做畢設(shè)和課設(shè)的學(xué)生、需要快速驗(yàn)證目標(biāo)檢測方案的開發(fā)者、以及安防或零售行業(yè)想做客流統(tǒng)計(jì)的技術(shù)人員都可以直接用這套方案。使用邊界同樣需要說清楚。這類系統(tǒng)基于視覺模型對遮擋嚴(yán)重的密集場景檢測精度會下降光線暗、雨天、低分辨率攝像頭都會影響效果。另外在公共區(qū)域部署時(shí)務(wù)必獲得監(jiān)控設(shè)備和數(shù)據(jù)使用的合法授權(quán)不能私自采集人臉或行人的可識別信息用于其他用途涉及隱私數(shù)據(jù)要脫敏處理。模型本身只輸出人體位置和數(shù)量不識別身份但采集端合規(guī)問題仍然需要自己把關(guān)。3. 環(huán)境準(zhǔn)備與前置條件先確認(rèn)環(huán)境。這套系統(tǒng)核心依賴是 PyTorch、Ultralytics YOLOv8、OpenCV 和 PyQt5。硬件方面訓(xùn)練推薦至少一塊 NVIDIA GPU最好是 6GB 以上顯存。純推理的話CPU 也能跑但視頻流實(shí)時(shí)性和高分辨率圖片的處理速度會差很多。如果你手里只有 GTX 1660 Ti、RTX 3060、RTX 4060 這類顯卡只要顯存超過 6GB跑 YOLOv8s 或 YOLOv8m 沒有問題。軟件環(huán)境建議如下我這里列的是推薦配置實(shí)際以你本機(jī)為基礎(chǔ)操作系統(tǒng)Windows 10/11 或 Ubuntu 20.04/22.04Python3.8 到 3.11 均可推薦 3.10CUDA11.8 或 12.1需匹配 PyTorch 版本主要依賴ultralytics、torch、torchvision、opencv-python、PyQt5、numpy安裝 PyTorch 前先確認(rèn)顯卡驅(qū)動和 CUDA 版本。推薦直接用 pip 安裝命令如下# 先安裝 PyTorchCUDA 12.1 版本示例 pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu121 # 再安裝其余依賴 pip install ultralytics opencv-python PyQt5 numpy如果在國內(nèi)網(wǎng)絡(luò)環(huán)境安裝較慢可以換用清華鏡像源pip install torch torchvision torchaudio -i https://pypi.tuna.tsinghua.edu.cn/simple pip install ultralytics opencv-python PyQt5 numpy -i https://pypi.tuna.tsinghua.edu.cn/simple安裝完成后用下面這段代碼驗(yàn)證環(huán)境是否正常import torch import ultralytics import cv2 import PyQt5 print(PyTorch:, torch.__version__) print(CUDA available:, torch.cuda.is_available()) print(Ultralytics:, ultralytics.__version__) print(OpenCV:, cv2.__version__) print(PyQt5:, PyQt5.QtCore.PYQT_VERSION_STR)如果torch.cuda.is_available()返回 False說明 PyTorch 的 CUDA 版本和驅(qū)動不匹配需要重新安裝對應(yīng)版本的 PyTorch。CPU 環(huán)境也能繼續(xù)做推理測試只是速度會慢。4. 數(shù)據(jù)處理與模型訓(xùn)練這套系統(tǒng)的核心之一是訓(xùn)練一個(gè)人體檢測模型。如果你不想自己訓(xùn)練可以直接用 YOLOv8 自帶的預(yù)訓(xùn)練權(quán)重yolov8n.pt和yolov8s.pt模型里本身就包含 person 這個(gè)類別。但你如果想要針對自己場景做更高精度的檢測用自己的數(shù)據(jù)集微調(diào)是必須的。4.1 數(shù)據(jù)集準(zhǔn)備人體檢測數(shù)據(jù)集最常見的公開選項(xiàng)是 COCO 數(shù)據(jù)集中的 person 類別或者 CrowdHuman 這類密集人群數(shù)據(jù)集。自己采集數(shù)據(jù)時(shí)要注意覆蓋不同角度、不同光照、不同密度場景。數(shù)據(jù)集目錄結(jié)構(gòu)建議如下dataset/ ├── images/ │ ├── train/ │ ├── val/ │ └── test/ └── labels/ ├── train/ ├── val/ └── test/標(biāo)注格式采用 YOLO 格式每個(gè)圖片對應(yīng)一個(gè)同名的 txt 文件每行代表一個(gè)目標(biāo)class_id x_center y_center width height坐標(biāo)值都是歸一化到 0~1 的浮點(diǎn)數(shù)。比如0 0.514648 0.479492 0.235352 0.772461標(biāo)注工具可以用 LabelImg 或者 LabelStudio導(dǎo)出成 YOLO 格式即可。4.2 模型配置文件在項(xiàng)目目錄下創(chuàng)建person-detection.yaml內(nèi)容如下path: ./dataset train: images/train val: images/val test: images/test names: 0: person這個(gè)文件告訴 YOLOv8 數(shù)據(jù)集的路徑和類別名稱。4.3 訓(xùn)練命令YOLOv8 訓(xùn)練入口非常簡單一條命令就能啟動yolo detect train dataperson-detection.yaml modelyolov8s.pt epochs100 imgsz640 batch16 device0參數(shù)含義data數(shù)據(jù)集配置文件的路徑。model預(yù)訓(xùn)練權(quán)重路徑也可以用yolov8s.yaml從頭訓(xùn)練但用預(yù)訓(xùn)練權(quán)重收斂更快。epochs訓(xùn)練輪數(shù)小數(shù)據(jù)集建議 100 輪起步。imgsz輸入圖像分辨率推薦 640 或 768。密集小目標(biāo)場景可以適當(dāng)提升到 960但顯存占用會增大。batch批大小根據(jù)顯存調(diào)整。8GB 顯存跑 YOLOv8s 建議 batch 不超過 32。device0表示第一張 GPUcpu表示 CPU 訓(xùn)練。訓(xùn)練過程中日志會打印每個(gè) epoch 的 mAP、precision、recall 等指標(biāo)。訓(xùn)練結(jié)束后最優(yōu)權(quán)重保存在runs/detect/train/weights/best.pt。如果你只是想快速驗(yàn)證整套系統(tǒng)流程先不要訓(xùn)練直接用官方預(yù)訓(xùn)練權(quán)重測試yolo predict modelyolov8s.pt sourcetest.jpg5. PyQt5 系統(tǒng)設(shè)計(jì)與界面實(shí)現(xiàn)現(xiàn)在進(jìn)入系統(tǒng)核心部分。這套人體檢測識別計(jì)數(shù)系統(tǒng)采用 PyQt5 作為桌面界面框架整體結(jié)構(gòu)分為三層層級組件職責(zé)界面層PyQt5 主窗口顯示視頻畫面、按鈕控制、計(jì)數(shù)結(jié)果展示邏輯層檢測線程、計(jì)數(shù)邏輯調(diào)用 YOLOv8 模型推理統(tǒng)計(jì)人數(shù)數(shù)據(jù)層輸入源管理支持圖片文件、視頻文件、攝像頭、RTSP 流界面布局參考如下左側(cè)視頻/圖片顯示區(qū)域。右側(cè)檢測結(jié)果信息區(qū)包括總?cè)藬?shù)、當(dāng)前幀人數(shù)、檢測耗時(shí)。底部操作按鈕包括打開圖片、打開視頻、打開攝像頭、停止檢測、導(dǎo)出結(jié)果。頂部菜單模型選擇、置信度閾值設(shè)置、IOU 閾值設(shè)置。這里直接給出主窗口的核心代碼框架import sys import cv2 import numpy as np from PyQt5.QtCore import QThread, pyqtSignal, Qt from PyQt5.QtGui import QImage, QPixmap from PyQt5.QtWidgets import ( QApplication, QMainWindow, QLabel, QPushButton, QVBoxLayout, QHBoxLayout, QWidget, QFileDialog, QSpinBox, QDoubleSpinBox, QMessageBox ) from ultralytics import YOLO class DetectThread(QThread): 檢測線程避免在 UI 線程中執(zhí)行推理導(dǎo)致界面卡頓 frame_signal pyqtSignal(object, int, float) # 處理后的幀、人數(shù)、耗時(shí) def __init__(self): super().__init__() self.model None self.cap None self.running False self.conf_thres 0.25 self.iou_thres 0.45 def load_model(self, model_path): self.model YOLO(model_path) def set_video_source(self, source): source 可以是圖片路徑、視頻路徑、攝像頭索引或 RTSP 地址 if isinstance(source, int): self.cap cv2.VideoCapture(source) else: self.cap cv2.VideoCapture(source) def run(self): self.running True while self.running: ret, frame self.cap.read() if not ret: break results self.model(frame, confself.conf_thres, iouself.iou_thres, verboseFalse) annotated_frame results[0].plot() person_count 0 for box in results[0].boxes: cls int(box.cls[0]) if cls 0: # person person_count 1 self.frame_signal.emit(annotated_frame, person_count, results[0].speed) def stop(self): self.running False檢測線程通過frame_signal把處理后的幀、人數(shù)和推理耗時(shí)發(fā)回主界面主界面再渲染到 QLabel 上。關(guān)鍵點(diǎn)在于推理絕對不能放在主界面線程里做否則視頻流一幀要卡幾百毫秒界面直接假死。主窗口類核心代碼如下class MainWindow(QMainWindow): def __init__(self): super().__init__() self.setWindowTitle(YOLOv8 人體檢測識別計(jì)數(shù)系統(tǒng)) self.setMinimumSize(1280, 720) # 主布局 self.video_label QLabel(請打開視頻或攝像頭) self.video_label.setAlignment(Qt.AlignCenter) self.video_label.setStyleSheet(background-color: #1e1e1e; color: white;) self.count_label QLabel(當(dāng)前人數(shù): 0) self.time_label QLabel(檢測耗時(shí): 0 ms) self.open_image_btn QPushButton(打開圖片) self.open_video_btn QPushButton(打開視頻) self.open_camera_btn QPushButton(打開攝像頭) self.stop_btn QPushButton(停止檢測) self.export_btn QPushButton(導(dǎo)出結(jié)果) # 參數(shù)控制 self.conf_spin QDoubleSpinBox() self.conf_spin.setRange(0.05, 0.95) self.conf_spin.setValue(0.25) self.conf_spin.setSingleStep(0.05) self.iou_spin QDoubleSpinBox() self.iou_spin.setRange(0.05, 0.95) self.iou_spin.setValue(0.45) self.iou_spin.setSingleStep(0.05) # 檢測線程 self.detect_thread DetectThread() self.detect_thread.frame_signal.connect(self.update_frame) self._init_ui() def _init_ui(self): central_widget QWidget() self.setCentralWidget(central_widget) layout QHBoxLayout(central_widget) # 左側(cè)視頻區(qū)域 left_layout QVBoxLayout() left_layout.addWidget(self.video_label) layout.addLayout(left_layout, stretch4) # 右側(cè)控制區(qū)域 right_layout QVBoxLayout() right_layout.addWidget(self.count_label) right_layout.addWidget(self.time_label) right_layout.addWidget(self.open_image_btn) right_layout.addWidget(self.open_video_btn) right_layout.addWidget(self.open_camera_btn) right_layout.addWidget(self.stop_btn) right_layout.addWidget(self.export_btn) right_layout.addWidget(QLabel(置信度閾值:)) right_layout.addWidget(self.conf_spin) right_layout.addWidget(QLabel(IOU 閾值:)) right_layout.addWidget(self.iou_spin) right_layout.addStretch() layout.addLayout(right_layout, stretch1) # 信號連接 self.open_image_btn.clicked.connect(self.open_image) self.open_video_btn.clicked.connect(self.open_video) self.open_camera_btn.clicked.connect(self.open_camera) self.stop_btn.clicked.connect(self.stop_detection) self.export_btn.clicked.connect(self.export_results) def update_frame(self, frame, count, speed): 將 OpenCV BGR 幀轉(zhuǎn)換為 QImage 并顯示 rgb_frame cv2.cvtColor(frame, cv2.COLOR_BGR2RGB) h, w, ch rgb_frame.shape bytes_per_line ch * w q_img QImage(rgb_frame.data, w, h, bytes_per_line, QImage.Format_RGB888) pixmap QPixmap.fromImage(q_img) pixmap pixmap.scaled( self.video_label.size(), Qt.KeepAspectRatio, Qt.SmoothTransformation ) self.video_label.setPixmap(pixmap) self.count_label.setText(f當(dāng)前人數(shù): {count}) self.time_label.setText(f檢測耗時(shí): {speed[inference]:.1f} ms) def open_image(self): path, _ QFileDialog.getOpenFileName( self, 選擇圖片, , 圖片文件 (*.jpg *.png *.bmp) ) if path: self.detect_thread.requestInterruption() frame cv2.imread(path) results self.detect_thread.model(frame, confself.conf_spin.value(), iouself.iou_spin.value()) annotated results[0].plot() person_count sum(1 for box in results[0].boxes if int(box.cls[0]) 0) self.update_frame(annotated, person_count, results[0].speed)圖中代碼是簡化的主窗口。實(shí)際使用時(shí)建議把模型路徑、輸入源、線程狀態(tài)管理寫得更嚴(yán)謹(jǐn)比如打開攝像頭前先停止當(dāng)前檢測線程再重新創(chuàng)建。6. 功能測試與效果驗(yàn)證6.1 圖片檢測測試測試目的驗(yàn)證模型能否正確識別圖片中的行人并統(tǒng)計(jì)數(shù)量。操作步驟啟動系統(tǒng)點(diǎn)擊打開圖片。選擇一張人流較多的圖片。觀察右側(cè)人數(shù)統(tǒng)計(jì)和檢測耗時(shí)。預(yù)期結(jié)果畫面中出現(xiàn)的人體都被矩形框標(biāo)出右側(cè)顯示的人數(shù)和圖片中實(shí)際人數(shù)基本一致。判斷標(biāo)準(zhǔn)檢測出的人數(shù)誤差是否在可接受范圍內(nèi)。如果漏檢嚴(yán)重降低置信度閾值如果誤檢多提高置信度閾值。6.2 視頻文件檢測測試測試目的驗(yàn)證系統(tǒng)在連續(xù)幀上的穩(wěn)定性和計(jì)數(shù)變化。操作步驟點(diǎn)擊打開視頻選擇一個(gè) mp4 文件。觀察視頻播放過程中人數(shù)統(tǒng)計(jì)是否實(shí)時(shí)更新。注意畫面是否卡頓。預(yù)期結(jié)果視頻流暢播放每幀畫面中的人數(shù)隨著行人進(jìn)出而變化。判斷標(biāo)準(zhǔn)視頻處理幀率能否達(dá)到 15 FPS 以上。如果幀率太低考慮換更小的模型yolov8n或降低輸入分辨率。6.3 攝像頭實(shí)時(shí)檢測測試測試目的驗(yàn)證攝像頭輸入源的實(shí)時(shí)性。操作步驟點(diǎn)擊打開攝像頭。在攝像頭前走動觀察檢測框是否跟隨人體移動。記錄檢測耗時(shí)。預(yù)期結(jié)果系統(tǒng)能以準(zhǔn)實(shí)時(shí)的速度對攝像頭畫面進(jìn)行檢測。判斷標(biāo)準(zhǔn)從畫面變化到檢測框更新的延遲是否在可接受范圍內(nèi)。CPU 推理延遲會明顯高于 GPU。6.4 密集場景測試這是這套系統(tǒng)的核心功能驗(yàn)證。選擇一張人流非常密集的圖片比如地鐵通道、景區(qū)門口觀察小目標(biāo)漏檢情況。遠(yuǎn)處的人體很小模型能否識別出來。人群互相遮擋時(shí)能否區(qū)分不同個(gè)體。計(jì)數(shù)結(jié)果與人工計(jì)數(shù)的差距。如果密集場景效果差優(yōu)先在更高分辨率下推理imgsz960或imgsz1280或者使用 YOLOv8m/YOLOv8l 等更大的模型。7. 接口 API 與批量任務(wù)如果你想把檢測能力集成到其他系統(tǒng)里可以單獨(dú)封裝一個(gè)檢測服務(wù)。這里給兩個(gè)方案。7.1 Python 函數(shù)封裝最簡單的 API 就是一個(gè)函數(shù)from ultralytics import YOLO model YOLO(runs/detect/train/weights/best.pt) def detect_persons(image_path, conf_thres0.25, iou_thres0.45): results model(image_path, confconf_thres, iouiou_thres, verboseFalse) boxes results[0].boxes persons [] for box in boxes: cls_id int(box.cls[0]) if cls_id 0: x1, y1, x2, y2 box.xyxy[0].tolist() conf float(box.conf[0]) persons.append({ bbox: [x1, y1, x2, y2], confidence: conf }) return {total: len(persons), persons: persons}調(diào)用result detect_persons(crowd.jpg) print(總?cè)藬?shù):, result[total])7.2 HTTP 接口服務(wù)用 FastAPI 把檢測封裝成 HTTP 服務(wù)方便跨語言調(diào)用from fastapi import FastAPI, UploadFile, File import cv2 import numpy as np from ultralytics import YOLO app FastAPI() model YOLO(runs/detect/train/weights/best.pt) app.post(/detect) async def detect(file: UploadFile File(...)): contents await file.read() nparr np.frombuffer(contents, np.uint8) img cv2.imdecode(nparr, cv2.IMREAD_COLOR) results model(img, verboseFalse) persons [] for box in results[0].boxes: if int(box.cls[0]) 0: persons.append({ bbox: [float(v) for v in box.xyxy[0]], confidence: float(box.conf[0]) }) return {total: len(persons), persons: persons}啟動服務(wù)uvicorn api_server:app --host 0.0.0.0 --port 8000測試請求curl -X POST -F filetest.jpg http://127.0.0.1:8000/detect7.3 批量圖片檢測批量處理任務(wù)建議加上進(jìn)度記錄和失敗重試邏輯。核心思路遍歷目錄下所有圖片逐張推理結(jié)果保存到輸出目錄并按原文件名命名同時(shí)生成一個(gè) CSV 匯總表import csv import os from pathlib import Path from ultralytics import YOLO model YOLO(yolov8s.pt) input_dir Path(./test_images) output_dir Path(./output_images) output_dir.mkdir(exist_okTrue) results_csv [] for img_path in input_dir.glob(*.jpg): try: results model(img_path, conf0.25, verboseFalse) annotated results[0].plot() output_path output_dir / img_path.name cv2.imwrite(str(output_path), annotated) person_count sum(1 for box in results[0].boxes if int(box.cls[0]) 0) results_csv.append([img_path.name, person_count]) print(f{img_path.name}: {person_count} people) except Exception as e: print(f{img_path.name}: FAILED - {e}) with open(batch_results.csv, w, newline) as f: writer csv.writer(f) writer.writerow([image, person_count]) writer.writerows(results_csv)批量任務(wù)做得再完善一點(diǎn)可以加多線程并行推理或者將任務(wù)拆分成多個(gè)批次交給 GPU 排隊(duì)處理。8. 資源占用與性能觀察資源占用是實(shí)際部署時(shí)最需要關(guān)心的部分。雖然沒有統(tǒng)一的數(shù)字可以套用但可以給出觀察方法和調(diào)優(yōu)方向。8.1 顯存占用怎么看訓(xùn)練和推理時(shí)用 NVIDIA 官方工具查看nvidia-smiLinux 上還可以用實(shí)時(shí)監(jiān)控watch -n 1 nvidia-smiWindows 上 Task Manager 的 GPU 頁簽也能看到顯存占用。8.2 模型大小對性能的影響模型參數(shù)量推理速度精度適用環(huán)境YOLOv8n最小最快較低嵌入式設(shè)備、實(shí)時(shí)性要求高YOLOv8s小較快中上消費(fèi)級 GPU、通用場景YOLOv8m中中等較高高精度需求YOLOv8l/x大較慢高服務(wù)器端離線處理選擇建議實(shí)時(shí)視頻流優(yōu)先 yolov8s 或 yolov8n密集小目標(biāo)圖片優(yōu)先 yolov8m 以上并結(jié)合 imgsz960 甚至 1280。8.3 推理性能關(guān)鍵參數(shù)輸入分辨率直接決定推理速度和顯存占用。640 和 1280 相比推理時(shí)間可能差 3~4 倍。batch size 對單張圖片推理沒有意義但對批量任務(wù)影響很大。GPU 在 batch 越大時(shí)效率越高。CPU 推理時(shí)輸入分辨率對速度的影響更大建議密集場景先用預(yù)處理裁切而不是整張大圖直接推理。8.4 PyQt5 界面性能優(yōu)化視頻流界面卡頓有兩個(gè)常見原因一是推理線程耗時(shí)太長二是 QImage 轉(zhuǎn)換和 QPixmap 縮放消耗過多 CPU。優(yōu)化方向推理線程只負(fù)責(zé)推理和畫框不負(fù)責(zé)界面縮放。顯示幀進(jìn)行降采樣。比如推理分辨率是 1280顯示時(shí)縮放到 720p。使用QLabel.setPixmap前先判斷畫面尺寸是否有變化避免重復(fù)縮放。幀率控制不是每幀都要做檢測可以隔幀檢測界面顯示原幀和最近一次檢測結(jié)果。9. 常見問題與排查方法實(shí)際部署中遇到最多的問題集中在這幾類問題現(xiàn)象可能原因排查方式解決方案安裝 ultralytics 失敗Python 版本過高或依賴沖突查看 pip 報(bào)錯日志使用 Python 3.9~3.11重新創(chuàng)建虛擬環(huán)境CUDA available 為 FalsePyTorch 版本和驅(qū)動不匹配運(yùn)行nvidia-smi查看驅(qū)動版本安裝匹配 CUDA 版本的 PyTorch訓(xùn)練時(shí)顯存不足batch 太大或 imgsz 太大查看 nvidia-smi 顯存占用降低 batch 或 imgsz開啟梯度累積檢測漏檢嚴(yán)重置信度閾值過高、模型過小、輸入分辨率不足查看置信度分布降低 conf 到 0.15換大模型提高 imgsz誤檢多置信度閾值太低、場景復(fù)雜查看誤檢框置信度提高 conf增加負(fù)樣本訓(xùn)練視頻流卡頓推理耗時(shí)太長、顯示刷新阻塞統(tǒng)計(jì)每幀推理耗時(shí)換小模型、降分辨率、隔幀檢測PyQt5 界面打不開依賴缺失或 Python 環(huán)境問題終端運(yùn)行看報(bào)錯重裝 PyQt5檢查 QT_QPA_PLATFORM攝像頭打不開攝像頭索引錯誤、權(quán)限不足用 cv2.VideoCapture 單獨(dú)測試檢查設(shè)備索引Windows 可嘗試 0/1/2批量任務(wù)中途失敗單張圖片損壞、內(nèi)存溢出查看異常日志增加 try/except逐張保存結(jié)果模型文件缺失權(quán)重路徑錯誤或未下載完成檢查路徑和文件大小重新下載權(quán)重確認(rèn)路徑正確重點(diǎn)說兩個(gè)常見坑第一個(gè)是 PyTorch 和 CUDA 版本不匹配。很多用戶裝完 PyTorch 后發(fā)現(xiàn)torch.cuda.is_available()是 False。解決方法是先查驅(qū)動支持的 CUDA 版本再安裝對應(yīng) PyTorch。最新的 NVIDIA 驅(qū)動一般能兼容 CUDA 12.x 系列直接安裝 cu121 或 cu124 的 PyTorch 通常沒問題。第二個(gè)是 PyQt5 界面閃退或空白。這個(gè)問題在高 DPI 縮放和多顯示器場景下很常見??梢栽谥鞒绦蛉肟诩由蟟mport os os.environ[QT_AUTO_SCREEN_SCALE_FACTOR] 1如果畫面閃爍或顯示異??梢試L試調(diào)整QImage.Format或檢查bytes_per_line是否計(jì)算正確。10. 最佳實(shí)踐與使用建議這套系統(tǒng)從原型到真實(shí)可用中間還有很多細(xì)節(jié)。結(jié)合我的經(jīng)驗(yàn)給幾條工程化建議。第一第一次跑通流程用最小配置。先拿一張圖片用官方預(yù)訓(xùn)練模型跑通 PyQt5 界面再逐步加視頻、攝像頭、自定義模型。一步到位容易出問題排查起來也麻煩。第二模型、數(shù)據(jù)集、輸出結(jié)果分目錄管理。推薦目錄結(jié)構(gòu)project/ ├── models/ # 訓(xùn)練好的權(quán)重文件 ├── dataset/ # 訓(xùn)練數(shù)據(jù)集 ├── images/ # 測試圖片 ├── videos/ # 測試視頻 ├── runs/ # YOLOv8 訓(xùn)練和推理日志 ├── ui/ # PyQt5 界面代碼 └── main.py # 主程序入口第三批量任務(wù)一定要加日志。每一張圖片的處理狀態(tài)、結(jié)果、耗時(shí)都記錄到日志文件里。處理幾千張圖片時(shí)沒有日志根本沒法定位是哪些圖片出了問題。第四接口服務(wù)要限制訪問范圍。如果封裝成 HTTP API至少設(shè)置--host 127.0.0.1只允許本機(jī)訪問或者加上簡單的 Token 驗(yàn)證。直接暴露在公網(wǎng)非常危險(xiǎn)。第五涉及人臉、聲音、版權(quán)素材時(shí)必須確認(rèn)授權(quán)。這套系統(tǒng)檢測的是行人整體不涉及人臉識別但在公共區(qū)域部署仍然需要符合當(dāng)?shù)乇O(jiān)控和數(shù)據(jù)管理規(guī)定。不要在未經(jīng)授權(quán)的情況下采集和存儲可識別個(gè)人的數(shù)據(jù)。第六發(fā)布或商用前要做效果復(fù)核。訓(xùn)練集上的指標(biāo)再好也不代表現(xiàn)場效果沒問題。拿一段真實(shí)場景的視頻跑一遍統(tǒng)計(jì)誤檢率、漏檢率再決定是否上線。11. 總結(jié)與下一步這套基于 YOLOv8 PyQt5 的人體檢測系統(tǒng)最值得嘗試的點(diǎn)是它把模型訓(xùn)練、桌面界面和實(shí)際業(yè)務(wù)場景串在了一條完整的鏈路上。從數(shù)據(jù)集準(zhǔn)備、模型微調(diào)到 PyQt5 界面開發(fā)、視頻流檢測、批量任務(wù)處理每一步都是可落地的。最先要驗(yàn)證的功能是圖片檢測和視頻檢測的基礎(chǔ)流程。用官方預(yù)訓(xùn)練模型跑通后再換自己的數(shù)據(jù)集微調(diào)。最容易踩的坑是環(huán)境配置階段的 CUDA 版本不匹配以及 PyQt5 界面渲染的性能瓶頸。后續(xù)可以繼續(xù)擴(kuò)展的方向也很多接入更復(fù)雜的跟蹤算法如 ByteTrack 或 DeepSORT 實(shí)現(xiàn)跨幀人數(shù)統(tǒng)計(jì)和軌跡繪制增加 ROI 區(qū)域設(shè)定只統(tǒng)計(jì)指定區(qū)域的人群密度接入 RTSP 流做多路攝像頭并發(fā)處理或者把 PyQt5 界面替換成 Web 界面統(tǒng)一管理多臺檢測設(shè)備。這套系統(tǒng)的價(jià)值不只是演示目標(biāo)檢測而是提供了一個(gè)完整的多功能桌面應(yīng)用開發(fā)模板值得你動手試一試。