引言
在现代 AI 应用开发中,将机器学习模型封装成易于调用的 API 服务是一种常见的模式。这使得模型可以被不同的前端应用、后端服务或其他系统轻松集成。本教程将指导您如何使用 FastAPI 框架,将 YOLO(You Only Look Once)目标检测模型部署为一个高效的行人检测 API 服务。该服务将接收 Base64 编码的图片,进行推理,并返回检测到的行人数量。
技术栈
后端框架: FastAPI
目标检测模型: YOLOv8/v11 (通过 ultralytics 库加载)
图像处理: OpenCV (cv2)
图像编解码: NumPy (np)
API 服务器: Uvicorn
API 规范: Swagger UI (FastAPI 自带)
部署环境与目标
操作系统: Windows, Linux, macOS (理论上均可)
Python 版本: 3.11.7
部署形态: 本地运行的 HTTP API 服务
输入: JSON 格式请求体,包含 Base64 编码的图片字符串
输出: JSON 格式响应体,包含检测到的行人数量 (person) 和可能的错误信息 (error)
安装必备包:
python
pip install fastapi uvicorn ultralytics opencv-python numpy
fastapi: 用于创建 API。
uvicorn: ASGI 服务器,用于运行 FastAPI 应用。
ultralytics: 用于加载和运行 YOLO 模型。
opencv-python: 用于图像解码。
numpy: 用于数组操作。
第二步:编写 API 服务代码,并启动
person_fastapi.py
python
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
import cv2
import numpy as np
import base64
from ultralytics import YOLO
import uvicorn
# 初始化 FastAPI
app = FastAPI(title="Sinoma Person Detection Service")
# 全局加载模型 (建议使用最新 yolo11n.pt,比 v8n 更快更准)
# 第一次运行会自动下载
model = YOLO("yolo11n.pt")
class ImageRequest(BaseModel):
image: str # 接收 Base64 编码的字符串
@app.post("/detect/person")
async def detect_person(request: ImageRequest):
try:
# 1. Base64 转 OpenCV 图像
img_data = base64.b64decode(request.image)
nparr = np.frombuffer(img_data, np.uint8)
img = cv2.imdecode(nparr, cv2.COLOR_BGR2RGB)
if img is None:
raise ValueError("图片解码失败")
# 2. 高性能推理
# classes=[0] 只检测行人
# conf=0.4 过滤低置信度
# iou=0.5 减少重叠框
# verbose=False 减少后台日志,提高性能
results = model.predict(source=img, classes=[0], conf=0.4, verbose=False)
# 3. 获取行人数量
person_count = len(results[0].boxes)
return {"person": person_count}
except Exception as e:
return {"person": 0, "error": str(e)}
if __name__ == "__main__":
# 启动服务,端口 8220 (避开你之前的 8210)
uvicorn.run(app, host="0.0.0.0", port=8220)
创建api_start.sh 脚本
python
# 生产环境启动(后台运行)
nohup uvicorn person_fastapi:app --host 0.0.0.0 --port 8220 --workers 1 --log-level warning > detect.log 2>&1 &
测试例子:
python
import cv2
from ultralytics import YOLO
def best_person_detection(image_path):
# 第一次运行会自动下载 yolov8n.pt,约 6MB
model = YOLO("yolov8n.pt")
# 执行推理
# classes=[0] 锁定检测目标为"人"
# conf=0.4 置信度,低于0.4的会被忽略,有效减少误报
results = model.predict(source=image_path, classes=[0], conf=0.4, verbose=False)
person_count = len(results[0].boxes)
print(f"检测完成,画面中共有 {person_count} 个人")
# 如果需要保存结果图查看
res_plotted = results[0].plot()
cv2.imwrite("yolo_best_result.jpg", res_plotted)
return person_count > 0
if __name__ == "__main__":
test_image = "frame_2026_01_23_14_20_25.jpg"
is_someone = best_person_detection(test_image)
print(f"结论:{'有人' if is_someone else '无人'}")
测试结果:
python
正在发送请求测试图片: frame_2026_01_23_14_20_25.jpg ...
--- 检测结果 ---
返回 JSON: {'person': 2}
检测到人数: 2
接口响应耗时: 0.083 秒
----------------
恭喜!您已经成功使用 FastAPI 部署了一个简单的行人检测 API 服务。该服务能够接收 Base64 编码的图片,利用 YOLO 模型进行行人计数,并返回结果。这个基础框架可以根据您的具体需求进行扩展,例如返回详细的检测框坐标、支持视频流、添加身份认证、记录日志等。