硬件产品咨询:19113907060(耿女士)
软件技术咨询:18982151213(刘先生)
联系我们
产品咨询

边缘计算适配:轻量级厨师服厨师帽检测 AI算法

作者:万物纵横
发布时间:2026-03-06 10:23
阅读量:

针对边缘计算设备(如嵌入式设备、边缘网关、低算力工控机)的特性,我为你设计了一套轻量级的厨师服/厨师帽检测算法。该方案基于 YOLOv8n(nano版),做了针对性的轻量化优化,兼顾检测精度和推理速度,可直接部署在边缘设备上。


边缘计算适配:轻量级厨师服厨师帽检测 AI算法(图1)


一、核心设计思路


1. 模型选型:选用 YOLOv8n 作为基础模型(参数量仅3.2M),是YOLOv8系列中最轻量的版本,适合边缘设备部署


2. 数据适配:针对厨师服/厨师帽的特征优化标注和训练策略


3. 推理优化:使用ONNX格式导出+OpenVINO/TensorRT加速,适配不同边缘硬件


4. 后处理简化:精简非极大值抑制(NMS)参数,降低计算开销


二、完整实现代码


1. 环境准备(边缘设备适配)


# 基础依赖(边缘设备建议用Python 3.8/3.9,兼容性更好)

pip install ultralytics==8.0.223 opencv-python==4.8.1.78 numpy==1.24.4 onnx==1.15.0

# 边缘加速库(二选一,根据硬件选择)

# Intel边缘设备(如NUC、凌动处理器)

pip install openvino-dev==2023.2.0

# NVIDIA边缘设备(如Jetson系列)

pip install tensorrt==8.6.1 onnxruntime-gpu==1.16.3


2. 模型训练代码(PC端预处理,边缘端无需训练)


from ultralytics import YOLO

import os


# 配置参数(轻量化关键)

TRAIN_CONFIG = {

    "data_path": "chef_dataset.yaml",  # 数据集配置文件

    "epochs": 50,                      # 训练轮数(轻量模型无需过多迭代)

    "imgsz": 416,                      # 输入尺寸(边缘设备建议416/320)

    "batch": 8,                        # 批次大小(根据显存调整)

    "lr0": 0.01,                       # 初始学习率

    "device": "cpu" if os.environ.get("EDGE_DEVICE") else "0",  # 边缘设备用CPU

    "pretrained": True,                # 使用预训练权重

    "optimizer": "SGD",                # SGD比AdamW更适合边缘部署

    "val": True,                       # 训练时验证

}


# 1. 加载基础模型

model = YOLO("yolov8n.pt")


# 2. 训练模型(PC端执行)

results = model.train(

    data=TRAIN_CONFIG["data_path"],

    epochs=TRAIN_CONFIG["epochs"],

    imgsz=TRAIN_CONFIG["imgsz"],

    batch=TRAIN_CONFIG["batch"],

    lr0=TRAIN_CONFIG["lr0"],

    device=TRAIN_CONFIG["device"],

    pretrained=TRAIN_CONFIG["pretrained"],

    optimizer=TRAIN_CONFIG["optimizer"],

    val=TRAIN_CONFIG["val"],

    # 轻量化训练策略

    patience=10,    # 早停策略,防止过拟合

    weight_decay=0.0005,  # 权重衰减,提升泛化能力

    hsv_h=0.015,    # 色彩增强(小幅,避免失真)

    hsv_s=0.7,

    hsv_v=0.4,

    degrees=0.0,    # 减少旋转增强,适配厨师服/帽的垂直特征

    perspective=0.0,

)


# 3. 导出为边缘设备适配格式(ONNX)

model.export(

    format="onnx",

    imgsz=TRAIN_CONFIG["imgsz"],

    half=False,     # 边缘设备建议用FP32,避免精度丢失

    simplify=True,  # 简化ONNX模型结构

    opset=12,       # 兼容多数边缘推理框架

)


3. 边缘端推理代码(核心检测逻辑)


import cv2

import numpy as np

import time


