# AI智能视觉检测
**Repository Path**: get2bad/visual_ai
## Basic Information
- **Project Name**: AI智能视觉检测
- **Description**: 实时视频流 AI 检测服务
- **Primary Language**: Unknown
- **License**: GPL-2.0
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 0
- **Forks**: 0
- **Created**: 2025-12-17
- **Last Updated**: 2026-03-05
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
# lf_ai - 实时视频流 AI 检测服务
[](https://github.com/yourusername/lf_ai)
[](https://www.python.org/)
[](LICENSE)
> 实时视频流 AI 检测服务
> 支持多路视频流并发处理、RTSP/RTMP/HTTP-FLV/HLS 输入、GPU 加速推理、实时 RTMP 推流输出
---
## 目录
- [项目简介](#项目简介)
- [核心特性](#核心特性)
- [快速开始](#快速开始)
- [系统架构](#系统架构)
- [项目结构](#项目结构)
- [配置说明](#配置说明)
- [API 文档](#api-文档)
- [部署指南](#部署指南)
- [开发指南](#开发指南)
- [性能优化](#性能优化)
- [常见问题](#常见问题)
---
## 项目简介
**lf_ai** 是一个实时视频流 AI 检测服务。项目采用分层架构,支持多种检测场景(人车检测、火焰识别、安全帽检测、车牌识别等),可应用于安防监控、无人机巡检等领域。
### 技术栈
- **后端框架**: Flask + Gevent (异步服务)
- **AI 推理**: PyTorch + Ultralytics YOLO (支持 TensorRT 加速)
- **视频处理**: FFmpeg (多格式支持 + NVENC 硬件编码)
- **消息队列**: MQTT (异步告警推送)
- **并发模型**: 多进程 + 多线程 (规避 GIL,每路流独立进程)
### 应用场景
- **实时视频监控**: RTSP/RTMP 流接入,实时目标检测
- **无人机巡检**: 空中视频实时分析,异常自动告警
- **交通监控**: 车辆识别、车牌识别、违章检测
- **安全预警**: 火焰检测、烟雾识别、异常行为识别
- **数据分析**: 人流统计、区域入侵检测、目标轨迹追踪
---
## 核心特性
### 性能特点
- **低延迟**: 端到端延迟 < 1s,丢帧策略防止堆积
- **多路并发**: 每路流独立进程,互不影响,支持数十路同时处理
- **动态调度**: 动态跳帧、队列满丢旧帧,确保实时性
- **内存优化**: LRU 缓存 + 模型共享,内存占用可控
### 功能特性
- **多格式支持**: RTSP/RTMP/HTTP-FLV/HLS/本地文件
- **灵活渲染**: 可配置检测框/标签/置信度/ID 显示
- **实时告警**: MQTT 推送 + HTTP 回调
- **图像分析**: 单图检测、图像差异对比
- **扩展能力**: 车牌识别等可插拔扩展
- **热配置**: 配置热加载,无需重启服务
### 硬件加速
- **GPU 推理**: 支持 CUDA + TensorRT 加速
- **NVENC 编码**: NVIDIA 硬件编码,降低 CPU 负载
- **多模型支持**: PyTorch (.pt) / ONNX (.onnx) / TensorRT (.engine)
---
## 快速开始
### 前置要求
- **Python**: 3.10 或更高版本
- **FFmpeg**: 系统已安装 `ffmpeg` 和 `ffprobe`
- **GPU (可选)**: NVIDIA 显卡 + CUDA (用于 GPU 加速)
### 安装步骤
#### 1. 克隆项目
```bash
git clone https://github.com/yourusername/lf_ai.git
cd lf_ai
```
#### 2. 创建虚拟环境
```bash
python3 -m venv .venv310
source .venv310/bin/activate # Windows: .venv310\Scripts\activate
```
#### 3. 安装依赖
**CPU 版本** (Mac / 无显卡环境):
```bash
pip install -r requirements-cpu.txt
```
**GPU 版本** (NVIDIA GPU):
```bash
pip install -r requirements-gpu.txt
```
#### 4. 配置环境
编辑 [config.ini](config.ini) 文件,设置运行环境:
```ini
[app]
env = dev # 开发环境: dev, 生产环境: platform
```
#### 5. 启动服务
```bash
python launch.py
```
服务默认运行在 `http://0.0.0.0:8001`
#### 6. 验证服务
```bash
curl http://127.0.0.1:8001/health
```
返回 `{"status": "ok"}` 表示服务正常运行。
### 示例:发起视频流分析
```bash
curl -X POST http://127.0.0.1:8001/stream/analyse \
-H "Content-Type: application/json" \
-d '{
"url": "rtmp://example.com/live/input",
"targetUrl": "rtmp://example.com/live/output",
"type": "person_car",
"modelType": 3,
"maxDet": 2000,
"boxesFlag": true,
"labelsFlag": true
}'
```
### 示例:停止流分析
```bash
curl -X POST http://127.0.0.1:8001/stop/stream \
-H "Content-Type: application/json" \
-d '{"url": "rtmp://example.com/live/output"}'
```
---
## 系统架构
### 架构概览
项目采用分层架构,将业务逻辑、基础设施、运行时管线清晰分离:
```mermaid
graph TB
subgraph Presentation["接口层 (Presentation Layer)"]
API[Flask HTTP API]
Swagger[Swagger 文档]
DTO[数据传输对象 DTO]
end
subgraph Application["应用层 (Application Layer)"]
UseCase[业务用例 Use Cases]
Factory[分析工厂 Factory]
Registry[解析器注册表 Registry]
Resolver[场景解析器 Resolvers]
end
subgraph Runtime["运行时层 (Runtime Layer)"]
Processor[流处理器 Processor]
Worker[工作进程 Worker]
FrameProc[帧处理器]
Renderer[渲染器]
end
subgraph Infrastructure["基础设施层 (Infrastructure Layer)"]
FFmpeg[FFmpeg 视频处理]
MQTT[MQTT 消息推送]
Model[AI 模型加载]
Cache[缓存管理]
end
Presentation --> Application
Application --> Runtime
Runtime --> Infrastructure
style Presentation fill:#e1f5ff
style Application fill:#fff3e0
style Runtime fill:#f3e5f5
style Infrastructure fill:#e8f5e9
```
### 数据流(端到端)
**实时流分析处理流程**:
```mermaid
flowchart LR
A[客户端请求] --> B[Flask API]
B --> C[DTO 映射]
C --> D[分析工厂]
D --> E[场景解析器]
E --> F[流处理器]
F --> G[启动子进程]
subgraph Worker["子进程 Worker"]
H[FFmpeg 拉流] --> I[帧解码]
I --> J[AI 模型推理]
J --> K[结果过滤]
K --> L[检测框绘制]
L --> M{是否告警?}
M -->|是| N[MQTT 推送]
M -->|否| O[继续处理]
N --> O
O --> P[FFmpeg 推流]
end
G --> H
P --> Q[RTMP 服务器]
style A fill:#e3f2fd
style B fill:#fff3e0
style Q fill:#e8f5e9
style Worker fill:#f3e5f5
```
**处理步骤说明**:
1. **HTTP 请求** → Flask 接收 `/stream/analyse`
2. **请求解析** → DTO 映射为 `Request` 实体
3. **服务分发** → `analyse_factory` 选择对应的 resolver
4. **进程调度** → `StreamProcessor` 启动子进程 `StreamWorker`
5. **视频拉取** → FFmpeg 拉流并解码为 rawvideo (BGR24)
6. **逐帧推理** → `FrameProcessor` 调用 AI 模型检测目标
7. **结果过滤** → 按置信度、区域、类别过滤
8. **渲染绘制** → 在帧上绘制检测框和标签
9. **告警触发** → 满足条件时发送 MQTT/HTTP 回调
10. **视频推流** → FFmpeg 编码并推送到 RTMP 服务器
### 并发模型
```mermaid
graph TB
subgraph MainProcess["主进程 Main Process"]
Flask[Flask HTTP 服务
端口: 8001]
Scheduler[任务调度器]
Manager[进程管理器]
end
subgraph Stream1["子进程 1 - 流 A"]
FFmpeg1_Pull[FFmpeg 拉流进程]
Worker1[StreamWorker]
Thread1[写入线程
队列大小: 6]
FFmpeg1_Push[FFmpeg 推流进程]
FFmpeg1_Pull --> Worker1
Worker1 --> Thread1
Thread1 --> FFmpeg1_Push
end
subgraph Stream2["子进程 2 - 流 B"]
FFmpeg2_Pull[FFmpeg 拉流进程]
Worker2[StreamWorker]
Thread2[写入线程
队列大小: 6]
FFmpeg2_Push[FFmpeg 推流进程]
FFmpeg2_Pull --> Worker2
Worker2 --> Thread2
Thread2 --> FFmpeg2_Push
end
subgraph StreamN["子进程 N - 流 N"]
FFmpegN_Pull[FFmpeg 拉流进程]
WorkerN[StreamWorker]
ThreadN[写入线程
队列大小: 6]
FFmpegN_Push[FFmpeg 推流进程]
FFmpegN_Pull --> WorkerN
WorkerN --> ThreadN
ThreadN --> FFmpegN_Push
end
Flask --> Scheduler
Scheduler --> Manager
Manager --> Stream1
Manager --> Stream2
Manager --> StreamN
RTSP1[RTSP 输入源 A] --> FFmpeg1_Pull
FFmpeg1_Push --> RTMP1[RTMP 输出 A]
RTSP2[RTSP 输入源 B] --> FFmpeg2_Pull
FFmpeg2_Push --> RTMP2[RTMP 输出 B]
RTSPN[RTSP 输入源 N] --> FFmpegN_Pull
FFmpegN_Push --> RTMPN[RTMP 输出 N]
style MainProcess fill:#e3f2fd
style Stream1 fill:#fff3e0
style Stream2 fill:#f3e5f5
style StreamN fill:#e8f5e9
```
**并发特点**:
- **主进程**: Flask HTTP 服务 + 任务调度
- **每路流一个子进程**: 规避 Python GIL,隔离故障
- **子进程内**:
- 1 个 FFmpeg 拉流进程 (解码)
- 1 个 FFmpeg 推流进程 (编码)
- 1 个写入线程 (队列满丢旧帧,保证实时性)
核心原则: 宁可丢帧,不允许堆积导致延迟
### 核心组件关系
```mermaid
graph LR
subgraph HTTP["HTTP 层"]
API[AppEndpoint
API 路由]
Mapper[RequestMapper
请求映射]
end
subgraph UseCases["用例层"]
Analyse[Analyse
流/视频/图片分析]
Stop[StopStream
停止流]
Active[ActiveStreams
活跃流查询]
end
subgraph Services["服务层"]
Factory[AnalyseFactory
分析工厂]
Registry[ResolverRegistry
解析器注册表]
Lifecycle[StreamLifecycle
流生命周期]
end
subgraph Resolvers["场景解析器"]
PersonCar[PersonCar
人车检测]
Fire[Fire
火焰检测]
Helmet[Helmet
安全帽]
Others[其他场景...]
end
subgraph Processors["处理器层"]
StreamProc[StreamProcessor
流处理调度]
VideoProc[VideoProcessor
视频处理]
Worker[StreamWorker
工作进程]
end
subgraph Runtime["运行时组件"]
FrameProc[FrameProcessor
帧处理]
Inference[FrameInference
推理封装]
Drawer[DetectionDrawer
检测框绘制]
Filter[DetectionFilter
结果过滤]
Writer[StreamWriter
推流写入]
end
subgraph Infra["基础设施"]
FFmpegCmd[FFmpegCmd
FFmpeg 命令]
ModelHandler[ModelHandler
模型加载]
MQTTSender[MQTTAsyncSender
消息推送]
LocalCache[LocalCache
本地缓存]
end
API --> Mapper
Mapper --> Analyse
Analyse --> Factory
Factory --> Registry
Registry --> PersonCar
Registry --> Fire
Registry --> Helmet
Registry --> Others
PersonCar --> StreamProc
Fire --> StreamProc
Helmet --> StreamProc
Stop --> Lifecycle
Active --> Lifecycle
StreamProc --> Worker
VideoProc --> Worker
Worker --> FrameProc
FrameProc --> Inference
FrameProc --> Filter
FrameProc --> Drawer
FrameProc --> Writer
Inference --> ModelHandler
Writer --> FFmpegCmd
FrameProc --> MQTTSender
StreamProc --> LocalCache
style HTTP fill:#e3f2fd
style UseCases fill:#fff3e0
style Services fill:#f3e5f5
style Resolvers fill:#e8f5e9
style Processors fill:#fce4ec
style Runtime fill:#fff9c4
style Infra fill:#e0f2f1
```
---
## 项目结构
```
lf_ai/
├── launch.py # 服务启动入口
├── config.ini # 环境配置 (dev/platform)
├── requirements-cpu.txt # CPU 环境依赖
├── requirements-gpu.txt # GPU 环境依赖
├── Dockerfile # Docker 构建文件
├── README.md # 项目文档
├── ARCH_REFACTORING_PLAN.md # 架构重构计划
├── CONFIG_REFRESH_GUIDE.md # 配置刷新指南
│
├── app/ # 应用主目录
│ ├── presentation/ # 【接口层】HTTP API 与数据传输对象
│ │ ├── http/ # Flask 路由与 Swagger
│ │ │ ├── app_endpoint.py # 主要 API 端点
│ │ │ ├── __init__.py # 路由注册
│ │ │ └── swagger_configs/ # Swagger 文档配置
│ │ └── dto/ # 数据传输对象
│ │ └── request_mapper.py # 请求映射器
│ │
│ ├── application/ # 【应用层】业务用例与服务
│ │ ├── use_cases/ # 用例(业务流程入口)
│ │ │ ├── analyse.py # 流/视频/图片分析
│ │ │ ├── active_streams.py # 查询活跃流
│ │ │ ├── stop_stream.py # 停止流
│ │ │ ├── stream_standby.py # 流预热
│ │ │ └── pic_diff.py # 图片差异分析
│ │ ├── services/ # 服务(工厂、注册表、辅助)
│ │ │ ├── analyse_factory.py # 核心分发工厂
│ │ │ ├── resolver_registry.py # Resolver 注册表
│ │ │ ├── resolver_contract.py # Resolver 接口协议
│ │ │ ├── model_path_resolver.py # 模型路径解析
│ │ │ ├── handle_type_guesser.py # 媒体类型识别
│ │ │ ├── request_accessor.py # 请求字段访问器
│ │ │ ├── image_diff_helper.py # 图像差异算法
│ │ │ ├── image_diff_processor.py # 图像差异处理
│ │ │ ├── stream_lifecycle.py # 流生命周期管理
│ │ │ └── resolvers/ # 业务场景 Resolver
│ │ │ ├── person_car.py # 人车检测
│ │ │ ├── fire.py # 火焰检测
│ │ │ ├── helmet.py # 安全帽检测
│ │ │ └── ... # 其他场景
│ │ └── ports/ # 接口定义(依赖反转)
│ │ ├── media.py # 媒体接口
│ │ ├── messaging.py # 消息接口
│ │ ├── model.py # 模型接口
│ │ └── storage.py # 存储接口
│ │
│ ├── runtime/ # 【运行时层】性能关键路径
│ │ ├── streaming/ # 实时流处理核心
│ │ │ ├── frame_processor.py # 帧处理主循环
│ │ │ ├── frame_inference.py # 推理封装
│ │ │ ├── stream_writer.py # 推流写入线程
│ │ │ ├── stream_trigger.py # 告警触发器
│ │ │ ├── detection_filter.py # 检测结果过滤
│ │ │ └── condition_filter.py # 条件过滤器
│ │ ├── orchestration/ # 进程调度与管理
│ │ │ ├── stream_processor.py # 流处理调度器
│ │ │ ├── video_processor.py # 视频处理调度器
│ │ │ ├── process_manager.py # 子进程管理器
│ │ │ ├── caches.py # 全局缓存
│ │ │ └── stream_standby.py # 流预热管理
│ │ ├── workers/ # 子进程工作单元
│ │ │ ├── stream_worker.py # 流处理 Worker
│ │ │ └── video_worker.py # 视频处理 Worker
│ │ ├── rendering/ # 渲染与绘制
│ │ │ ├── detection_drawer.py # 检测框绘制
│ │ │ ├── color_manager.py # 颜色管理
│ │ │ └── color_configs.py # 颜色配置
│ │ ├── media_helper.py # 媒体辅助(截图/水印)
│ │ └── model_predict.py # 通用推理封装
│ │
│ ├── infrastructure/ # 【基础设施层】外部依赖
│ │ ├── ffmpeg/ # FFmpeg 封装
│ │ │ ├── ffmpeg_cmd.py # 命令拼接
│ │ │ └── ffmpeg_util.py # 工具函数
│ │ ├── messaging/ # 消息推送
│ │ │ ├── mqtt_connector.py # MQTT 连接器
│ │ │ ├── mqtt_async_sender.py # 异步发送器
│ │ │ └── mqtt_trigger.py # MQTT 触发器
│ │ ├── ml/ # 模型加载与管理
│ │ │ ├── model_handler.py # 模型处理器
│ │ │ └── download_util.py # 模型下载
│ │ ├── cache/ # 缓存实现
│ │ │ └── local_cache.py # 本地 TTL 缓存
│ │ └── misc/ # 工具集合
│ │ ├── logger.py # 日志封装
│ │ ├── log_handler.py # 日志轮转
│ │ ├── license_checker.py # License 校验
│ │ └── ... # 其他工具
│ │
│ ├── entity/ # 【实体层】数据模型
│ │ ├── request.py # 请求实体
│ │ └── result.py # 响应实体
│ │
│ ├── domain/ # 【领域层】领域类型与策略
│ │ ├── entities/ # 领域实体
│ │ ├── policies/ # 领域策略
│ │ └── types/ # 领域类型
│ │ └── media_extensions.py # 媒体扩展类型
│ │
│ ├── extensions/ # 【扩展层】可插拔功能
│ │ └── plate_recognition/ # 车牌识别扩展
│ │ ├── plate_recognizer.py # 车牌识别器
│ │ ├── plate_processor.py # 车牌处理器
│ │ └── ...
│ │
│ ├── conf/ # 配置管理
│ │ ├── app_config.py # 配置加载器
│ │ ├── config_parser.py # 配置解析器
│ │ ├── constants.py # 常量定义
│ │ └── yaml/ # YAML 配置文件
│ │ ├── app_config_dev.yaml # 开发环境配置
│ │ └── app_config_platform.yaml # 生产环境配置
│ │
│ └── tools/ # 运维工具
│ ├── api_doc_export.py # API 文档导出
│ ├── batch_export.py # 批量导出
│ └── image_diff_benchmark.py # 性能测试
│
├── asset/ # 资源文件
│ ├── model/ # AI 模型存储
│ │ ├── person_car/ # 人车检测模型
│ │ └── rail_transit/ # 轨道交通模型
│ ├── font/ # 字体资源
│ └── icon/ # 图标资源
│
├── logs/ # 日志目录
│ └── backup/ # 日志备份
│
└── tmp_static/ # 临时静态文件(截图等)
```
### 关键模块说明
| 模块 | 职责 | 性能关键 |
|------|------|---------|
| **presentation** | HTTP 接口、请求映射 | ❌ |
| **application** | 业务逻辑、服务编排 | ❌ |
| **runtime** | 实时管线、多进程调度 | ✅ |
| **infrastructure** | FFmpeg、MQTT、模型加载 | ✅ (部分) |
| **entity/domain** | 数据模型、领域定义 | ❌ |
注: ✅ 标记为性能关键路径,修改时需格外小心
---
## 配置说明
### 配置文件结构
- **config.ini**: 环境选择器(`dev` 或 `platform`)
- **app_config_dev.yaml**: 开发环境配置
- **app_config_platform.yaml**: 生产环境配置
### 主要配置项
#### FFmpeg 配置
```yaml
ffmpeg:
pull_scale_enable: false # 是否降低拉流分辨率
pull_scale_width: 1280
pull_scale_height: 720
analyze_duration: '10000000' # 流分析持续时间(微秒)
probe_size: '10000000' # 探测大小(字节)
video_encoder: "h264_nvenc" # 视频编码器(h264_nvenc/libx264)
push_fps: 30 # 推流帧率
write_queue_size: 6 # 写入队列大小(越小延迟越低)
timeout_restart_threshold: 20 # 连续丢帧多少次后重启推流
```
#### 帧处理配置
```yaml
frame:
skip: 2 # 跳帧策略(1=每帧推理,2=每2帧推理)
infer_fps: 30 # 推理节拍器(0=禁用)
```
#### 模型配置
```yaml
model:
path: asset/model/ # 模型文件路径
type: 3 # 1:pt, 2:onnx, 3:engine
warmup: true # 是否进行模型预热
warmup_imgsz: 960 # 预热图像尺寸
```
#### MQTT 配置
```yaml
mqtt:
host: 127.0.0.1
port: 1883
username: mqtt_user
password: mqtt_password
topic: ai_analyse
```
#### 日志配置
```yaml
log:
level: INFO # 日志级别
backup_days: 7 # 日志备份保留天数
frame_log_interval: 5 # 每N帧打印一次详细日志
```
#### 绘制优化配置
```yaml
draw:
disable_chinese_text_threshold: 50 # 检测框超过此阈值禁用中文标签
high_performance_threshold: 120 # 超过此阈值启用极速模式(只画框)
frame_skip_threshold: 150 # 超过此阈值启用跳帧绘制
```
### 配置热更新
```bash
# 重新加载配置(无需重启服务)
curl -X POST http://127.0.0.1:8001/config/reload
# 查看当前配置
curl http://127.0.0.1:8001/config/info
```
---
## API 文档
### 核心接口
#### 1. 健康检查
```bash
GET /health
```
**响应示例**:
```json
{
"status": "ok",
"version": "2.7.4"
}
```
#### 2. 流分析
```bash
POST /stream/analyse
```
**请求参数**:
| 字段 | 类型 | 必填 | 说明 |
|------|------|------|------|
| url | string | ✅ | 输入流地址(RTSP/RTMP/HTTP-FLV等) |
| targetUrl | string | ❌ | 输出流地址(RTMP) |
| type | string | ✅ | 检测类型(person_car/fire/helmet等) |
| modelType | int | ❌ | 模型类型(1:pt, 2:onnx, 3:engine) |
| maxDet | int | ❌ | 最大检测数(默认5000) |
| conf | float | ❌ | 置信度阈值(默认0.25) |
| boxesFlag | bool | ❌ | 是否绘制检测框(默认true) |
| labelsFlag | bool | ❌ | 是否绘制标签(默认true) |
| confFlag | bool | ❌ | 是否显示置信度(默认false) |
| idFlag | bool | ❌ | 是否显示ID(默认false) |
| download | bool | ❌ | 是否先下载(视频文件,默认false) |
**请求示例**:
```bash
curl -X POST http://127.0.0.1:8001/stream/analyse \
-H "Content-Type: application/json" \
-d '{
"url": "rtmp://example.com/live/input",
"targetUrl": "rtmp://example.com/live/output",
"type": "person_car",
"modelType": 3,
"maxDet": 2000,
"conf": 0.5,
"boxesFlag": true,
"labelsFlag": true
}'
```
#### 3. 停止流
```bash
POST /stop/stream
```
**请求参数**:
| 字段 | 类型 | 必填 | 说明 |
|------|------|------|------|
| url | string | ✅ | 要停止的目标流地址(targetUrl) |
**请求示例**:
```bash
curl -X POST http://127.0.0.1:8001/stop/stream \
-H "Content-Type: application/json" \
-d '{"url": "rtmp://example.com/live/output"}'
```
#### 4. 图片分析
```bash
POST /pic/analyse
```
**请求参数**:
| 字段 | 类型 | 必填 | 说明 |
|------|------|------|------|
| url | string | ✅ | 图片URL地址 |
| type | string | ✅ | 检测类型 |
| conf | float | ❌ | 置信度阈值 |
#### 5. 图片差异对比
```bash
POST /pic/diff
```
**请求参数**:
| 字段 | 类型 | 必填 | 说明 |
|------|------|------|------|
| urls | array | ✅ | 两张图片的URL数组 |
| threshold | float | ❌ | 差异阈值 |
#### 6. 查询活跃流
```bash
GET /stream/active
```
#### 7. 流预热
```bash
POST /stream/standby
```
用于预先拉取流并保持连接,降低后续分析的启动延迟。
### Swagger 文档
启动服务后访问:`http://127.0.0.1:8001/apidocs`
---
## 部署指南
### Docker 部署
#### 1. 构建镜像
```bash
docker build -t lf_ai:latest .
```
#### 2. 运行容器
**CPU 版本**:
```bash
docker run -d \
--name lf_ai \
-p 8001:8001 \
-v $(pwd)/asset:/app/asset \
-v $(pwd)/logs:/app/logs \
lf_ai:latest
```
**GPU 版本**:
```bash
docker run -d \
--name lf_ai \
--gpus all \
-p 8001:8001 \
-v $(pwd)/asset:/app/asset \
-v $(pwd)/logs:/app/logs \
lf_ai:latest
```
### 生产环境部署
#### 1. 系统要求
- **操作系统**: Ubuntu 20.04+ / CentOS 7+
- **CPU**: 8核心+(推荐16核)
- **内存**: 16GB+(推荐32GB)
- **GPU**: NVIDIA RTX 3090/4090(可选)
- **存储**: 100GB+ SSD
#### 2. GPU 环境配置
```bash
# 安装 NVIDIA 驱动
ubuntu-drivers devices
sudo ubuntu-drivers autoinstall
# 验证驱动
nvidia-smi
# 安装 CUDA(推荐 11.8+)
# 参考:https://developer.nvidia.com/cuda-downloads
# 验证 PyTorch CUDA 支持
python -c "import torch; print(torch.cuda.is_available())"
# 验证 FFmpeg NVENC 支持
ffmpeg -hide_banner -encoders | grep nvenc
```
#### 3. 服务配置
编辑 `app/conf/yaml/app_config_platform.yaml`:
```yaml
# 启用 NVENC 硬件编码
ffmpeg:
video_encoder: "h264_nvenc"
# 使用 TensorRT 引擎
model:
type: 3 # engine
# 配置日志级别
log:
level: WARNING # 生产环境降低日志输出
```
#### 4. 使用 Systemd 管理服务
创建服务文件 `/etc/systemd/system/lf_ai.service`:
```ini
[Unit]
Description=AI Service
After=network.target
[Service]
Type=simple
User=ai_user
WorkingDirectory=/opt/lf_ai
Environment="PATH=/opt/lf_ai/.venv310/bin"
ExecStart=/opt/lf_ai/.venv310/bin/python launch.py
Restart=always
RestartSec=10
[Install]
WantedBy=multi-user.target
```
启动服务:
```bash
sudo systemctl daemon-reload
sudo systemctl enable lf_ai
sudo systemctl start lf_ai
sudo systemctl status lf_ai
```
#### 5. Nginx 反向代理
```nginx
upstream lf_ai_backend {
server 127.0.0.1:8001;
}
server {
listen 80;
server_name ai.example.com;
location / {
proxy_pass http://lf_ai_backend;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_connect_timeout 300s;
proxy_send_timeout 300s;
proxy_read_timeout 300s;
}
}
```
### Nuitka 打包(单文件可执行程序)
```bash
python -m nuitka \
--standalone \
--onefile \
--follow-imports \
--assume-yes-for-downloads \
--remove-output \
--output-dir=dist \
--output-filename=ai_infer_service \
launch.py
```
---
## 开发指南
### 新增检测场景(Resolver)
#### 1. 创建 Resolver 文件
在 `app/application/services/resolvers/` 目录下创建新文件,例如 `my_scene.py`:
```python
from app.runtime.orchestration.stream_processor import StreamProcessor
from app.runtime.orchestration.video_processor import VideoProcessor
def analyse_stream(model_path, request):
"""实时流分析"""
return StreamProcessor().analyse_stream(
model_path=model_path,
request=request
)
def analyse_video(model_path, request):
"""视频文件分析"""
return VideoProcessor().analyse_video(
model_path=model_path,
request=request
)
def analyse_pic(model_path, request):
"""单图分析"""
from app.runtime.model_predict import model_predict
return model_predict(model_path, request)
```
#### 2. 准备模型文件
将模型文件放置在 `asset/model/my_scene/` 目录下:
```
asset/model/my_scene/
├── best.pt # PyTorch 模型
├── best.onnx # ONNX 模型
└── best.engine # TensorRT 引擎
```
#### 3. 发起请求
```bash
curl -X POST http://127.0.0.1:8001/stream/analyse \
-H "Content-Type: application/json" \
-d '{
"url": "rtmp://example.com/live/input",
"targetUrl": "rtmp://example.com/live/output",
"type": "my_scene",
"modelType": 3
}'
```
### 自定义检测框样式
编辑 `app/runtime/rendering/detection_drawer.py`:
```python
def draw_detections(self, image, detections, request):
for det in detections:
# 自定义线宽
line_width = max(2, request.line_width or 3)
# 自定义颜色
color = self.color_manager.get_color(det.class_id)
# 绘制矩形框
cv2.rectangle(
image,
(x1, y1),
(x2, y2),
color,
line_width
)
# 自定义标签
label = f"{det.class_name} {det.conf:.2f}"
if det.id:
label = f"[{det.id}] {label}"
self.draw_label(image, label, x1, y1, color)
```
### 自定义告警规则
编辑 `app/runtime/streaming/stream_trigger.py`:
```python
def should_trigger(self, detections, request):
"""自定义触发逻辑"""
# 示例:目标数量超过阈值
if len(detections) > request.threshold:
return True
# 示例:特定类别出现
for det in detections:
if det.class_name in ['fire', 'smoke']:
return True
return False
```
### 代码规范
- 使用 **PEP 8** Python 代码风格
- 函数命名:snake_case
- 类命名:PascalCase
- 常量命名:UPPER_CASE
- 添加类型注解(Type Hints)
- 编写文档字符串(Docstrings)
### 测试
```bash
# 运行单元测试
pytest tests/
# 性能测试
python app/tools/image_diff_benchmark.py
```
---
## 性能优化
### 低延迟优化策略
#### 1. 丢帧策略
- **队列满丢旧帧**: 写入队列满时,丢弃最旧的帧,只保留最新帧
- **动态跳帧**: 根据检测目标数量动态调整跳帧率
- **推理节拍器**: 固定推理频率,防止堆积
#### 2. 多进程隔离
- 每路流独立子进程,规避 Python GIL
- 进程间不共享内存,隔离故障
- 子进程崩溃不影响主服务
#### 3. GPU 加速
- **推理加速**: TensorRT 引擎(.engine)性能最佳
- **编码加速**: 使用 NVENC 硬件编码
- **模型预热**: 启动时预先运行推理,降低首帧延迟
#### 4. 绘制优化
```yaml
draw:
disable_chinese_text_threshold: 50 # 目标多时禁用中文标签
high_performance_threshold: 120 # 目标多时只画框不画标签
frame_skip_threshold: 150 # 目标多时跳帧绘制
```
### 性能调优参数
#### 降低延迟
```yaml
ffmpeg:
write_queue_size: 4 # 减小队列(默认6)
push_fps: 25 # 降低推流帧率
frame:
skip: 3 # 增加跳帧(每3帧推理一次)
infer_fps: 25 # 降低推理频率
model:
type: 3 # 使用 TensorRT 引擎
```
#### 提升准确率
```yaml
frame:
skip: 1 # 每帧都推理
# API 请求参数
{
"conf": 0.5, # 提高置信度阈值
"maxDet": 1000 # 减少最大检测数
}
```
#### 多路并发优化
```yaml
# 降低单路资源占用
ffmpeg:
pull_scale_enable: true # 降低拉流分辨率
pull_scale_width: 960
pull_scale_height: 540
push_fps: 20
frame:
skip: 2
```
### 性能监控
查看系统资源占用:
```bash
# CPU/内存/GPU 占用
htop
nvidia-smi -l 1
# 进程列表
ps aux | grep python
# 日志监控
tail -f logs/app.log
```
---
## 常见问题
### Q1: 模型文件不存在错误
**问题**: `FileNotFoundError: Model file not found`
**解决方案**:
1. 检查模型文件路径是否正确:`asset/model/{type}/best.{pt|onnx|engine}`
2. 确认 `config.ini` 中的 `env` 设置正确
3. 检查 YAML 配置中的 `model.path` 设置
### Q2: 推流断开 (Broken pipe)
**问题**: 推流过程中出现 `Broken pipe` 错误
**解决方案**:
1. 检查输出 RTMP 地址是否正确
2. 确认 RTMP 服务器是否正常运行
3. 检查网络连接是否稳定
4. 降低推流码率和帧率
### Q3: GPU 内存不足 (CUDA out of memory)
**问题**: `RuntimeError: CUDA out of memory`
**解决方案**:
1. 减少并发处理的流数量
2. 降低模型输入分辨率(`maxDet` 参数)
3. 使用更小的模型
4. 启用 `pull_scale_enable` 降低输入分辨率
### Q4: 延迟过高
**问题**: 端到端延迟超过3秒
**解决方案**:
1. 增加跳帧率:`frame.skip: 3`
2. 减小写入队列:`ffmpeg.write_queue_size: 4`
3. 降低推流帧率:`ffmpeg.push_fps: 20`
4. 使用 TensorRT 引擎:`model.type: 3`
5. 启用 NVENC 编码:`ffmpeg.video_encoder: h264_nvenc`
### Q5: 画面没有检测框
**问题**: 推流正常但看不到检测框
**解决方案**:
1. 检查 `boxesFlag: true` 和 `labelsFlag: true`
2. 确认模型推理是否正常(查看日志)
3. 降低置信度阈值:`conf: 0.25`
4. 检查是否触发了高性能模式(目标过多时自动禁用标签)
### Q6: FFmpeg 找不到
**问题**: `FileNotFoundError: ffmpeg not found`
**解决方案**:
```bash
# Ubuntu/Debian
sudo apt-get update
sudo apt-get install ffmpeg
# CentOS/RHEL
sudo yum install ffmpeg
# macOS
brew install ffmpeg
# 验证安装
ffmpeg -version
ffprobe -version
```
### Q7: MQTT 连接失败
**问题**: `ConnectionRefusedError: [Errno 111] Connection refused`
**解决方案**:
1. 检查 MQTT broker 是否运行
2. 确认 YAML 中的 MQTT 配置正确
3. 检查防火墙设置
4. 测试 MQTT 连接:`mosquitto_pub -h -p -t test -m "hello"`
### Q8: 车牌识别准确性问题
**问题**: 车牌识别扩展返回结果不理想
**解决方案**:
1. 确保车辆检测框准确
2. 提高输入图像分辨率
3. 调整车牌识别模型的置信度阈值
4. 检查光照条件
### Q9: 服务启动失败
**问题**: `python launch.py` 启动报错
**解决方案**:
1. 检查 Python 版本:`python --version` (需要 3.10+)
2. 确认依赖已安装:`pip list | grep -E "torch|flask|opencv"`
3. 检查端口是否被占用:`lsof -i:8001`
4. 查看详细日志:`python launch.py` 查看错误堆栈
### Q10: Docker 容器无法访问 GPU
**问题**: Docker 中无法使用 GPU 加速
**解决方案**:
```bash
# 安装 nvidia-docker2
distribution=$(. /etc/os-release;echo $ID$VERSION_ID)
curl -s -L https://nvidia.github.io/nvidia-docker/gpgkey | sudo apt-key add -
curl -s -L https://nvidia.github.io/nvidia-docker/$distribution/nvidia-docker.list | \
sudo tee /etc/apt/sources.list.d/nvidia-docker.list
sudo apt-get update && sudo apt-get install -y nvidia-docker2
sudo systemctl restart docker
# 测试 GPU 访问
docker run --rm --gpus all nvidia/cuda:11.8.0-base-ubuntu22.04 nvidia-smi
```
---
## 相关文档
- [架构重构计划](ARCH_REFACTORING_PLAN.md)
- [配置刷新指南](CONFIG_REFRESH_GUIDE.md)
- [Swagger API 文档](http://127.0.0.1:8001/apidocs)
## License
本项目采用 MIT 许可证。详见 [LICENSE](LICENSE) 文件。
## 贡献
欢迎提交 Issue 和 Pull Request!
## 联系方式
- Email: tinx.wills@gmail.com
---
**更新日期**: 2026-01-12
**版本**: v2.7.5