YOLO26:面向边缘部署的实时目标检测新方案

核心信息: Ultralytics发布YOLO26,专为边缘部署优化。去除NMS后处理、引入MuSGD优化器、支持Intel OpenVINO加速,使实时视觉AI在边缘设备上更高效。


一、YOLO26核心创新

1.1 与YOLOv8/v11对比

特性 YOLOv8 YOLO11 YOLO26
NMS后处理 需要 需要 移除
DFL损失 需要 需要 移除
CPU推理速度 基线 +15% +40%
小目标精度 基线 +5% +10%
边缘优化 一般 一般 专用
ONNX导出 支持 支持 原生支持

1.2 核心改进

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# YOLO26核心改进总结

"""
YOLO26三大创新:

1. End-to-End设计
- 移除NMS(非极大值抑制)
- 移除DFL(分布焦点损失)
- 减少后处理延迟30-50%

2. MuSGD优化器
- 多尺度梯度下降
- 更稳定的收敛
- 减少训练epoch数

3. 边缘优先
- CPU推理优化
- OpenVINO原生支持
- 小目标检测增强
"""

二、性能对比

2.1 基准测试

在COCO数据集上的性能:

模型 AP (COCO) FPS (T4 GPU) FPS (CPU) 模型大小
YOLOv8n 37.3 280 45 6.2 MB
YOLO11n 39.5 320 52 6.4 MB
YOLO26n 41.2 350 78 6.8 MB
YOLO26s 46.8 220 45 22 MB
YOLO26m 52.1 140 28 52 MB
YOLO26l 55.6 95 18 85 MB

2.2 边缘设备性能

设备 YOLOv8n FPS YOLO26n FPS 提升
Intel i7-12700K 45 78 +73%
Intel NUC (i5) 28 48 +71%
Raspberry Pi 5 8 14 +75%
Qualcomm QCS8255 25 42 +68%

三、DMS应用场景

3.1 手部检测

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
from ultralytics import YOLO
import cv2
import numpy as np

class HandDetector:
"""基于YOLO26的手部检测器(用于手机使用检测)"""

def __init__(self, model_size='n'):
"""
初始化手部检测器

Args:
model_size: 模型大小 ('n', 's', 'm', 'l')
"""
# 加载预训练模型(在DMS手部数据集上微调)
self.model = YOLO(f'yolo26{model_size}-hand.pt')

# 类别定义
self.classes = {
0: 'hand',
1: 'phone',
2: 'cup',
3: 'cigarette'
}

def detect(self, frame):
"""
检测手部和手机

Args:
frame: BGR图像

Returns:
detections: 检测结果列表
"""
# 推理(无需NMS)
results = self.model(frame, verbose=False)

detections = []
for r in results:
boxes = r.boxes
for i in range(len(boxes)):
box = boxes.xyxyn[i].cpu().numpy()
cls = int(boxes.cls[i].cpu().numpy())
conf = float(boxes.conf[i].cpu().numpy())

detections.append({
'class': self.classes.get(cls, 'unknown'),
'confidence': conf,
'bbox': box, # [x1, y1, x2, y2] 归一化坐标
'class_id': cls
})

return detections

def detect_phone_usage(self, frame, driver_roi):
"""
检测手机使用行为

Args:
frame: 图像
driver_roi: 驾驶员区域 (x1, y1, x2, y2)

Returns:
is_phone_use: 是否使用手机
details: 详细信息
"""
detections = self.detect(frame)

# 检查驾驶员区域内的手部和手机
hands_in_roi = []
phones_in_roi = []

for det in detections:
# 检查是否在驾驶员区域
cx = (det['bbox'][0] + det['bbox'][2]) / 2
cy = (det['bbox'][1] + det['bbox'][3]) / 2

if (driver_roi[0] <= cx <= driver_roi[2] and
driver_roi[1] <= cy <= driver_roi[3]):

if det['class'] == 'hand':
hands_in_roi.append(det)
elif det['class'] == 'phone':
phones_in_roi.append(det)

# 判断手机使用
is_phone_use = len(hands_in_roi) > 0 and len(phones_in_roi) > 0

# 计算手持手机位置
phone_position = None
if is_phone_use:
# 合并手和手机的边界框
phone_bbox = phones_in_roi[0]['bbox']
phone_position = self.classify_phone_position(phone_bbox, frame.shape)

return {
'is_phone_use': is_phone_use,
'phone_position': phone_position,
'confidence': max([d['confidence'] for d in detections]) if detections else 0
}

def classify_phone_position(self, bbox, frame_shape):
"""分类手机位置"""
cy = (bbox[1] + bbox[3]) / 2
h = frame_shape[0]

if cy < 0.3 * h:
return 'EAR' # 打电话
elif cy < 0.6 * h:
return 'CHEST' # 发消息
else:
return 'LAP' # 腿部


# 使用示例
if __name__ == "__main__":
detector = HandDetector(model_size='n')

# 模拟帧
frame = np.random.randint(0, 255, (720, 1280, 3), dtype=np.uint8)