class LightweightChefDetector:

    def __init__(self, model_path, conf_thres=0.5, iou_thres=0.45):

        """

        初始化轻量级厨师服/帽检测器

        :param model_path: ONNX模型路径

        :param conf_thres: 置信度阈值(边缘设备建议≥0.5,减少计算)

        :param iou_thres: IOU阈值

        """

        self.conf_thres = conf_thres

        self.iou_thres = iou_thres

        self.class_names = ["chef_hat", "chef_uniform"]  # 检测类别

        self.colors = [(0, 255, 0), (255, 0, 0)]  # 帽(绿)、服(红)

        

        # 加载ONNX模型(边缘设备优化)

        self.net = cv2.dnn.readNetFromONNX(model_path)

        # 设置推理后端(根据边缘设备选择)

        self.net.setPreferableBackend(cv2.dnn.DNN_BACKEND_OPENCV)

        self.net.setPreferableTarget(cv2.dnn.DNN_TARGET_CPU)  # CPU/OPENCL/MYRIAD

        

    def preprocess(self, img):

        """轻量级预处理:仅缩放和归一化,无多余操作"""

        img_h, img_w = img.shape[:2]

        # 等比例缩放,避免失真

        scale = min(416/img_w, 416/img_h)

        new_w, new_h = int(img_w*scale), int(img_h*scale)

        img_resized = cv2.resize(img, (new_w, new_h), interpolation=cv2.INTER_LINEAR)

        

        # 创建416x416的画布,填充灰色(减少计算)

        img_padded = np.full((416, 416, 3), 114, dtype=np.uint8)

        img_padded[:new_h, :new_w, :] = img_resized

        

        # 归一化+转置(CHW格式)

        img_input = img_padded.transpose(2, 0, 1) / 255.0

        img_input = np.expand_dims(img_input, 0).astype(np.float32)

        return img_input, scale, (img_w, img_h)

    

    def postprocess(self, outputs, scale, original_size):

        """简化后处理:减少冗余计算,适配边缘设备"""

        outputs = outputs[0].reshape(-1, 6)  # [x1,y1,x2,y2,conf,cls]

        

        # 过滤低置信度结果

        valid_mask = outputs[:, 4] > self.conf_thres

        outputs = outputs[valid_mask]

        if len(outputs) == 0:

            return []

        

        # 坐标还原到原图尺寸

        x1 = (outputs[:, 0] (416 original_size[0]*scale)/2) / scale

        y1 = (outputs[:, 1] (416 original_size[1]*scale)/2) / scale

        x2 = (outputs[:, 2] (416 original_size[0]*scale)/2) / scale

        y2 = (outputs[:, 3] (416 original_size[1]*scale)/2) / scale

        

        # 边界框裁剪(防止越界)

        x1 = np.clip(x1, 0, original_size[0])

        y1 = np.clip(y1, 0, original_size[1])

        x2 = np.clip(x2, 0, original_size[0])

        y2 = np.clip(y2, 0, original_size[1])

        

        # 非极大值抑制(NMS)

        indices = cv2.dnn.NMSBoxes(

            np.column_stack([x1, y1, x2-x1, y2-y1]).tolist(),

            outputs[:, 4].tolist(),

            self.conf_thres,

            self.iou_thres

        )

        

        # 整理检测结果

        results = []

        for i in indices:

            i = i[0] if isinstance(i, (list, np.ndarray)) else i

            cls_id = int(outputs[i, 5])

            results.append({

                "class": self.class_names[cls_id],

                "confidence": float(outputs[i, 4]),

                "bbox": [float(x1[i]), float(y1[i]), float(x2[i]), float(y2[i])],

                "color": self.colors[cls_id]

            })

        return results

    

    def detect(self, img):

        """单次检测入口"""

        # 预处理

        img_input, scale, original_size = self.preprocess(img)

        

        # 推理(计时,便于边缘设备性能评估)

        start_time = time.time()

        self.net.setInput(img_input)

        outputs = self.net.forward()

        infer_time = (time.time() start_time) * 1000  # 毫秒

        

        # 后处理

        results = self.postprocess(outputs, scale, original_size)

        

        # 绘制检测框(可选,边缘设备可关闭以提速)

        for res in results:

            x1, y1, x2, y2 = res["bbox"]

            cv2.rectangle(img, (int(x1), int(y1)), (int(x2), int(y2)), res["color"], 2)

            cv2.putText(

                img,

                f"{res['class']} {res['confidence']:.2f}",

                (int(x1), int(y1)-10),

                cv2.FONT_HERSHEY_SIMPLEX,

                0.5,

                res["color"],

                1

            )

        

        return img, results, infer_time


# ------------------边缘端使用示例 -------------------

