mcpField
C
computer-vision-pipeline

computer-vision-pipeline

github.com/curiositech开发257271 次安装2 天前更新
代码仓库

关于 computer-vision-pipeline

computer-vision-pipeline 是用于构建计算机视觉系统的技能,面向目标检测、视频分析和多目标跟踪任务。它涵盖帧预处理、采样、批量推理、模型微调及跟踪实践。

主要功能

  1. 01指导选择目标检测模型
  2. 02提供视频帧预处理与抽样方法
  3. 03说明批量推理和 NMS 参数调整
  4. 04涵盖 ByteTrack 等多目标跟踪
  5. 05提供 YOLO 模型微调与视频分析脚本

适用场景

  1. 01分析无人机或野生动物视频
  2. 02构建实时目标检测流程
  3. 03跟踪视频中的多个对象
  4. 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.json
references/
yolo-guide.md
video-processing.md
tracking-algorithms.md
scripts/
model_trainer.py
video_analyzer.py

详细介绍

计算机视觉流水线

擅长构建适用于生产环境的计算机视觉系统,用于目标检测、跟踪和视频分析。

适用场景

✅ 适用于:

  • 无人机影像分析(考古调查、保护工作)
  • 野生动物监测与跟踪
  • 实时目标检测系统
  • 视频预处理与分析
  • 自定义模型训练与推理
  • 多目标跟踪(MOT)

❌ 不适用于:

  • 简单的图像滤镜(使用 Pillow/PIL)
  • 照片编辑(使用 Photoshop/GIMP)
  • 人脸识别 API(使用 AWS Rekognition)
  • 基础 OCR(使用 Tesseract)

技术选型

目标检测模型
模型速度(FPS)准确率(mAP)使用场景
YOLOv814053.9%实时检测
Detectron22558.7%高准确率、研究
EfficientDet3555.1%移动端部署
Faster R-CNN1042.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 利用率吞吐量
顺序处理45s20%2.2 img/s
批量处理(16)8s85%12.5 img/s
批量处理(32)6s92%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 参数指南:

使用场景IoUConf最大检测数
稀疏目标(野生动物)0.50.4100
密集目标(人群)0.30.5300
高精度(证据)0.50.750
实时(速度优先)0.450.3100

反模式 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