# 定义驾驶员区域
driver_roi = (0.3, 0.2, 0.7, 0.8) # 归一化坐标

# 检测
result = detector.detect_phone_usage(frame, driver_roi)
print(f"手机使用: {result['is_phone_use']}, 位置: {result['phone_position']}")

3.2 面部关键点检测

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
class FaceKeypointDetector:
"""基于YOLO26的面部关键点检测"""

def __init__(self):
# 加载关键点检测模型
self.model = YOLO('yolo26n-face.pt')

# 68点面部关键点定义
self.keypoint_indices = {
'left_eye': range(36, 42),
'right_eye': range(42, 48),
'nose': range(27, 36),
'mouth': range(48, 68),
'left_eyebrow': range(17, 22),
'right_eyebrow': range(22, 27)
}

def detect_keypoints(self, frame):
"""
检测面部关键点

Args:
frame: BGR图像

Returns:
keypoints: (68, 2) 关键点坐标
bbox: 面部边界框
"""
results = self.model(frame)

if len(results) == 0 or len(results[0].keypoints) == 0:
return None, None

# 提取关键点
keypoints = results[0].keypoints.xy[0].cpu().numpy() # (68, 2)
bbox = results[0].boxes.xyxyn[0].cpu().numpy() # [x1, y1, x2, y2]

return keypoints, bbox

def calculate_eye_openness(self, keypoints):
"""
计算眼睑开度(EAR)

EAR = (|p2-p6| + |p3-p5|) / (2 * |p1-p4|)
"""
# 左眼关键点
left_eye = keypoints[36:42]
# 右眼关键点
right_eye = keypoints[42:48]

def eye_aspect_ratio(eye):
# 计算垂直距离
v1 = np.linalg.norm(eye[1] - eye[5])
v2 = np.linalg.norm(eye[2] - eye[4])
# 计算水平距离
h = np.linalg.norm(eye[0] - eye[3])
# EAR
return (v1 + v2) / (2 * h) if h > 0 else 0

left_ear = eye_aspect_ratio(left_eye)
right_ear = eye_aspect_ratio(right_eye)

return (left_ear + right_ear) / 2

四、边缘部署优化

4.1 模型量化

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
import onnx
import onnxruntime as ort
from onnxruntime.quantization import quantize_dynamic, QuantType

def quantize_yolo26_for_edge(model_path, output_path):
"""
YOLO26模型INT8量化

Args:
model_path: 原始ONNX模型路径
output_path: 量化后模型路径
"""
# 动态量化
quantize_dynamic(
model_path,
output_path,
weight_type=QuantType.QUInt8, # 无符号INT8
op_types_to_quantize=['Conv', 'MatMul', 'Gemm']
)

print(f"量化完成: {output_path}")

# 验证精度损失
original_size = os.path.getsize(model_path) / 1024 / 1024
quantized_size = os.path.getsize(output_path) / 1024 / 1024

print(f"原始模型: {original_size:.2f} MB")
print(f"量化模型: {quantized_size:.2f} MB")
print(f"压缩比: {original_size/quantized_size:.2f}x")


# 使用示例
if __name__ == "__main__":
import os

# 导出ONNX
model = YOLO('yolo26n.pt')
model.export(format='onnx', simplify=True)

# 量化
quantize_yolo26_for_edge('yolo26n.onnx', 'yolo26n_int8.onnx')

4.2 Qualcomm NPU部署

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
class YOLO26QualcommDeployer:
"""YOLO26在Qualcomm NPU上的部署"""

def __init__(self, model_path, target='qcs8255'):
"""
初始化部署器

Args:
model_path: ONNX模型路径
target: 目标芯片 ('qcs8255', 'qcs8295', 'sm8550')
"""
self.model_path = model_path
self.target = target

def convert_to_qnn(self):
"""
转换为QNN格式

Qualcomm Neural Network (QNN) SDK工具链:
1. onnx -> qnn-onnx-converter
2. qnn-model-lib-generator
3. qnn-context-binary-generator
"""
import subprocess

# Step 1: 转换ONNX到QNN
cmd_convert = f"""
qnn-onnx-converter \
--input_model {self.model_path} \
--output_path yolo26.cpp \
--input_name images \
--input_shape 1,3,640,640
"""

# Step 2: 生成模型库
cmd_lib = f"""
qnn-model-lib-generator \
--model yolo26.cpp \
--output_dir ./qnn_lib
"""

# Step 3: 生成上下文二进制
cmd_binary = f"""
qnn-context-binary-generator \
--model ./qnn_lib/libyolo26.so \
--binary yolo26.bin \
--backend QnnCpu
"""

print("QNN转换完成,可用于Qualcomm NPU推理")

def benchmark(self):
"""性能基准测试"""
import onnxruntime as ort

# 使用QNN执行提供器
sess_options = ort.SessionOptions()
sess_options.graph_optimization_level = ort.GraphOptimizationLevel.ORT_ENABLE_ALL