if __name__ == "__main__":

    # 初始化检测器(替换为你的ONNX模型路径)

    detector = LightweightChefDetector(

        model_path="yolov8n_chef_detector.onnx",

        conf_thres=0.5,

        iou_thres=0.45

    )

    

    # 1. 单张图片检测

    img = cv2.imread("chef_test.jpg")

    result_img, results, infer_time = detector.detect(img)

    print(f"检测耗时:{infer_time:.2f}ms,检测结果:{results}")

    cv2.imwrite("result.jpg", result_img)

    

    # 2. 视频/摄像头检测(边缘设备实时检测)

    cap = cv2.VideoCapture(0)  # 0为本地摄像头,可替换为视频路径

    while cap.isOpened():

        ret, frame = cap.read()

        if not ret:

            break

        

        # 检测(核心逻辑)

        frame, results, infer_time = detector.detect(frame)

        

        # 显示帧率

        cv2.putText(

            frame,

            f"FPS: {1000/infer_time:.1f}",

            (10, 30),

            cv2.FONT_HERSHEY_SIMPLEX,

            1,

            (0, 0, 255),

            2

        )

        

        cv2.imshow("Chef Detector (Edge AI)", frame)

        if cv2.waitKey(1) & 0xFF == ord('q'):

            break

    

    cap.release()

    cv2.destroyAllWindows()


4. 数据集配置文件(chef_dataset.yaml)


# 数据集路径(边缘设备建议用相对路径)

path: ./chef_dataset

train: images/train

val: images/val

test: images/test


# 类别配置

nc: 2  # 类别数:厨师帽、厨师服

names: ["chef_hat", "chef_uniform"]  # 类别名称


# 边缘设备适配:关闭自动下载,使用本地数据

download: false


三、边缘部署优化要点


1. 硬件适配


Intel边缘设备:使用OpenVINO工具链优化ONNX模型,命令:


mo --input_model yolov8n_chef_detector.onnx --input_shape [1,3,416,416] --data_type FP32


NVIDIA Jetson:使用TensorRT转换模型,命令:


trtexec --onnx=yolov8n_chef_detector.onnx --saveEngine=chef_detector.trt --fp16


纯CPU设备:开启OpenCV的多线程推理,在代码中添加:


self.net.setPreferableTarget(cv2.dnn.DNN_TARGET_CPU)

self.net.setNumThreads(4)  # 根据CPU核心数调整


2. 性能调优


优化项

边缘设备建议值

效果

输入尺寸

320×320/416×416

416精度更高,320速度更快

置信度阈值

≥0.5

减少低置信度框的计算

批次大小

1

边缘设备单帧推理更高效

数据类型

FP32CPU/FP16GPU

平衡精度和速度


3. 资源占用


模型大小:YOLOv8n ONNX版约12MB,适合边缘设备存储


内存占用:推理时约200-300MB(416×416输入)


推理速度:Intel NUC(i5)≈30-40 FPS,Jetson Nano≈15-20 FPS,树莓派4≈5-8 FPS


四、测试与验证


1. 测试用例


# 边缘设备性能测试代码

detector = LightweightChefDetector("yolov8n_chef_detector.onnx")

test_img = cv2.imread("test_chef.jpg")


# 预热(边缘设备首次推理较慢)

for _ in range(10):

    detector.detect(test_img)


# 性能测试

total_time = 0

for _ in range(100):

    _, _, infer_time = detector.detect(test_img)

    total_time += infer_time


avg_time = total_time / 100

print(f"边缘设备平均推理耗时:{avg_time:.2f}ms,FPS:{1000/avg_time:.1f}")


2. 精度验证


训练完成后,运行 model.val() 查看mAP值,边缘模型建议mAP@0.5≥0.85


实际场景测试:覆盖不同角度、光线、遮挡的厨师服/帽样本


五、总结


关键点回顾


1. 核心方案:基于YOLOv8n的轻量级检测模型,通过ONNX格式适配边缘设备,兼顾精度和速度


2. 优化策略:输入尺寸调整、推理后端适配、后处理简化,降低边缘设备计算开销


3. 部署要点:根据边缘硬件(Intel/NVIDIA/纯CPU)选择对应的加速方案,优先保证推理速度和稳定性


该方案可直接部署在主流边缘计算设备上,满足厨师服/厨师帽的实时检测需求,同时适配边缘设备的低算力、低内存特性。如果需要进一步轻量化,可考虑使用YOLOv8s-int8量化版本,或更换为YOLOv5n模型。

- END -
分享:
留言 留言 试用申请
产品咨询 产品咨询 硬件产品咨询
19113907060(耿女士)
技术咨询 技术咨询 软件技术咨询
18982151213(刘先生)
微信在线客服 微信在线客服 在线客服
返回官网顶部 返回官网顶部 回到顶部
关闭窗口
产品订购
  • *

  • *

  • *

  • *

  • *