GHBanner
# 语义分割系统(SegServer) > 基于 React + FastAPI + SAM 2 的全栈交互式图像/视频语义分割与标注平台。 > > 支持本地多媒体资产上传、服务器端按帧解析、交互式 Canvas 标注、视频片段传播、GT mask 导入、模板分类管理和标注数据结构化导出;工作区点/框 AI 推理走可选 SAM 2.1 tiny/small/base+/large,前端会显示真实 GPU/模型状态。SAM 3 源码和脚本在仓库中保留,但由于当前系统不提供文本提示,产品入口已隐藏,后端也不暴露 `sam3` 模型。 --- ## 核心功能 - **多媒体资产管理** — 支持视频(MP4/AVI/MOV)和 DICOM 医学影像上传;视频导入与生成帧分离,生成帧时选择目标 FPS - **AI 智能分割引擎** — 当前产品入口启用 SAM 2.1 四个变体(tiny/small/base+/large)选择;支持点分割(point)、框分割(box)、交互式正/反点细化、自动分割(auto)和 video predictor 传播,前端默认只采用最高分候选避免重叠备选同时显示 - **交互式画布标注** — 基于 Konva 的高性能 Canvas,支持缩放/平移/手工多边形/矩形/圆/点/线、polygon 顶点拖动/删除、边中点插点、双击边界插点、区域合并/去除、选点/框选、撤销/重做,实时渲染 Mask 遮罩 - **GT Mask 导入** — 工作区可导入 GT mask 图片,后端按非零像素值和连通域生成 polygon 标注并用 distance transform 写入 seed point;前端可回显和拖动 seed point - **本体字典管理** — 可配置的分类体系、颜色映射、图层优先级(z-index) - **项目工作区** — 项目创建、帧浏览、多图层标注、已编辑帧提示、进度追踪 - **数据导出** — 支持 COCO JSON 格式和 PNG Mask 批量导出;PNG ZIP 包含单标注 mask、按 z-index 融合的语义 mask 和类别映射 --- ## 系统架构 ``` ┌─────────────────────────────────────────────────────────────┐ │ 前端展示层 (React 19 + Vite + TailwindCSS) │ │ localhost:3000 │ │ Zustand(状态) + Axios(API) + WebSocket(实时进度) │ │ Konva(Canvas渲染) + lucide-react(图标) │ └──────────────────────────┬──────────────────────────────────┘ │ HTTP / WebSocket ┌──────────────────────────▼──────────────────────────────────┐ │ 业务逻辑层 (FastAPI + Python 3.11) │ │ localhost:8000 │ │ ├── /api/auth 登录认证 │ │ ├── /api/projects 项目 & 视频帧 CRUD │ │ ├── /api/templates 本体字典(分类/颜色/z-index) │ │ ├── /api/media 文件上传 & 异步拆帧任务创建 │ │ ├── /api/tasks Celery 后台任务状态/取消/重试/详情 │ │ ├── /api/ai SAM 2 推理与模型状态 │ │ └── /api/export COCO JSON / PNG Masks 导出 │ └──────────────────────────┬──────────────────────────────────┘ │ SQLAlchemy 2.0 ┌──────────────────────────▼──────────────────────────────────┐ │ 数据持久化层 │ │ PostgreSQL 14 — 项目/帧/标注/Mask/Task 元数据 │ │ Redis 6 — Celery broker/result backend + 进度 pub/sub │ │ MinIO — 对象存储(原始视频/解析帧/Mask图像) │ └─────────────────────────────────────────────────────────────┘ ``` --- ## 技术栈 | 层级 | 技术选型 | 版本 | |------|----------|------| | 前端框架 | React + TypeScript | React 19, TS 5.8 | | 构建工具 | Vite | v6 | | 样式方案 | TailwindCSS + 自定义深色主题 | v4 | | 状态管理 | Zustand | - | | Canvas 渲染 | Konva + react-konva | - | | 几何布尔运算 | polygon-clipping | 0.15+ | | HTTP 客户端 | Axios | - | | 后端框架 | FastAPI | v0.136+ | | 数据库 ORM | SQLAlchemy(依赖中包含 Alembic) | 2.0+ | | 数据库 | PostgreSQL | 14 | | 队列 Broker | Redis | 6 | | 后台任务 | Celery worker | 5.6+ | | 对象存储 | MinIO | 2025+ | | AI 推理 | SAM 2.1 (Meta) + PyTorch,可选 tiny/small/base+/large | - | | 视频处理 | FFmpeg + OpenCV | 4.4+ | | DICOM 处理 | pydicom | 3.0+ | --- ## 目录结构 ``` Seg_Server/ ├── backend/ # FastAPI 后端 │ ├── main.py # 应用入口(CORS/生命周期/路由注册/WebSocket) │ ├── config.py # 环境变量配置(Pydantic Settings) │ ├── database.py # SQLAlchemy 引擎 + Session │ ├── models.py # ORM 模型(Project/Frame/Template/Annotation/Mask/ProcessingTask) │ ├── schemas.py # Pydantic 请求/响应校验模型 │ ├── minio_client.py # MinIO 上传/下载/预签名URL封装 │ ├── redis_client.py # Redis 连接封装 │ ├── progress_events.py # 任务进度事件 payload 与 Redis 发布 │ ├── statuses.py # 项目/任务状态常量 │ ├── celery_app.py # Celery app 配置 │ ├── worker_tasks.py # Celery 任务入口 │ ├── download_sam2.py # SAM 2 模型权重自动下载脚本 │ ├── setup_sam3_env.sh # 历史保留的 SAM 3 独立 Python 3.12 环境安装脚本;当前产品入口禁用 │ ├── requirements.txt # Python 依赖 │ ├── routers/ # API 路由 │ │ ├── auth.py # 登录认证 │ │ ├── projects.py # 项目 & 帧 CRUD │ │ ├── templates.py # 本体字典管理 │ │ ├── media.py # 上传 & 解析 │ │ ├── ai.py # SAM 推理与模型状态接口 │ │ └── export.py # 数据导出 │ └── services/ # 业务服务 │ ├── sam2_engine.py # SAM 2.1 变体选择、单帧推理 + video predictor 传播 │ ├── sam3_engine.py # 历史保留的 SAM 3 桥接实现;当前未接入 registry │ ├── sam3_external_worker.py # 历史保留的独立 sam3 helper;当前未被产品入口调用 │ ├── sam_registry.py # 当前暴露 SAM 2.1 变体、GPU 状态与推理分发 │ └── frame_parser.py # FFmpeg 拆帧 / pydicom 读片 ├── src/ # React 前端 │ ├── main.tsx # 应用挂载点 │ ├── App.tsx # 根组件(模块路由 + 鉴权) │ ├── store/ │ │ └── useStore.ts # Zustand 全局状态 │ ├── lib/ │ │ ├── api.ts # Axios 实例 + API 方法封装 │ │ ├── websocket.ts # WebSocket 客户端(解析进度) │ │ └── utils.ts # cn() 工具函数 │ └── components/ # 组件(扁平化目录) │ ├── Login.tsx # 登录页 │ ├── Sidebar.tsx # 左侧导航栏 │ ├── Dashboard.tsx # 总体概况仪表盘(任务进度/任务控制) │ ├── ProjectLibrary.tsx # 项目库列表 │ ├── VideoWorkspace.tsx # 核心分割工作区布局 │ ├── CanvasArea.tsx # Konva 画布(缩放/平移/手工绘制/选点/Mask渲染) │ ├── ToolsPalette.tsx # 左侧工具栏 │ ├── OntologyInspector.tsx # 右侧本体/属性检查面板 │ ├── FrameTimeline.tsx # 底部时间轴 │ ├── AISegmentation.tsx # AI 智能分割引擎界面 │ └── TemplateRegistry.tsx # 模板库管理 ├── models/ # SAM 2 模型权重(.pt 文件) ├── uploads/ # 临时上传目录 ├── frames/ # 临时帧目录 ├── doc/ # 当前实现审计、接口契约与后续实施文档 ├── public/ │ └── logo.png # 侧边栏 Logo 静态资源 ├── start_services.sh # 一键启动所有服务脚本 ├── server.ts # Express + Vite 前端入口(也保留少量旧版 mock API) ├── index.html # SPA HTML 入口 ├── vite.config.ts # Vite 构建配置 ├── package.json # npm 依赖与脚本 └── tsconfig.json # TypeScript 配置 ``` --- ## 项目文档 当前实现审计与接口契约文档在 `doc/` 目录: - `doc/01-purpose-and-word-summary.md` — 项目目的、Word 方案摘要与当前落地程度 - `doc/03-frontend-element-audit.md` — 前端逐元素功能审计,标注真实可用、部分可用、Mock/UI-only、接口不通 - `doc/04-api-contracts.md` — 前后端接口契约和已知不一致 - `doc/06-fastapi-docs-explained.md` — `http://192.168.3.11:8000/docs` 的作用说明 --- ## 环境准备 ### 系统要求 - **OS**: Ubuntu 22.04 LTS - **GPU**: NVIDIA GPU(推荐 RTX 4090 或同等算力),用于 SAM 2 推理 - **CUDA**: 12.x / 13.x - **Node.js**: 22.x+ - **Python**: 主后端使用 3.11(通过 Miniconda/Anaconda 管理);历史保留的 SAM 3 环境不是当前必需运行条件 ### 安装系统级依赖 ```bash # 更新包索引 sudo apt update # 安装 PostgreSQL、Redis、FFmpeg、构建工具 sudo apt install -y postgresql postgresql-contrib redis-server ffmpeg \ libpq-dev build-essential curl ca-certificates gnupg # 安装 MinIO(二进制方式) mkdir -p ~/minio_data cd /tmp wget https://dl.min.io/server/minio/release/linux-amd64/minio chmod +x minio sudo mv minio /usr/local/bin/ ``` --- ## 部署流程 ### 步骤 1: 配置 PostgreSQL 数据库 ```bash # 启动服务 sudo systemctl start postgresql redis-server # 创建数据库和用户 sudo -u postgres psql -c "CREATE DATABASE segserver;" sudo -u postgres psql -c "CREATE USER seguser WITH PASSWORD 'segpass123';" sudo -u postgres psql -c "GRANT ALL PRIVILEGES ON DATABASE segserver TO seguser;" sudo -u postgres psql -d segserver -c "GRANT ALL ON SCHEMA public TO seguser;" sudo -u postgres psql -c "ALTER DATABASE segserver OWNER TO seguser;" ``` ### 步骤 2: 启动 MinIO ```bash nohup minio server ~/minio_data --console-address :9001 > /tmp/minio.log 2>&1 & # 验证 # API: http://localhost:9000 # 控制台: http://localhost:9001 (minioadmin / minioadmin) ``` ### 步骤 3: 创建 Conda 环境并安装 Python 依赖 ```bash # 创建环境 conda create -n seg_server python=3.11 -y conda activate seg_server # 安装 PyTorch(根据 CUDA 版本选择) # CUDA 12.x 用户: pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu124 # CPU 用户(无 GPU): pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cpu # 安装后端依赖 cd ~/Desktop/Seg_Server/backend pip install -r requirements.txt ``` ### 步骤 4: 下载 SAM 2 模型权重 ```bash cd ~/Desktop/Seg_Server/backend python download_sam2.py # 模型将下载到 ~/Desktop/Seg_Server/models/ # 推荐放置 SAM 2.1 文件名: # sam2.1_hiera_tiny.pt # sam2.1_hiera_small.pt # sam2.1_hiera_base_plus.pt # sam2.1_hiera_large.pt # # 兼容旧版 SAM 2 文件名: # sam2_hiera_tiny.pt / sam2_hiera_small.pt / sam2_hiera_base_plus.pt / sam2_hiera_large.pt ``` > **注意**:当前系统磁盘紧张时,建议仅保留 `sam2.1_hiera_tiny.pt` 或兼容旧名 `sam2_hiera_tiny.pt`,删除其他模型以释放空间。前端可以选择四个变体,但只有本地存在对应 checkpoint 的变体会显示可用。 ### 步骤 5: 历史保留的 SAM 3 环境 当前产品入口不再启用 SAM 3:前端隐藏 SAM 3 相关入口,后端 registry 只暴露 SAM 2.1 变体,`model=sam3` 会返回不支持。以下脚本和 helper 仅作为以后恢复 SAM 3 研究路径的保留文件,正常部署不需要执行。 ```bash cd ~/Desktop/Seg_Server ./backend/setup_sam3_env.sh # 仅在后续恢复 SAM 3 实验路径时使用。 ``` 官方 `facebook/sam3` 权重约 3.45 GB,当前没有类似 SAM 2 `tiny/small/base/large` 的官方小权重梯度。本项目不会提交权重文件;由于当前系统不提供文本提示,SAM 3 不在模型状态接口和前端 UI 中展示。 ### 步骤 6: 配置环境变量 后端通过 `backend/config.py` 中的 Pydantic Settings 读取 `backend/.env`。如需覆盖默认值,请编辑以下文件: **backend/.env**(数据库/Redis/MinIO/SAM 路径): ```ini db_url=postgresql://seguser:segpass123@localhost:5432/segserver redis_url=redis://localhost:6379/0 minio_endpoint=192.168.3.11:9000 minio_access_key=minioadmin minio_secret_key=minioadmin minio_secure=false sam_model_path=/home/wkmgc/Desktop/Seg_Server/models/sam2.1_hiera_tiny.pt sam_model_config=configs/sam2.1/sam2.1_hiera_t.yaml sam_default_model=sam2.1_hiera_tiny # 以下 sam3_* 配置为历史保留项;当前产品入口不读取它们来暴露 SAM 3。 # sam3_model_version=sam3 # sam3_checkpoint_path=/home/wkmgc/Desktop/Seg_Server/sam3权重/sam3.pt # sam3_external_enabled=true # sam3_external_python=/home/wkmgc/miniconda3/envs/sam3/bin/python # sam3_timeout_seconds=300 cors_origins=["http://localhost:3000","http://192.168.3.11:3000"] ``` 前端根目录的 `.env.example` 包含 AI Studio 注入变量和前端 API 配置: ```ini VITE_API_BASE_URL=http://192.168.3.11:8000 VITE_WS_PROGRESS_URL=ws://192.168.3.11:8000/ws/progress ``` 如果未配置 `VITE_API_BASE_URL`,前端会按当前浏览器 hostname 推导 `http://:8000`。 ### 步骤 7: 启动后端服务 ```bash cd ~/Desktop/Seg_Server/backend source ~/miniconda3/etc/profile.d/conda.sh conda activate seg_server uvicorn main:app --host 0.0.0.0 --port 8000 # 或使用后台模式 nohup uvicorn main:app --host 0.0.0.0 --port 8000 > /tmp/fastapi.log 2>&1 & ``` 后端启动后将自动: - 创建数据库表(如果不存在) - 检查 MinIO bucket 是否存在 - 测试 Redis 连接 - 懒加载所选 SAM 2.1 模型;`GET /api/ai/models/status` 会返回 tiny/small/base+/large 和 GPU 的真实可用状态,`selected_model=sam3` 会返回不支持 - `/api/ai/predict` 支持 AI 参数 `crop_to_prompt`、`auto_filter_background` 和 `min_score`,用于点/框 prompt 的局部裁剪推理、回映射和背景过滤 - `/api/ai/propagate` 支持从当前帧 seed 区域向视频片段传播:当前使用所选 SAM 2.1 变体的 `SAM2VideoPredictor.add_new_mask()` + `propagate_in_video()` ### 步骤 6.1: 启动 Celery Worker ```bash cd ~/Desktop/Seg_Server/backend source ~/miniconda3/etc/profile.d/conda.sh conda activate seg_server celery -A celery_app:celery_app worker --loglevel=info --concurrency=1 # 或使用后台模式 nohup celery -A celery_app:celery_app worker --loglevel=info --concurrency=1 > /tmp/celery.log 2>&1 & ``` 视频导入只创建项目并把源视频保存到 MinIO,不会自动拆帧;用户在项目库点击“生成帧”后,再选择目标 FPS 并调用 `POST /api/media/parse`。该接口只创建 `processing_tasks` 记录并把任务投递给 Celery;真正的 FFmpeg/OpenCV/pydicom 拆帧由 worker 执行。接口支持 `parse_fps`、`max_frames` 和 `target_width`,用于生成后续 SAM 2 视频处理可复用的标准帧序列;视频帧按 `frame_%06d.jpg` 连续命名,帧表会记录 `timestamp_ms` 和 `source_frame_number`,任务完成结果会返回 `frame_sequence` 元数据。worker 每次更新任务状态后会发布到 Redis `seg:progress` 频道,FastAPI 订阅后转发到 `/ws/progress`,前端 Dashboard 可实时更新。Dashboard 的任务进度区展示 queued/running/success/failed/cancelled 最近任务,处理中统计只计算 queued/running;WebSocket 状态由浏览器 `onopen/onclose/onerror` 驱动,客户端会定时发送 `ping` 心跳,服务端返回 `status` 确认连接。Dashboard 也可调用 `/api/tasks/{id}/cancel`、`/api/tasks/{id}/retry` 和 `/api/tasks/{id}` 完成任务取消、重试与失败详情查看。 ### 步骤 7: 安装前端依赖并构建 ```bash cd ~/Desktop/Seg_Server # 安装依赖 npm install # 类型检查 npm run lint # 生产构建 npm run build # 启动前端服务 npm start # 或使用后台模式 nohup npm start > /tmp/frontend.log 2>&1 & ``` --- ## 一键启动(推荐) 项目根目录提供了 `start_services.sh` 脚本,可一键启动所有服务: ```bash cd ~/Desktop/Seg_Server ./start_services.sh ``` 脚本将依次检查并启动:PostgreSQL → Redis → MinIO → FastAPI 后端 → Celery Worker → 前端。 --- ## 访问地址与默认凭证 | 服务 | 地址 | 说明 | |------|------|------| | 前端界面 | http://localhost:3000 | admin / 123456 | | 后端 API 文档 | http://localhost:8000/docs | Swagger UI | | MinIO 控制台 | http://localhost:9001 | minioadmin / minioadmin | | PostgreSQL | localhost:5432 | seguser / segpass123 | --- ## 可用命令 ### 前端 ```bash npm install # 安装依赖 npm run dev # 运行 tsx server.ts,Express + Vite 中间件(端口 3000) npm run build # 生产构建(输出到 dist/) npm run lint # TypeScript 类型检查 npm run test # Vitest watch 模式 npm run test:run # Vitest 单次运行 npm start # Node.js 运行 server.ts(生产静态服务 / 旧版 mock API) ``` ### 后端 ```bash # 在 conda seg_server 环境中 cd backend pip install -r requirements-dev.txt # 安装后端测试依赖 pytest tests # 后端接口测试 uvicorn main:app --host 0.0.0.0 --port 8000 --reload # 开发模式(热重载) uvicorn main:app --host 0.0.0.0 --port 8000 # 生产模式 celery -A celery_app:celery_app worker --loglevel=info --concurrency=1 # 后台任务 worker ``` --- ## 常见问题 ### Q1: 磁盘空间不足导致 PyTorch / sam2 安装失败 **现象**: `OSError: [Errno 28] No space left on device` **解决**: ```bash # 1. 清理系统包缓存 sudo apt autoremove -y && sudo apt clean # 2. 清理 conda 缓存 conda clean --all -y # 3. 仅保留最小模型 rm ~/Desktop/Seg_Server/models/sam2.1_hiera_large.pt rm ~/Desktop/Seg_Server/models/sam2.1_hiera_base_plus.pt rm ~/Desktop/Seg_Server/models/sam2.1_hiera_small.pt # 4. 如需安装 sam2 包,确保有 >5GB 可用空间后再执行 ``` ### Q2: SAM 2 推理返回 dummy polygons(矩形框) **原因**: `sam2` Python 包未安装,或模型权重路径不正确。 **解决**: ```bash # 1. 确认模型文件存在 ls ~/Desktop/Seg_Server/models/sam2.1_hiera_tiny.pt # 2. 安装 sam2(需 >5GB 磁盘空间) cd /tmp git clone --depth 1 https://github.com/facebookresearch/segment-anything-2.git cd segment-anything-2 pip install -e . --no-build-isolation # 3. 重启后端服务 ``` ### Q3: MinIO 报 `XMinioStorageFull` **原因**: 系统磁盘可用空间低于 MinIO 默认阈值。 **解决**: 清理解析产生的临时帧文件或扩展磁盘空间。 ### Q4: 前端无法连接后端 API **检查清单**: 1. 后端是否已启动(`curl http://localhost:8000/health`) 2. `backend/.env` 中的 `cors_origins` 是否包含 `http://localhost:3000` 3. 前端是否配置了正确的 `VITE_API_BASE_URL`;未配置时会按当前浏览器 hostname 推导 `http://:8000` ### Q5: 如何验证 AI 推理或 COCO 导出接口 **当前状态**: - 前端 `predictMask()` 已发送后端需要的 `image_id`、`prompt_type`、`prompt_data`,并把后端 `polygons` 转成 Konva `pathData`。 - 工作区点选/框选会使用当前帧的数据库 `frame.id` 调用 `/api/ai/predict`。 - 工作区 SAM 2.1 交互式细化包含反向点时会启用后端背景过滤;若反向点排除了当前候选区域并返回空结果,前端会移除旧候选 mask。 - AI 页面只显示本页新生成的 SAM 2.1 候选,不会把工作区已有 mask 带入 AI 画布;新生成 mask 会写入全局 `masks` 并自动选中,右侧分类树可直接给生成结果换标签,“推送至工作区编辑”会切回工作区的多边形调整工具并保留选择。 - 工作区“传播片段”会使用当前选中区域或当前帧第一个区域作为 seed,调用 `/api/ai/propagate`,并在完成后刷新已保存标注。 - 前端 `exportCoco()` 已对齐到 `/api/export/{projectId}/coco`。 - 工作区“导出 JSON 标注集”和“导出 PNG Mask ZIP”按钮已绑定下载流程;导出前会先保存当前待归档的前端 mask。 - 工作区“导入 GT Mask”按钮已绑定 `/api/ai/import-gt-mask`,导入后会刷新并回显已保存标注和 seed point。 - 工作区“结构化归档保存”按钮会把当前项目未保存 mask 写入 `POST /api/ai/annotate`,并把 dirty mask 写入 `PATCH /api/ai/annotations/{id}`。 - 工作区“清空遮罩”会通过 `DELETE /api/ai/annotations/{id}` 删除当前帧已保存标注,并清空当前帧本地 mask。 **验证**: ```bash curl http://localhost:8000/health curl http://localhost:8000/api/export/1/coco curl http://localhost:8000/api/export/1/masks ``` --- ## 开发团队 本项目基于 Google AI Studio 模板构建,经全栈化改造后用于工业级语义分割场景。 --- > 如需添加新功能或修复问题,请遵循项目根目录 `工程分析/代码编纂工作流.md` 中定义的代码编纂流程。