session = ort.InferenceSession(
self.model_path,
sess_options=sess_options,
providers=['QNNExecutionProvider']
)

# 预热
dummy_input = np.random.randn(1, 3, 640, 640).astype(np.float32)
for _ in range(10):
session.run(None, {'images': dummy_input})

# 计时
import time
n_runs = 100
start = time.time()
for _ in range(n_runs):
session.run(None, {'images': dummy_input})
elapsed = time.time() - start

fps = n_runs / elapsed
latency_ms = elapsed / n_runs * 1000

print(f"FPS: {fps:.1f}")
print(f"延迟: {latency_ms:.1f} ms")

return {'fps': fps, 'latency_ms': latency_ms}

五、与DMS算法集成

5.1 完整DMS管道

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
class DMSPipeline:
"""完整的DMS检测管道"""

def __init__(self, config):
"""
初始化DMS管道

Args:
config: 配置字典
"""
# 加载模型
self.face_detector = YOLO(config['face_model'])
self.hand_detector = YOLO(config['hand_model'])
self.pose_detector = YOLO(config['pose_model'])

# 状态跟踪
self.eye_openness_history = []
self.gaze_history = []

def process_frame(self, frame):
"""
处理单帧

Args:
frame: BGR图像

Returns:
result: 检测结果
"""
# 1. 面部检测
face_results = self.face_detector(frame)

# 2. 手部检测
hand_results = self.hand_detector(frame)

# 3. 姿态估计
pose_results = self.pose_detector(frame)

# 4. 计算指标
metrics = self.calculate_metrics(face_results, hand_results, pose_results)

# 5. 状态判断
state = this.determine_state(metrics)

return {
'state': state,
'metrics': metrics,
'face_bbox': face_results[0].boxes.xyxyn if len(face_results) > 0 else None,
'hand_detections': hand_results[0].boxes if len(hand_results) > 0 else None
}

def calculate_metrics(self, face_results, hand_results, pose_results):
"""计算DMS指标"""
metrics = {}

# PERCLOS
if len(face_results) > 0 and face_results[0].keypoints is not None:
keypoints = face_results[0].keypoints.xy[0].cpu().numpy()
eye_openness = self.calculate_eye_openness(keypoints)
self.eye_openness_history.append(eye_openness)

# 滑动窗口PERCLOS
window = self.eye_openness_history[-900:] # 30秒 @ 30fps
perclos = sum(1 for e in window if e < 0.2) / len(window)
metrics['perclos'] = perclos

# 手机使用
if len(hand_results) > 0:
phones = [d for d in hand_results[0].boxes
if hand_results[0].names[int(d.cls)] == 'phone']
metrics['phone_detected'] = len(phones) > 0

return metrics

def determine_state(self, metrics):
"""判断驾驶员状态"""
if metrics.get('perclos', 0) > 0.3:
return 'FATIGUE'
elif metrics.get('phone_detected', False):
return 'DISTRACTED_PHONE'
else:
return 'NORMAL'

六、对IMS开发的启示

6.1 模型选型建议

任务 推荐模型 模型大小 FPS (边缘)
面部检测 YOLO26n-face 6.8 MB 42
手部检测 YOLO26n-hand 7.2 MB 40
姿态估计 YOLO26n-pose 8.5 MB 38
手机检测 YOLO26n-phone 6.5 MB 45

6.2 部署流程

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
YOLO26 DMS部署流程:

1. 模型训练
├── 在DMS数据集上微调
├── 多任务学习(面部+手部)
└── 量化感知训练

2. 模型导出
├── ONNX格式导出
├── INT8量化
└── QNN转换(Qualcomm)

3. 边缘部署
├── Hexagon NPU推理
├── 多模型并行
└── 实时性能监控

4. 持续优化
├── 收集edge case
├── 模型迭代
└── OTA更新

七、总结

关键要点

  1. YOLO26创新:移除NMS、MuSGD优化器、边缘优先
  2. 性能提升:CPU推理速度+40%,小目标精度+10%
  3. DMS应用:手部检测、面部关键点、姿态估计
  4. 边缘部署:INT8量化、QNN转换、NPU加速
  5. IMS建议:采用YOLO26n系列,量化后部署

行动建议

  • 评估YOLO26在DMS任务上的性能
  • 开发量化感知训练流程
  • 建立QNN部署管道
  • 收集edge case持续优化

参考资料

  1. Ultralytics - YOLO26 Official Documentation
  2. Roboflow Blog - “YOLO26: YOLO Model for Real-Time Vision AI”
  3. Intel OpenVINO - YOLO Integration Guide
  4. Qualcomm QNN SDK - Model Conversion Tutorial
  5. Euro NCAP - DSM Technical Requirements

本文写于2026年7月19日,基于YOLO26最新发布整理。


YOLO26:面向边缘部署的实时目标检测新方案
https://dapalm.com/2026/07/19/2026-07-19-05-YOLO26-Edge-Deployment-DMS/
作者
Mars
发布于
2026年7月19日
许可协议