☰
用码道做一个 YOLO 目标检测平台:从“这是什么”到“它在哪里”
2026/10/10 2:46:38 网站建设 项目流程

项目地址:
yolo-object-detection-lab:基于 FastAPI 与 Ultralytics YOLO 的图像目标检测实验项目 - AtomGit

前面几篇文章里,我一直围绕 MNIST 做图像分类实验,从 CNN、Feature Map、CNN vs MLP,一直做到 ResNet + Grad-CAM。

但图像分类解决的问题始终是:

“这张图片是什么?”

这一次我想继续往前走一步,开始做目标检测。

目标检测不仅需要判断图片里有什么,还需要回答:

“目标在哪里?”

所以这次我继续使用码道 Agent,从零搭建了一个基于Ultralytics YOLO + FastAPI的目标检测 Web 实验平台。

最终效果可以直接上传图片,并得到:

  • 检测类别
  • 置信度
  • Bounding Box
  • 检测目标数量
  • 检测结果图
  • 每个目标的详细检测信息

一、从 Image Classification 到 Object Detection

前面的 CNN、ResNet 都属于图像分类任务。

比如输入一张手写数字:

Input Image ↓ CNN / ResNet ↓ Class = 8

模型只需要告诉我们:

这张图是什么?

但 YOLO 做的是 Object Detection。

它的输出更像:

Input Image ↓ YOLO ↓ Dog 93.2% [x1, y1, x2, y2] Person 80.4% [x1, y1, x2, y2] Backpack 83.9% [x1, y1, x2, y2] ...

不仅知道是什么,还能给出目标的位置。

因此这次我单独创建了一个新项目:

yolo-object-detection-lab

而没有继续往之前的 MNIST 项目里塞功能。


二、项目整体结构

这次后端使用:

Python FastAPI Ultralytics YOLO OpenCV Pillow

前端仍然保持比较轻量:

HTML CSS JavaScript

检测流程大致是:

用户上传图片 ↓ FastAPI ↓ 图片解析与校验 ↓ YOLO11 ↓ 目标检测 ↓ 解析 Bounding Box ↓ 绘制检测框 ↓ 返回 Base64 图片 + Detection List ↓ 浏览器可视化

前端本身不生成任何假框。

页面中看到的类别、置信度和 Bounding Box 全部来自后端真实 YOLO 推理结果。


三、使用 YOLO11n

这次使用的模型是:

yolo11n.pt

其中n对应 Nano 版本。

对于一个目标检测实验平台来说,它体积比较小,推理速度也比较快,很适合先把完整流程跑通。

本地环境中使用:

PyTorch 2.14.0+cu130 Ultralytics 8.4.165 NVIDIA GeForce RTX 4090 CUDA Available = True

一开始启动项目以后,我发现页面中的模型信息显示:

Device: cpu

也就是说,虽然机器有 RTX 4090,但项目默认实际上还在使用 CPU。

于是启动服务时指定:

YOLO_DEVICE=0 python -m uvicorn app.main:app --reload

再次查看模型状态:

{ "model_name": "yolo11n.pt", "device": "0", "model_loaded": true, "class_count": 80 }

这时才真正切换到 GPU。


四、先做真实测试,而不是直接相信页面

Agent 完成项目以后,我首先运行了完整 pytest:

pytest -v

最终结果:

34 passed, 1 warning in 0.91s

34 个测试覆盖了:

  • API 状态
  • 模型信息
  • 无文件上传
  • 空文件
  • 非图片
  • 损坏图片
  • 文件过大
  • 权重缺失
  • 推理异常
  • Bounding Box 格式
  • Confidence 范围
  • Detection Schema
  • 图片绘制
  • Base64 编码

不过这里需要注意:

部分 YOLO 推理测试使用的是 Mock。

所以 pytest 全通过以后,我又单独进行了真实模型推理。

直接加载:

model = YOLO("yolo11n.pt")

然后指定:

device=0

真实推理中,模型本身的 inference 时间大约只有:

9.7 ms

说明 CUDA 和 YOLO 模型都已经正常工作。


五、真实多目标检测效果

为了测试多目标场景,我准备了一张同时包含多种常见物体的测试图片。

图片中包含:

  • 人
  • 狗
  • 背包
  • 植物
  • 笔记本电脑
  • 杯子
  • 椅子
  • 床 / 沙发区域
  • 书籍等目标

上传以后点击:

Start Detection

YOLO 最终检测到了:

16 个目标

图片尺寸为:

1634 × 962

这次检测结果中比较明显的几个目标包括:

