关于 computer-vision-pipeline
computer-vision-pipeline 是用于构建计算机视觉系统的技能,面向目标检测、视频分析和多目标跟踪任务。它涵盖帧预处理、采样、批量推理、模型微调及跟踪实践。
主要功能
- 01指导选择目标检测模型
- 02提供视频帧预处理与抽样方法
- 03说明批量推理和 NMS 参数调整
- 04涵盖 ByteTrack 等多目标跟踪
- 05提供 YOLO 模型微调与视频分析脚本
适用场景
- 01分析无人机或野生动物视频
- 02构建实时目标检测流程
- 03跟踪视频中的多个对象
- 04使用自定义数据集微调 YOLO
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ curiositech/ some_claude_skills --skill computer-vision-pipeline安装后在 Claude Code 中输入/computer-vision-pipeline确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
.claude-plugin/plugin.jsonreferences/yolo-guide.mdvideo-processing.mdtracking-algorithms.mdscripts/model_trainer.pyvideo_analyzer.py详细介绍
计算机视觉流水线
擅长构建适用于生产环境的计算机视觉系统,用于目标检测、跟踪和视频分析。
适用场景
✅ 适用于:
- 无人机影像分析(考古调查、保护工作)
- 野生动物监测与跟踪
- 实时目标检测系统
- 视频预处理与分析
- 自定义模型训练与推理
- 多目标跟踪(MOT)
❌ 不适用于:
- 简单的图像滤镜(使用 Pillow/PIL)
- 照片编辑(使用 Photoshop/GIMP)
- 人脸识别 API(使用 AWS Rekognition)
- 基础 OCR(使用 Tesseract)
技术选型
目标检测模型
| 模型 | 速度(FPS) | 准确率(mAP) | 使用场景 |
|---|---|---|---|
| YOLOv8 | 140 | 53.9% | 实时检测 |
| Detectron2 | 25 | 58.7% | 高准确率、研究 |
| EfficientDet | 35 | 55.1% | 移动端部署 |
| Faster R-CNN | 10 | 42.0% | 旧有系统 |
时间线:
- 2015:Faster R-CNN(两阶段检测)
- 2016:YOLO v1(单阶段、实时)
- 2020:YOLOv5(PyTorch,适用于生产环境)
- 2023:YOLOv8(最先进技术)
- 2024:YOLOv8 成为实时检测的行业标准
决策树:
Need real-time (>30 FPS)? → YOLOv8
Need highest accuracy? → Detectron2 Mask R-CNN
Need mobile deployment? → YOLOv8-nano or EfficientDet
Need instance segmentation? → Detectron2 or YOLOv8-seg
Need custom objects? → Fine-tune YOLOv8
常见反模式
反模式 1:检测前不预处理视频帧
新手想法:“直接对原始视频帧运行检测”
问题:检测准确率低,浪费 GPU 资源。
错误做法:
# ❌ No preprocessing - poor results
import cv2
from ultralytics import YOLO
model = YOLO('yolov8n.pt')
video = cv2.VideoCapture('drone_footage.mp4')
while True:
ret, frame = video.read()
if not ret:
break
# Raw frame detection - no normalization, no resizing
results = model(frame)
# Poor accuracy, slow inference
错误原因:
- 视频分辨率过高(4K = 每帧 830 万像素)
- 未进行归一化(像素值为 0-255,而非 0-1)
- 未保持纵横比
- 高分辨率帧会导致 GPU 内存溢出
正确做法:
# ✅ Proper preprocessing pipeline
import cv2
import numpy as np
from ultralytics import YOLO
model = YOLO('yolov8n.pt')
video = cv2.VideoCapture('drone_footage.mp4')
# Model expects 640x640 input
TARGET_SIZE = 640
def preprocess_frame(frame):
# Resize while maintaining aspect ratio
h, w = frame.shape[:2]
scale = TARGET_SIZE / max(h, w)
new_w, new_h = int(w * scale), int(h * scale)
resized = cv2.resize(frame, (new_w, new_h), interpolation=cv2.INTER_LINEAR)
# Pad to square
pad_w = (TARGET_SIZE - new_w) // 2
pad_h = (TARGET_SIZE - new_h) // 2
padded = cv2.copyMakeBorder(
resized,
pad_h, TARGET_SIZE - new_h - pad_h,
pad_w, TARGET_SIZE - new_w - pad_w,
cv2.BORDER_CONSTANT,
value=(114, 114, 114) # Gray padding
)
# Normalize to 0-1 (if model expects it)
# normalized = padded.astype(np.float32) / 255.0
return padded, scale
while True:
ret, frame = video.read()
if not ret:
break
preprocessed, scale = preprocess_frame(frame)
results = model(preprocessed)
# Scale bounding boxes back to original coordinates
for box in results[0].boxes:
x1, y1, x2, y2 = box.xyxy[0]
x1, y1, x2, y2 = x1/scale, y1/scale, x2/scale, y2/scale
性能对比:
- 原始 4K 帧:5 FPS,72% mAP
- 预处理为 640x640:45 FPS,89% mAP
时间线背景:
- 2015:需要手动预处理
- 2020:YOLOv5 加入自动调整大小功能
- 2023:YOLOv8 具备智能预处理功能,但显式控制效果更好
反模式 2:处理视频中的每一帧
新手想法:“对每一帧都运行检测”
问题:99% 的帧都是冗余的,浪费计算资源。
错误做法:
# ❌ Process every frame (30 FPS video = 1800 frames/min)
import cv2
from ultralytics import YOLO
model = YOLO('yolov8n.pt')
video = cv2.VideoCapture('drone_footage.mp4')
detections = []
while True:
ret, frame = video.read()
if not ret:
break
# Run detection on EVERY frame
results = model(frame)
detections.append(results)
# 10-minute video = 18,000 inferences (15 minutes on GPU)
错误原因:
- 相邻帧几乎完全相同
- 将 95% 的计算资源浪费在重复工作上
- 处理速度慢
- 结果占用大量存储空间
正确做法 1:帧采样
# ✅ Sample every Nth frame
import cv2
from ultralytics import YOLO
model = YOLO('yolov8n.pt')
video = cv2.VideoCapture('drone_footage.mp4')
SAMPLE_RATE = 30 # Process 1 frame per second (if 30 FPS video)
frame_count = 0
detections = []
while True:
ret, frame = video.read()
if not ret:
break
frame_count += 1
# Only process every 30th frame
if frame_count % SAMPLE_RATE == 0:
results = model(frame)
detections.append({
'frame': frame_count,
'timestamp': frame_count / 30.0,
'results': results
})
# 10-minute video = 600 inferences (30 seconds on GPU)
正确做法 2:结合场景变化检测的自适应采样
# ✅ Only process when scene changes significantly
import cv2
import numpy as np
from ultralytics import YOLO
model = YOLO('yolov8n.pt')
video = cv2.VideoCapture('drone_footage.mp4')
def scene_changed(prev_frame, curr_frame, threshold=0.3):
"""Detect scene change using histogram comparison"""
if prev_frame is None:
return True
# Convert to grayscale
prev_gray = cv2.cvtColor(prev_frame, cv2.COLOR_BGR2GRAY)
curr_gray = cv2.cvtColor(curr_frame, cv2.COLOR_BGR2GRAY)
# Calculate histograms
prev_hist = cv2.calcHist([prev_gray], [0], None, [256], [0, 256])
curr_hist = cv2.calcHist([curr_gray], [0], None, [256], [0, 256])
# Compare histograms
correlation = cv2.compareHist(prev_hist, curr_hist, cv2.HISTCMP_CORREL)
return correlation < (1 - threshold)
prev_frame = None
detections = []
while True:
ret, frame = video.read()
if not ret:
break
# Only run detection if scene changed
if scene_changed(prev_frame, frame):
results = model(frame)
detections.append(results)
prev_frame = frame.copy()
# Adapts to video content - static shots skip frames, action scenes process more
节省情况:
- 处理每一帧:18,000 次推理
- 以 1 FPS 采样:600 次推理(减少 97%)
- 自适应采样:约 1,200 次推理(减少 93%)
反模式 3:不使用批量推理
新手想法:“一次处理一张图像”
问题:GPU 有 80% 的时间因等待数据而闲置。
错误做法:
# ❌ Sequential processing - GPU underutilized
import cv2
from ultralytics import YOLO
import time
model = YOLO('yolov8n.pt')
# 100 images to process
image_paths = [f'frame_{i:04d}.jpg' for i in range(100)]
start = time.time()
for path in image_paths:
frame = cv2.imread(path)
results = model(frame) # Process one at a time
# GPU utilization: ~20%
elapsed = time.time() - start
print(f"Processed {len(image_paths)} images in {elapsed:.2f}s")
# Output: 45 seconds
错误原因:
- GPU 必须等待 CPU 加载每张图像
- 没有并行处理
- GPU 利用率约为 20%
- 吞吐量低
正确做法:
# ✅ Batch inference - GPU fully utilized
import cv2
from ultralytics import YOLO
import time
model = YOLO('yolov8n.pt')
image_paths = [f'frame_{i:04d}.jpg' for i in range(100)]
BATCH_SIZE = 16 # Process 16 images at once
start = time.time()
for i in range(0, len(image_paths), BATCH_SIZE):
batch_paths = image_paths[i:i+BATCH_SIZE]
# Load batch
frames = [cv2.imread(path) for path in batch_paths]
# Batch inference (single GPU call)
results = model(frames) # Pass list of images
# GPU utilization: ~85%
elapsed = time.time() - start
print(f"Processed {len(image_paths)} images in {elapsed:.2f}s")
# Output: 8 seconds (5.6x faster!)
性能对比:
| 方法 | 耗时(100 张图像) | GPU 利用率 | 吞吐量 |
|---|---|---|---|
| 顺序处理 | 45s | 20% | 2.2 img/s |
| 批量处理(16) | 8s | 85% | 12.5 img/s |
| 批量处理(32) | 6s | 92% | 16.7 img/s |
批量大小调优:
# Find optimal batch size for your GPU
import torch
def find_optimal_batch_size(model, image_size=(640, 640)):
for batch_size in [1, 2, 4, 8, 16, 32, 64]:
try:
dummy_input = torch.randn(batch_size, 3, *image_size).cuda()
start = time.time()
with torch.no_grad():
_ = model(dummy_input)
elapsed = time.time() - start
throughput = batch_size / elapsed
print(f"Batch {batch_size}: {throughput:.1f} img/s")
except RuntimeError as e:
print(f"Batch {batch_size}: OOM (out of memory)")
break
# Find optimal batch size before production
find_optimal_batch_size(model)
反模式 4:忽略非极大值抑制(NMS)调优
问题:检测结果重复、漏检目标、后处理速度慢。
错误做法:
# ❌ Use default NMS settings for everything
from ultralytics import YOLO
model = YOLO('yolov8n.pt')
# Default settings (iou_threshold=0.45, conf_threshold=0.25)
results = model('crowded_scene.jpg')
# Result: 50 bounding boxes, 30 are duplicates!
错误原因:
- 对密集目标而言,默认的 IoU=0.45 过于宽松
- 默认的 conf=0.25 会纳入低质量检测结果
- 未针对使用场景进行调整
正确做法:
# ✅ Tune NMS for your use case
from ultralytics import YOLO
model = YOLO('yolov8n.pt')
# Sparse objects (dolphins in ocean)
sparse_results = model(
'ocean_footage.jpg',
iou=0.5, # Higher IoU = allow closer boxes
conf=0.4 # Higher confidence = fewer false positives
)
# Dense objects (crowd, flock of birds)
dense_results = model(
'crowded_scene.jpg',
iou=0.3, # Lower IoU = suppress more duplicates
conf=0.5 # Higher confidence = filter noise
)
# High precision needed (legal evidence)
precise_results = model(
'evidence.jpg',
iou=0.5,
conf=0.7, # Very high confidence
max_det=50 # Limit max detections
)
NMS 参数指南:
| 使用场景 | IoU | Conf | 最大检测数 |
|---|---|---|---|
| 稀疏目标(野生动物) | 0.5 | 0.4 | 100 |
| 密集目标(人群) | 0.3 | 0.5 | 300 |
| 高精度(证据) | 0.5 | 0.7 | 50 |
| 实时(速度优先) | 0.45 | 0.3 | 100 |
反模式 5:未在帧之间进行跟踪
新手思维:“对每一帧分别运行检测”
问题:无法统计唯一对象、跟踪移动或构建轨迹。
错误做法:
# ❌ Independent frame detection - no object identity
from ultralytics import YOLO
import cv2
model = YOLO('yolov8n.pt')
video = cv2.VideoCapture('dolphins.mp4')
detections = []
while True:
ret, frame = video.read()
if not ret:
break
results = model(frame)
detections.append(results)
# Result: Can't tell if frame 10 dolphin is same as frame 20 dolphin
# Can't count unique dolphins
# Can't track trajectories
错误原因:
- 无法在不同帧之间保持对象身份
- 无法统计唯一对象
- 无法分析移动模式
- 无法构建轨迹
正确做法:使用跟踪(ByteTrack)
# ✅ Multi-object tracking with ByteTrack
from ultralytics import YOLO
import cv2
# YOLO with tracking
model = YOLO('yolov8n.pt')
video = cv2.VideoCapture('dolphins.mp4')
# Track objects across frames
tracks = {}
while True:
ret, frame = video.read()
if not ret:
break
# Run detection + tracking
results = model.track(
frame,
persist=True, # Maintain IDs across frames
tracker='bytetrack.yaml' # ByteTrack algorithm
)
# Each detection now has persistent ID
for box in results[0].boxes:
track_id = int(box.id[0]) # Unique ID across frames
x1, y1, x2, y2 = box.xyxy[0]
# Store trajectory
if track_id not in tracks:
tracks[track_id] = []
tracks[track_id].append({
'frame': len(tracks[track_id]),
'bbox': (x1, y1, x2, y2),
'conf': box.conf[0]
})
# Now we can analyze:
print(f"Unique dolphins detected: {len(tracks)}")
# Trajectory analysis
for track_id, trajectory in tracks.items():
if len(trajectory) > 30: # Only long tracks
print(f"Dolphin {track_id} appeared in {len(trajectory)} frames")
# Calculate movement, speed, etc.
跟踪的优势:
- 统计唯一对象(而非仅统计每帧的检测结果)
- 构建轨迹和移动模式
- 分析对象随时间的行为
- 过滤短暂的误报
跟踪算法:
| 算法 | 速度 | 稳健性 | 遮挡处理能力 |
|---|---|---|---|
| ByteTrack | 快 | 良好 | 出色 |
| SORT | 非常快 | 一般 | 一般 |
| DeepSORT | 中等 | 出色 | 良好 |
| BotSORT | 中等 | 出色 | 出色 |
生产环境检查清单
□ Preprocess frames (resize, pad, normalize)
□ Sample frames intelligently (1 FPS or scene change detection)
□ Use batch inference (16-32 images per batch)
□ Tune NMS thresholds for your use case
□ Implement tracking if analyzing video
□ Log inference time and GPU utilization
□ Handle edge cases (empty frames, corrupted video)
□ Save results in structured format (JSON, CSV)
□ Visualize detections for debugging
□ Benchmark on representative data
适用与不适用场景
| 场景 | 是否适用? |
|---|---|
| 分析用于考古的无人机影像 | ✅ 是 - 自定义对象检测 |
| 跟踪视频中的野生动物 | ✅ 是 - 检测 + 跟踪 |
| 统计人群中的人数 | ✅ 是 - 密集对象检测 |
| 实时安防摄像头 | ✅ 是 - YOLOv8 实时检测 |
| 筛选度假照片 | ❌ 否 - 使用照片管理应用 |
| 人脸识别登录 | ❌ 否 - 使用 AWS Rekognition API |
| 读取车牌 | ❌ 否 - 使用专用 OCR |
参考资料
/references/yolo-guide.md- YOLOv8 设置、训练、推理模式/references/video-processing.md- 帧提取、场景检测、优化/references/tracking-algorithms.md- ByteTrack、SORT、DeepSORT 对比
脚本
scripts/video_analyzer.py- 提取帧、运行检测、生成时间线scripts/model_trainer.py- 在自定义数据集上微调 YOLO,导出权重
此技能适用于:计算机视觉 | 对象检测 | 视频分析 | YOLO | 跟踪 | 无人机影像 | 野生动物监测
评论
支持 Markdown