基于YOLOv8的公共场所危险武器检测系统(Python源码+Pyqt6界面+数据集) 本数据集中的物品分为六类,分别为tarjeta、smartphone、pistol、monedero、billete、knife

公共场所的监控系统加入AI识别能力后,能实现很多有意思的功能。今天咱们来聊聊如何用YOLOv8训练一个能识别六类物品的检测系统——重点找出pistol和knife这类危险物品,顺便区分手机、钱包这些日常物品。

先看看数据集的构成。六类物品里tarjeta(卡片)、monedero(钱包)、billete(纸币)这类物品体积小且外形相似,knife和pistol的样本可能存在角度变化大的特点。训练前需要特别注意数据标注的质量,这里推荐用LabelImg重新抽查部分标注框:

from PIL import Image
import os

img_path = 'dataset/train/images/001.jpg'
label_path = img_path.replace('images','labels').replace('.jpg','.txt')

with Image.open(img_path) as img:
    img.show()  # 弹出图片预览窗口

with open(label_path, 'r') as f:
    print(f.read())  # 输出格式:类别编号 x_center y_center width height

模型训练直接用Ultralytics的YOLOv8接口特别方便。但要注意调整anchor设置——因为我们的目标物品尺寸差异较大,手枪可能只占画面5%而手机可能占据20%:

from ultralytics import YOLO

model = YOLO('yolov8n.yaml')  # 选择nano版本兼顾速度与精度
results = model.train(
    data='custom_dataset.yaml',
    epochs=100,
    imgsz=640,
    batch=16,
    optimizer='Adam',  # 改用Adam优化器应对小样本
    lr0=0.001,
    mixup=0.5  # 启用数据增强应对角度变化
)

训练完成后别急着部署,先用这段代码验证下实际效果。注意这里特别处理了检测结果的置信度阈值和不同类别的显示颜色:

import cv2
from ultralytics import YOLO

model = YOLO('best.pt')
cap = cv2.VideoCapture(0)  # 调用摄像头

while True:
    ret, frame = cap.read()
    results = model.predict(frame, conf=0.6)  # 调高置信度避免误报
    
    for box in results[0].boxes:
        x1, y1, x2, y2 = map(int, box.xyxy[0])
        cls_id = int(box.cls[0])
        # 危险物品用红色框,其他用绿色
        color = (0,0,255) if cls_id in [2,5] else (0,255,0)
        cv2.rectangle(frame, (x1,y1), (x2,y2), color, 2)
    
    cv2.imshow('Detection', frame)
    if cv2.waitKey(1) == 27: break

图形界面用PyQt6实现比Tkinter更现代。这里有个小技巧:把YOLO检测封装成QThread子类防止界面卡死。核心代码结构长这样:

from PyQt6.QtCore import QThread, pyqtSignal
from ultralytics import YOLO

class DetectionThread(QThread):
    result_ready = pyqtSignal(np.ndarray)  # 信号传递检测结果
    
    def __init__(self):
        super().__init__()
        self.model = YOLO('best.pt')
    
    def run(self):
        cap = cv2.VideoCapture(0)
        while True:
            ret, frame = cap.read()
            results = self.model.predict(frame)
            self.result_ready.emit(results[0].plot())  # 直接发送绘制好的图像

实际部署时会遇到两个坑:一是OpenCV的BGR格式与QT的RGB转换问题,记得用cvtColor转换;二是线程的资源释放,最好在窗口关闭事件里终止检测线程。

基于YOLOv8的公共场所危险武器检测系统(Python源码+Pyqt6界面+数据集) 本数据集中的物品分为六类,分别为tarjeta、smartphone、pistol、monedero、billete、knife

这个项目最有趣的部分是模型对相似物品的区分能力。测试时发现钱包(monedero)和智能手机容易被混淆,通过增加mixup数据增强比例到0.7后效果明显改善。而knife的检测准确率在侧视角度下会下降,需要补充更多侧视训练样本。

完整代码里还包含了报警功能——当检测到危险物品时,除了红框提示还会触发声音警报。这里用了QSoundEffect实现异步播放,避免阻塞主线程:

from PyQt6.QtMultimedia import QSoundEffect
from PyQt6.QtCore import QUrl

class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        self.alarm = QSoundEffect()
        self.alarm.setSource(QUrl.fromLocalFile("alert.wav"))
    
    def handle_detection(self, img):
        if has_dangerous_item(img):  # 自定义的危险物品判断逻辑
            self.alarm.play()

最后说个经验:用PyInstaller打包时记得把YOLO的权重文件和qt6的插件目录一起打包,否则在别人电脑上会闪退。建议写个hook文件处理这些依赖关系。

Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