ClassConfidence
Dog93.2%
Potted Plant86.5%
Backpack83.9%
Person80.4%

比如 Dog 对应的检测结果:

Class: Dog Confidence: 93.2% BBox: [182, 410, 642, 934]

Backpack:

Class: Backpack Confidence: 83.9% BBox: [1205, 584, 1584, 962]

Person:

Class: Person Confidence: 80.4% BBox: [726, 47, 1175, 924]

也就是说,现在平台已经不再只是输出一个类别,而是能够真正返回:

Class + Confidence + Bounding Box

六、Bounding Box 到底是什么?

目标检测里的 Bounding Box 本质上就是一个矩形框。

当前接口返回:

x1 y1 x2 y2

分别表示:

(x1, y1) 左上角 (x2, y2) 右下角

例如:

BBox: [182, 410, 642, 934]

可以理解为:

左上角 = (182, 410) 右下角 = (642, 934)

然后 OpenCV 根据这些坐标在原始图片上绘制矩形。

因此最终页面中看到的框,并不是前端根据图片尺寸“猜”的,而是 YOLO 模型真实预测出来的位置。


七、这次还遇到了一个很有意思的前端 Bug

第一次真实上传图片以后,页面出现了一个现象:

YOLO 一直在转圈。

页面始终停留在:

Running YOLO inference...

一开始我还以为是:

YOLO 太慢 GPU 没工作 模型加载卡住

但继续排查以后发现,后端其实完全正常。

我直接绕开网页调用:

curl -F "file=@/tmp/yolo_test.jpg" \ http://127.0.0.1:8000/api/detect

结果大约 4 秒就正常返回:

image: 640 x 640 detection_count: 0 detections: [] result_image exists: True

这就说明:

YOLO 后端早就跑完了,只是前端 Loading 没消失。

最后定位到了 CSS。

JavaScript 中实际上已经正确执行:

function hideOverlay() { dom.overlay.hidden = true; }

而且finally也会执行:

finally { hideOverlay(); busy = false; dom.detectBtn.disabled = false; }

真正的问题是.overlay的 CSS 显示规则覆盖了 HTML 的hidden属性。

最终只需要补充:

[hidden] { display: none !important; }

问题就解决了。

这个 Bug 其实挺典型:

后端没有卡,模型没有卡,真正卡住的是 UI 状态。


八、现在这个平台已经实现了什么?

目前项目已经能够完成:

图片上传 Drag & Drop 原图预览 YOLO11 模型加载 GPU 推理 Confidence Threshold IoU Threshold 多目标检测 类别识别 置信度显示 Bounding Box 绘制 检测数量统计 图片尺寸统计 Detection List 异常处理 FastAPI API pytest 测试

模型信息也能直接显示:

Model: yolo11n.pt Device: 0 Confidence: 0.25 IoU: 0.70 Loaded: yes Classes: 80

对于一个从零开始搭建的 YOLO 实验平台来说,第一阶段的基本功能已经完整跑通。


九、从 CNN 到 YOLO,任务发生了什么变化?

做到这里以后,之前几篇文章的路线就比较清晰了。

最开始:

CNN ↓ 这张图片是什么?

然后:

Feature Map ↓ 卷积层提取了什么?

再到:

ResNet + Grad-CAM ↓ 当前类别主要响应在哪里?

而现在进入:

YOLO ↓ 图片里有什么? 它们分别在哪里?

这实际上就是从:

Image Classification

正式进入:

Object Detection


总结

这一次我使用码道 Agent 从零完成了一个 YOLO Object Detection Lab。

最终真实运行结果包括:

Model: YOLO11n GPU: RTX 4090 Classes: 80 pytest: 34 passed Multi-object Test: 16 detected objects Dog: 93.2% Potted Plant: 86.5% Backpack: 83.9% Person: 80.4%

同时开发过程中还真实遇到了:

CPU / GPU 配置问题 ↓ 真实 YOLO 推理验证 ↓ API 独立测试 ↓ Loading 一直不消失 ↓ 定位 hidden CSS 问题 ↓ 完成修复

所以这一篇对我来说也不只是“调用了一次 YOLO”。

而是把:

模型 → 后端 → API → 前端 → 测试 → GPU → 可视化

整个目标检测流程真正串起来了。

项目地址:

yolo-object-detection-lab:基于 FastAPI 与 Ultralytics YOLO 的图像目标检测实验项目 - AtomGit

下一步可以继续在这个项目上加入:

Confidence / Class Filter、摄像头实时检测、视频检测以及自定义数据集训练。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询