1. YOLOv8可视化基础概念与核心组件
1.1 可视化在目标检测中的重要性
目标检测可视化是计算机视觉项目开发中不可或缺的一环。在YOLOv8这类先进的目标检测模型中,可视化系统承担着三个关键职能:
-
模型性能验证:通过直观的检测框和标签,开发者能够快速评估模型在不同场景下的表现。例如,可以立即发现模型是否容易混淆相似类别(如猫和狗),或者在小目标检测上是否存在短板。
-
问题诊断工具:当模型出现误检或漏检时,可视化结果能帮助定位问题根源。比如连续的漏检可能暗示需要调整NMS阈值,而频繁的类别混淆则表明需要加强特定类别的训练数据。
-
成果展示媒介:相比抽象的mAP指标,带有检测框的可视化图像能让非技术人员直观理解模型能力。这在项目汇报、产品演示等场景中尤为重要。
YOLOv8的可视化系统设计充分考虑了这些需求,将检测结果转化为包含边界框位置(xyxy或xywh格式)、类别标签、置信度分数等丰富信息的视觉元素。这种设计使得技术评估和沟通效率都得到显著提升。
实际项目经验表明,良好的可视化能节省约30%的模型调试时间。特别是在处理复杂场景时,直接观察检测结果比分析数值指标更高效。
1.2 Ultralytics可视化框架核心架构
Ultralytics为YOLOv8设计的可视化框架采用模块化架构,主要由三个协同工作的核心组件构成:
预测引擎:
- 负责处理输入数据(图像/视频)并执行模型推理
- 通过
model.predict()方法的参数控制预测行为 - 关键参数包括:
conf:置信度阈值(默认0.25)iou:NMS的IoU阈值(默认0.7)imgsz:推理尺寸(默认640)device:计算设备(自动选择CUDA或CPU)
结果处理器:
- 将原始预测数据封装为
Results对象 - 提供数据格式转换(如xyxy↔xywh)
- 实现检测结果的过滤和排序
- 包含原始图像和预处理信息
渲染器:
- 根据
Results对象生成可视化输出 - 支持多种输出格式(OpenCV数组、PIL图像、文件保存)
- 提供丰富的样式定制选项:
- 线条粗细(
line_width) - 字体大小(
font_size) - 颜色方案(
color) - 标签内容(显示/隐藏置信度、类别等)
- 线条粗细(
python复制# 可视化框架工作流程示例
from ultralytics import YOLO
import cv2
# 1. 初始化预测引擎
model = YOLO('yolov8n.pt')
# 2. 执行预测并获取Results对象
results = model.predict('input.jpg',
conf=0.4,
imgsz=640,
save=False) # 不自动保存以进行自定义处理
# 3. 自定义渲染
for result in results:
# 获取OpenCV格式的可视化结果
vis_img = result.plot(line_width=2,
font_size=0.5,
labels=True,
conf=True)
# 显示结果
cv2.imshow('Custom Visualization', vis_img)
cv2.waitKey(0)
cv2.destroyAllWindows()
这种模块化设计带来的最大优势是灵活性。开发者可以在任意阶段介入处理流程:
- 预测阶段调整参数优化推理效率
- 结果处理阶段实现自定义过滤逻辑
- 渲染阶段完全控制视觉呈现效果
1.3 Results对象深度解析
Results对象是YOLOv8可视化系统的核心数据结构,理解其内部组成是进行高级可视化的前提。该对象主要包含以下关键属性:
基础检测信息:
boxes:边界框对象,包含:.xyxy:左上右下坐标格式的Tensor.xywh:中心点坐标+宽高格式的Tensor.conf:置信度Tensor.cls:类别ID Tensor.data:原始检测数据矩阵
names:类别ID到名称的映射字典speed:各阶段耗时统计(毫秒)
图像相关属性:
orig_img:原始图像数据(numpy数组)orig_shape:原始图像尺寸(H,W)path:原始图像路径
方法接口:
plot():生成可视化图像save():保存结果到文件show():显示结果(Jupyter环境)
python复制# Results对象深度探索示例
results = model.predict('demo.jpg', verbose=False)
result = results[0]
# 边界框信息分析
print(f"检测到 {len(result.boxes)} 个目标")
print(f"第一个目标的坐标(xyxy): {result.boxes[0].xyxy}")
print(f"第一个目标的置信度: {result.boxes[0].conf.item():.3f}")
print(f"第一个目标的类别: {result.names[int(result.boxes[0].cls.item())]}")
# 性能分析
print(f"预处理耗时: {result.speed['preprocess']:.1f}ms")
print(f"推理耗时: {result.speed['inference']:.1f}ms")
print(f"后处理耗时: {result.speed['postprocess']:.1f}ms")
# 可视化定制
custom_vis = result.plot(
line_width=3,
font_size=0.8,
labels=True,
conf=True,
boxes=True,
masks=False # 分割任务时使用
)
掌握这些属性和方法后,开发者可以实现各种高级功能:
- 基于置信度的动态过滤
- 特定类别的特殊渲染
- 多模型结果的融合显示
- 自定义性能监控面板
2. 单张图片可视化全面掌握
2.1 基础检测框与标签绘制
YOLOv8的单图可视化功能既简单易用又高度可定制。最基本的可视化只需调用model.predict()并设置save=True:
python复制from ultralytics import YOLO
# 初始化模型
model = YOLO('yolov8n.pt')
# 基础可视化
results = model.predict('street.jpg',
save=True, # 自动保存可视化结果
conf=0.25, # 置信度阈值
show=False) # 不弹出显示窗口
这段代码会在runs/detect/predict目录下生成带检测框的结果图像,默认包含:
- 彩色边界框(不同类别不同颜色)
- 类别标签(如"person"、"car")
- 置信度分数(如"0.87")
对于更精细的控制,可以使用以下常用参数:
| 参数 | 类型 | 说明 | 推荐值 |
|---|---|---|---|
conf |
float | 置信度阈值 | 0.25-0.5 |
line_width |
int/float | 框线粗细 | 1-3或"auto" |
font_size |
float | 标签字体大小 | 0.5-1.0 |
hide_labels |
bool | 隐藏类别标签 | False |
hide_conf |
bool | 隐藏置信度 | False |
boxes |
bool | 是否绘制边界框 | True |
python复制# 精细控制的可视化示例
results = model.predict(
'office.jpg',
save=True,
conf=0.35, # 提高置信度阈值减少误检
line_width=2, # 中等粗细的框线
font_size=0.7, # 稍大的字体
hide_conf=False, # 显示置信度
show=False # 批量处理时不显示
)
2.2 高级可视化参数详解
YOLOv8提供了丰富的高级参数来满足专业需求,这些参数可分为几大类:
显示控制参数:
show:是否弹出显示窗口(适合调试)save:是否保存结果文件(适合批量处理)save_txt:是否保存检测结果为YOLO格式文本save_conf:在保存的文本中包含置信度
样式调整参数:
line_width:支持数字或"auto"(基于图像尺寸自动调整)font_size:支持数字或"auto"box_color:边界框颜色(RGB元组或颜色名字符串)label_color:标签背景颜色
输出控制参数:
project:结果保存的根目录(默认"runs/detect")name:运行名称(生成子目录)exist_ok:是否允许覆盖已有结果
python复制# 高级参数综合应用
results = model.predict(
'park.jpg',
save=True,
show=True,
conf=0.3,
iou=0.6, # 调整NMS的IoU阈值
line_width='auto', # 自动调整线宽
font_size='auto', # 自动调整字体
box_color=(255,0,0), # 红色边界框
label_color=(0,255,0), # 绿色标签背景
project='my_project',
name='exp1',
exist_ok=True # 覆盖已有结果
)
2.3 自定义颜色与样式方案
默认的颜色方案虽然实用,但在特定场景下可能需要定制。YOLOv8支持多种颜色指定方式:
- 统一颜色方案:
python复制# 所有检测框使用相同颜色
results = model.predict('mall.jpg',
save=True,
box_color=(0,255,0)) # 绿色框
- 按类别指定颜色:
python复制# 不同类别使用不同颜色
color_map = {
0: (255,0,0), # 人-红色
2: (0,255,0), # 车-绿色
5: (0,0,255) # 公交车-蓝色
}
results = model.predict('traffic.jpg',
save=True,
box_color=color_map)
- 动态颜色方案:
python复制# 根据置信度动态设置颜色
results = model.predict('airport.jpg')
for result in results:
img = result.orig_img.copy()
for box in result.boxes:
conf = box.conf.item()
cls = int(box.cls.item())
# 高置信度-绿色,中-黄色,低-红色
if conf > 0.7:
color = (0, 255, 0)
elif conf > 0.4:
color = (0, 255, 255)
else:
color = (0, 0, 255)
# 绘制边界框
x1, y1, x2, y2 = map(int, box.xyxy[0])
cv2.rectangle(img, (x1,y1), (x2,y2), color, 2)
# 绘制标签
label = f"{result.names[cls]} {conf:.2f}"
cv2.putText(img, label, (x1,y1-10),
cv2.FONT_HERSHEY_SIMPLEX, 0.6, color, 2)
cv2.imwrite('dynamic_color.jpg', img)
2.4 多类别可视化策略
当图像中包含多个类别的目标时,有效的可视化策略尤为重要:
1. 颜色区分法:
python复制# 为每个类别生成视觉区分明显的颜色
def generate_colors(n):
hsv = [(i/n, 1, 1) for i in range(n)]
colors = list(map(lambda c: tuple(int(x*255) for x in colorsys.hsv_to_rgb(*c)), hsv))
return colors
# 应用颜色区分
results = model.predict('city.jpg')
class_ids = set(int(box.cls.item()) for r in results for box in r.boxes)
color_map = {cid: generate_colors(len(class_ids))[i]
for i, cid in enumerate(class_ids)}
for result in results:
img = result.plot(box_color=color_map)
cv2.imwrite('multi_class.jpg', img)
2. 分层显示法:
python复制# 按类别分层显示
results = model.predict('stadium.jpg')
class_order = [0, 1, 2, 3, 5, 7] # 定义类别显示顺序
for result in results:
img = result.orig_img.copy()
for cls_id in class_order:
for box in result.boxes:
if int(box.cls.item()) == cls_id:
# 绘制该类别所有检测框
x1, y1, x2, y2 = map(int, box.xyxy[0])
color = (36*cls_id % 256, 72*cls_id % 256, 108*cls_id % 256)
cv2.rectangle(img, (x1,y1), (x2,y2), color, 2)
cv2.imwrite('layered_view.jpg', img)
3. 视频流可视化实战技巧
3.1 视频文件处理全流程
处理视频文件需要特殊考虑帧率同步、内存管理等要素。以下是优化的视频处理流程:
python复制from ultralytics import YOLO
import cv2
import time
def process_video(input_path, output_path, model_name='yolov8n.pt', conf=0.3):
"""优化的视频处理函数
Args:
input_path: 输入视频路径
output_path: 输出视频路径
model_name: 模型文件名
conf: 置信度阈值
"""
# 初始化
model = YOLO(model_name)
cap = cv2.VideoCapture(input_path)
fps = cap.get(cv2.CAP_PROP_FPS)
width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
# 创建视频写入器
fourcc = cv2.VideoWriter_fourcc(*'mp4v')
out = cv2.VideoWriter(output_path, fourcc, fps, (width, height))
# 处理帧
frame_count = 0
start_time = time.time()
while True:
ret, frame = cap.read()
if not ret:
break
# 推理
results = model(frame, conf=conf, verbose=False)
# 可视化
vis_frame = results[0].plot()
# 写入输出
out.write(vis_frame)
frame_count += 1
# 打印进度
if frame_count % 100 == 0:
elapsed = time.time() - start_time
print(f"已处理 {frame_count} 帧 | 平均FPS: {frame_count/elapsed:.1f}")
# 释放资源
cap.release()
out.release()
print(f"处理完成! 输出保存到 {output_path}")
# 使用示例
process_video('input.mp4', 'output.mp4', 'yolov8s.pt', conf=0.4)
3.2 实时摄像头流可视化
实时处理需要特别关注延迟优化:
python复制from ultralytics import YOLO
import cv2
import time
class CameraProcessor:
def __init__(self, model_name='yolov8n.pt', camera_id=0):
self.model = YOLO(model_name)
self.cap = cv2.VideoCapture(camera_id)
self.fps_history = []
# 设置摄像头参数
self.cap.set(cv2.CAP_PROP_FRAME_WIDTH, 1280)
self.cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 720)
self.cap.set(cv2.CAP_PROP_FPS, 30)
def run(self, conf=0.3):
print("按'q'退出...")
while True:
start_time = time.time()
# 读取帧
ret, frame = self.cap.read()
if not ret:
break
# 推理
results = self.model(frame, conf=conf, verbose=False)
# 可视化
vis_frame = results[0].plot()
# 计算FPS
fps = 1 / (time.time() - start_time)
self.fps_history.append(fps)
avg_fps = sum(self.fps_history[-10:]) / min(10, len(self.fps_history))
# 显示FPS
cv2.putText(vis_frame, f"FPS: {avg_fps:.1f}",
(10, 30), cv2.FONT_HERSHEY_SIMPLEX, 1, (0,255,0), 2)
# 显示结果
cv2.imshow('Real-time Detection', vis_frame)
# 退出检查
if cv2.waitKey(1) & 0xFF == ord('q'):
break
# 释放资源
self.cap.release()
cv2.destroyAllWindows()
# 使用示例
processor = CameraProcessor('yolov8n.pt')
processor.run(conf=0.4)
3.3 批量视频处理方案
对于大量视频文件的自动化处理:
python复制import os
from concurrent.futures import ThreadPoolExecutor
class BatchVideoProcessor:
def __init__(self, model_name='yolov8n.pt'):
self.model = YOLO(model_name)
def process_single(self, input_path, output_dir, conf=0.3):
"""处理单个视频"""
# 创建输出路径
os.makedirs(output_dir, exist_ok=True)
filename = os.path.basename(input_path)
output_path = os.path.join(output_dir, f"processed_{filename}")
# 处理视频
cap = cv2.VideoCapture(input_path)
fps = cap.get(cv2.CAP_PROP_FPS)
width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
fourcc = cv2.VideoWriter_fourcc(*'mp4v')
out = cv2.VideoWriter(output_path, fourcc, fps, (width, height))
while True:
ret, frame = cap.read()
if not ret:
break
results = self.model(frame, conf=conf, verbose=False)
vis_frame = results[0].plot()
out.write(vis_frame)
cap.release()
out.release()
return output_path
def process_batch(self, input_dir, output_dir, max_workers=4):
"""批量处理目录中的所有视频"""
video_files = [os.path.join(input_dir, f)
for f in os.listdir(input_dir)
if f.endswith(('.mp4', '.avi', '.mov'))]
print(f"发现 {len(video_files)} 个视频文件,开始处理...")
with ThreadPoolExecutor(max_workers=max_workers) as executor:
futures = []
for video in video_files:
future = executor.submit(
self.process_single,
video,
output_dir
)
futures.append(future)
for future in futures:
try:
output_path = future.result()
print(f"完成处理: {output_path}")
except Exception as e:
print(f"处理失败: {str(e)}")
print("批量处理完成!")
# 使用示例
processor = BatchVideoProcessor('yolov8s.pt')
processor.process_batch('input_videos', 'output_videos', max_workers=4)
4. Results对象高级操作与自定义可视化
4.1 Results对象内部结构深度探索
Results对象的核心数据结构值得深入研究:
python复制# 深度分析Results对象
results = model.predict('demo.jpg')
result = results[0]
# 边界框分析
print(f"检测数量: {len(result.boxes)}")
print(f"坐标格式转换示例:")
print(f"XYXY格式: {result.boxes.xyxy[0]}")
print(f"XYWH格式: {result.boxes.xywh[0]}")
# 原始数据访问
print(f"原始数据矩阵形状: {result.boxes.data.shape}")
print(f"首行数据: {result.boxes.data[0]}")
# 性能分析
print(f"总耗时: {sum(result.speed.values()):.1f}ms")
print(f"各阶段耗时:")
for stage, t in result.speed.items():
print(f" {stage}: {t:.1f}ms")
# 图像信息
print(f"原始图像尺寸: {result.orig_shape}")
print(f"处理后尺寸: {result.shape}")
4.2 自定义可视化渲染器
实现完全自定义的渲染器:
python复制import cv2
from PIL import Image, ImageDraw, ImageFont
class CustomVisualizer:
def __init__(self, font_path=None):
self.font_path = font_path
self.colors = self._generate_colors(80)
def _generate_colors(self, n):
"""生成视觉区分度高的颜色"""
import colorsys
return [tuple(int(c*255) for c in colorsys.hsv_to_rgb(i/n, 1, 1))
for i in range(n)]
def draw_detections(self, image, boxes, names, conf_thresh=0.3):
"""自定义绘制函数"""
# 转换到PIL格式
pil_img = Image.fromarray(cv2.cvtColor(image, cv2.COLOR_BGR2RGB))
draw = ImageDraw.Draw(pil_img)
# 加载字体
try:
font = ImageFont.truetype(self.font_path or "arial.ttf", 16)
except:
font = ImageFont.load_default()
# 绘制每个检测框
for box in boxes:
if box.conf < conf_thresh:
continue
# 获取框信息
x1, y1, x2, y2 = map(int, box.xyxy[0])
cls = int(box.cls)
conf = float(box.conf)
label = f"{names[cls]} {conf:.2f}"
# 选择颜色
color = self.colors[cls % len(self.colors)]
# 绘制边界框
draw.rectangle([x1, y1, x2, y2], outline=color, width=3)
# 计算标签大小
text_width, text_height = draw.textsize(label, font=font)
# 绘制标签背景
draw.rectangle(
[x1, y1-text_height-5, x1+text_width+5, y1],
fill=color
)
# 绘制标签文本
draw.text(
(x1+3, y1-text_height-3),
label,
fill=(255,255,255),
font=font
)
# 转换回OpenCV格式
return cv2.cvtColor(np.array(pil_img), cv2.COLOR_RGB2BGR)
# 使用示例
visualizer = CustomVisualizer()
results = model.predict('sample.jpg')
for result in results:
custom_img = visualizer.draw_detections(
result.orig_img,
result.boxes,
result.names,
conf_thresh=0.4
)
cv2.imwrite('custom_visualization.jpg', custom_img)
4.3 动态可视化与交互式效果
实现带交互功能的可视化:
python复制import cv2
class InteractiveVisualizer:
def __init__(self, model):
self.model = model
self.current_conf = 0.3
self.show_labels = True
self.show_conf = True
def mouse_callback(self, event, x, y, flags, param):
"""鼠标回调函数"""
if event == cv2.EVENT_MOUSEWHEEL:
if flags > 0: # 滚轮上滚
self.current_conf = min(0.9, self.current_conf + 0.05)
else: # 滚轮下滚
self.current_conf = max(0.1, self.current_conf - 0.05)
def run(self, image_path):
"""运行交互式可视化"""
# 读取图像
image = cv2.imread(image_path)
cv2.namedWindow('Interactive Visualization')
cv2.setMouseCallback('Interactive Visualization', self.mouse_callback)
while True:
# 使用当前设置运行检测
results = self.model(image, conf=self.current_conf, verbose=False)
vis_image = results[0].plot(
labels=self.show_labels,
conf=self.show_conf
)
# 添加说明文本
help_text = [
f"Confidence: {self.current_conf:.2f}",
"Mouse Wheel: Adjust Confidence",
"L: Toggle Labels",
"C: Toggle Confidence",
"Q: Quit"
]
for i, text in enumerate(help_text):
cv2.putText(vis_image, text,
(10, 30 + i*30),
cv2.FONT_HERSHEY_SIMPLEX,
0.7, (0,255,0), 2)
# 显示图像
cv2.imshow('Interactive Visualization', vis_image)
# 处理按键
key = cv2.waitKey(1) & 0xFF
if key == ord('q'):
break
elif key == ord('l'):
self.show_labels = not self.show_labels
elif key == ord('c'):
self.show_conf = not self.show_conf
cv2.destroyAllWindows()
# 使用示例
model = YOLO('yolov8n.pt')
visualizer = InteractiveVisualizer(model)
visualizer.run('interactive_demo.jpg')
5. 高级可视化应用场景与实战案例
5.1 多模型结果融合可视化
比较不同模型的结果:
python复制def compare_models(image_path, model_names=['yolov8n.pt', 'yolov8s.pt', 'yolov8m.pt']):
"""多模型结果比较可视化"""
# 加载图像
image = cv2.imread(image_path)
orig_h, orig_w = image.shape[:2]
canvas = np.zeros((orig_h, orig_w*len(model_names), 3), dtype=np.uint8)
# 运行每个模型
for i, model_name in enumerate(model_names):
model = YOLO(model_name)
results = model(image, conf=0.3, verbose=False)
vis = results[0].plot(line_width=2, font_size=0.6)
# 添加到画布
canvas[:, i*orig_w:(i+1)*orig_w] = vis
# 添加模型名称
cv2.putText(canvas, model_name,
(i*orig_w + 10, 30),
cv2.FONT_HERSHEY_SIMPLEX,
1, (0,255,0), 2)
# 保存和显示
cv2.imwrite('model_comparison.jpg', canvas)
cv2.imshow('Model Comparison', canvas)
cv2.waitKey(0)
cv2.destroyAllWindows()
# 使用示例
compare_models('comparison_sample.jpg')
5.2 实时性能监控可视化
python复制class PerformanceMonitor:
def __init__(self, model_name='yolov8n.pt'):
self.model = YOLO(model_name)
self.timings = {
'preprocess': [],
'inference': [],
'postprocess': []
}
def run(self, image_path, iterations=100):
"""运行性能测试"""
print(f"开始性能测试,迭代次数: {iterations}")
for i in range(iterations):
results = self.model(image_path, verbose=False)
result = results[0]
# 记录时间
for stage in self.timings.keys():
self.timings[stage].append(result.speed[stage])
# 打印进度
if (i+1) % 10 == 0:
print(f"已完成 {i+1}/{iterations} 次迭代")
# 分析结果
self.analyze()
def analyze(self):
"""分析性能数据"""
import matplotlib.pyplot as plt
# 计算统计量
stats = {}
for stage, times in self.timings.items():
stats[stage] = {
'mean': np.mean(times),
'std': np.std(times),
'min': np.min(times),
'max': np.max(times)
}
# 打印结果
print("\n性能统计:")
for stage, data in stats.items():
print(f"{stage}:")
print(f" 平均: {data['mean']:.2f}ms")
print(f" 标准差: {data['std']:.2f}ms")
print(f" 范围: {data['min']:.2f}-{data['max']:.2f}ms")
# 绘制图表
fig, ax = plt.subplots(figsize=(10, 6))
labels = list(self.timings.keys())
means = [stats[s]['mean'] for s in labels]
stds = [stats[s]['std'] for s in labels]
ax.bar(labels, means, yerr=stds, capsize=5)
ax.set_title('YOLOv8 各阶段处理时间')
ax.set_ylabel('时间 (ms)')
plt.savefig('performance_analysis.png')
print("性能分析图表已保存为 performance_analysis.png")
# 使用示例
monitor = PerformanceMonitor('yolov8s.pt')
monitor.run('test_image.jpg', iterations=50)
5.3 数据增强效果可视化
python复制def visualize_augmentations(model_name='yolov8n.pt', image_path='demo.jpg', n_samples=5):
"""数据增强效果可视化"""
model = YOLO(model_name)
# 创建画布
image = cv2.imread(image_path)
h, w = image.shape[:2]
canvas = np.zeros((h*n_samples, w, 3), dtype=np.uint8)
# 生成并显示不同增强效果
for i in range(n_samples):
# 使用不同的增强参数
results = model.predict(
image,
augment=True, # 启用增强
degrees=10*i, # 旋转角度递增
translate=0.1*i, # 平移比例递增
scale=0.1 + 0.05*i, # 缩放比例递增
shear=2*i, # 剪切角度递增
flipud=0.5, # 上下翻转概率
fliplr=0.5, # 左右翻转概率
mosaic=False, # 禁用mosaic(单图处理)
verbose=False
)
# 获取增强后的图像
aug_img = results[0].plot(line_width=2, font_size=0.6)
# 添加到画布
canvas[i*h:(i+1)*h, :] = aug_img
# 添加说明文本
cv2.putText(canvas, f"Augmentation {i+1}",
(10, i*h + 30),
cv2.FONT_HERSHEY_SIMPLEX,
0.7, (0,255,0), 2)
# 保存和显示
cv2.imwrite('augmentation_effects.jpg', canvas)
cv2.imshow('Augmentation Effects', canvas)
cv2.waitKey(0)
cv2.destroyAllWindows()
# 使用示例
visualize_augmentations('yolov8n.pt', 'aug_sample.jpg', n_samples=4)
6. 可视化结果导出与部署方案
6.1 多格式结果导出实战
python复制def export_results(results, base_name='result', output_dir='exports'):
"""导出多种格式的结果"""
os.makedirs(output_dir, exist_ok=True)
for i, result in enumerate(results):
# 1. 导出图像
cv2.imwrite(f"{output_dir}/{base_name}_{i}.jpg", result.plot())
# 2. 导出JSON
import json
json_data = {
'boxes': result.boxes.data.tolist(),
'names': result.names,
'shape': result.orig_shape,
'speed': result.speed
}
with open(f"{output_dir}/{base_name}_{i}.json", 'w') as f:
json.dump(json_data, f, indent=2)
# 3. 导出YOLO格式文本
with open(f"{output_dir}/{base_name}_{i}.txt", 'w') as f:
for box in result.boxes:
cls = int(box.cls)
conf = float(box.conf)
x, y, w, h = box.xywh[0].tolist()
f.write(f"{cls} {x} {y} {w} {h} {conf}\n")
# 4. 导出裁剪的目标图像
os.makedirs(f"{output_dir}/crops", exist_ok=True)
for j, box in enumerate(result.boxes):
x1, y1, x2, y2 = map(int, box.xyxy[0])
crop = result.orig_img[y1:y2, x1:x2]
if crop.size > 0: # 确保裁剪区域有效
cv2.imwrite(
f"{output_dir}/crops/{base_name}_{i}_{j}.jpg",
crop
)
print(f"结果已导出到 {output_dir} 目录")
# 使用示例
results = model.predict('export_sample.jpg')
export_results(results, 'sample_export')
6.2 Web端可视化部署方案
使用Flask创建简单的Web接口:
python复制from flask import Flask, request, Response
import cv2
import numpy as np
from io import BytesIO
app = Flask(__name__)
model = YOLO('yolov8n.pt')
@app.route('/detect', methods=['POST'])
def detect():
"""处理图像检测请求"""
# 获取上传的图像
if 'image' not in request.files:
return "No image uploaded", 400
file = request.files['image']
img_bytes = file.read()
img_array = np.frombuffer(img_bytes, np.uint8)
img = cv2.imdecode(img_array, cv2.IMREAD_COLOR)
# 运行检测
results = model(img, verbose=False)
vis_img = results[0].plot()
# 编码为JPEG返回
_, buffer = cv2.imencode('.jpg', vis_img)
response = BytesIO(buffer)
return Response(
response.getvalue(),
mimetype='image/jpeg'
)
if __name__ == '__main__':
app.run(host='0.0.0.0', port=5000)