# health-python **Repository Path**: cxcy666_admin/health-python ## Basic Information - **Project Name**: health-python - **Description**: No description available - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-03-14 - **Last Updated**: 2026-03-23 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # Health Python - 伤病图像识别推理服务(RESTful API) 本仓库提供“健康管理系统”中的 **伤病图像识别(Python 推理服务)**,以 **FastAPI** 形式对外提供 RESTful API,供 Java 后端调用,并可在 Swagger / Apifox 中进行联调测试。 当前实现: - **受伤部位自动标注**:基于 U-Net 分割,输出 `mask` 与 `overlay` - **伤病类型识别(路线 A:业务粗分类)**:基于 `mask_ratio` 判断是否存在明显创口/溃疡(`ulcer_present / ulcer_absent`,提供中文名) - **严重程度初步评估**:基于 `mask_ratio` 规则分级(`mild / moderate / severe`,提供中文名) - **统一接口规范**:稳定字段、统一错误码,便于 Java 解析 - **文件落盘与可追溯**:上传原图保存到 `uploads_api/`,推理结果保存到 `outputs_api/` - **静态文件访问**:返回 `image_url / mask_url / overlay_url`,便于前端直接展示 - **可 Docker 部署**:推荐通过 `docker compose` 一键启动 > 说明:本服务输出仅用于“初步评估”和工程演示,不替代医学诊断。 --- ## 1. 目录结构(根目录交付) > 本仓库不提交数据集、模型权重、推理输出文件和本地虚拟环境。 ```text . ├── api_server.py # FastAPI 服务入口(REST API) ├── inference.py # 推理核心逻辑(加载模型、预处理、后处理、业务分类、严重度) ├── config.py # 配置(环境变量优先,含阈值、权重路径、输出策略) ├── schemas.py # Pydantic Schema(响应结构/错误结构) ├── model.py # U-Net 模型定义(推理端需要) ├── predict.py # 单机脚本推理(辅助调试) ├── requirements.txt # Python 依赖 ├── Dockerfile # Docker 镜像构建文件(无后缀) ├── docker-compose.yml # 推荐部署方式(挂载权重、持久化上传与输出) ├── .env.example # 环境变量示例(不要提交真实 .env) ├── .gitignore # 忽略权重/数据/输出/虚拟环境等 └── README.md # 本文档 ``` 默认不提交: - `runs/`(模型权重) - `uploads_api/`(上传原图) - `outputs_api/`(推理输出) - `data_*` / `datasets*`(数据集) - `.venv/` --- ## 2. 快速开始(Docker 推荐) ### 2.1 准备模型权重(必须) 本服务默认从以下路径加载模型权重: ```text runs/unet_best.pt ``` 请在项目根目录创建 `runs/`,并放入权重文件: ```text runs/ └── unet_best.pt ``` > 权重文件不提交仓库,由部署方在运行机上放置或挂载。 ### 2.2 一键启动 在项目根目录执行: ```bash docker compose up -d --build ``` ### 2.3 查看日志 ```bash docker compose logs -f ``` ### 2.4 停止服务 ```bash docker compose down ``` 如果需要清理旧的孤儿容器: ```bash docker compose down --remove-orphans ``` --- ## 3. 本地启动(开发调试) ### 3.1 Windows PowerShell ```powershell python -m venv .venv .\.venv\Scripts\Activate.ps1 python -m pip install -r requirements.txt # 确保 runs/unet_best.pt 存在 uvicorn api_server:app --host 0.0.0.0 --port 8000 --reload ``` 如果 PowerShell 禁止脚本执行: ```powershell Set-ExecutionPolicy -Scope CurrentUser RemoteSigned ``` ### 3.2 Linux / macOS ```bash python -m venv .venv source .venv/bin/activate pip install -r requirements.txt uvicorn api_server:app --host 0.0.0.0 --port 8000 --reload ``` --- ## 4. 配置说明(环境变量优先) 你可以通过环境变量调整行为,推荐写在 `.env` 中,但不要提交真实 `.env`。 关键配置如下: | 配置项 | 默认值 | 说明 | |---|---:|---| | `CHECKPOINT_PATH` | `runs/unet_best.pt` | 模型权重路径 | | `IMAGE_SIZE` | `256` | 推理 resize 尺寸 | | `MASK_THRESHOLD` | `0.5` | mask 二值化阈值 | | `ULCER_PRESENT_THRESHOLD` | `0.01` | 粗分类阈值(基于 `mask_ratio`) | | `RETURN_BASE64` | `false` | 推荐 `false`:保存文件并返回路径/URL | | `UPLOAD_DIR` | `uploads_api` | 上传原图保存目录 | | `OUTPUT_DIR` | `outputs_api` | mask / overlay 保存目录 | 示例见 `.env.example`。 --- ## 5. Docker 访问地址说明 ```yaml ports: - "8001:8000" ``` 访问时应使用: - Swagger:`http://127.0.0.1:8001/docs` - 健康检查:`http://127.0.0.1:8001/health` - 推理接口:`http://127.0.0.1:8001/infer` --- ## 6. API 接口说明(供 Java / Swagger / Apifox) ### 6.1 GET /health(健康检查) **URL**:`GET /health` 用途: - 检查服务是否可用 - 检查模型是否加载成功 - 用于部署排障 响应示例: ```json { "ok": true, "model_loaded": true, "device": "cpu", "checkpoint": "runs/unet_best.pt" } ``` 如果 `model_loaded=false`,请优先检查: - `runs/unet_best.pt` 是否存在 - Docker 挂载路径是否正确 - 权重文件名是否一致 --- ### 6.2 POST /infer(推理接口) **URL**:`POST /infer` **Content-Type**:`multipart/form-data` 表单字段: - `file`:图片文件(必填) #### 6.2.1 curl 示例 ```bash curl -X POST "http://127.0.0.1:8001/infer" \ -H "accept: application/json" \ -H "Content-Type: multipart/form-data" \ -F "file=@test.png" ``` --- ### 6.2.2 成功响应(推荐:`RETURN_BASE64=false`) ```json { "ok": true, "injury_type_code": "ulcer_absent", "injury_type_name": "未见明显创口", "severity": "mild", "severity_name": "轻度", "mask_ratio": 0.0082, "image_path": "uploads_api/xxx.png", "mask_path": "outputs_api/xxx_mask.png", "overlay_path": "outputs_api/xxx_overlay.png", "image_url": "http://127.0.0.1:8001/files/uploads_api/xxx.png", "mask_url": "http://127.0.0.1:8001/files/outputs_api/xxx_mask.png", "overlay_url": "http://127.0.0.1:8001/files/outputs_api/xxx_overlay.png" } ``` 字段说明: - `injury_type_code`:业务粗分类(`ulcer_present` / `ulcer_absent`) - `injury_type_name`:中文展示(`疑似创口/溃疡` / `未见明显创口`) - `severity`:严重程度(`mild / moderate / severe`) - `severity_name`:中文严重度(`轻度 / 中度 / 重度`) - `mask_ratio`:mask 前景面积占比(0~1) - `image_path`:上传原图本地相对路径 - `mask_path`:mask 图本地相对路径 - `overlay_path`:叠加图本地相对路径 - `image_url`:原图可访问 URL - `mask_url`:mask 图可访问 URL - `overlay_url`:叠加图可访问 URL --- ### 6.2.3 成功响应(可选:`RETURN_BASE64=true`) ```json { "ok": true, "injury_type_code": "ulcer_present", "injury_type_name": "疑似创口/溃疡", "severity": "moderate", "severity_name": "中度", "mask_ratio": 0.0213, "mask_png_base64": "....", "overlay_png_base64": "...." } ``` > 不推荐把 base64 作为默认工程交付方案,因为字符串过长,不利于 Java / 前端联调和结果追溯。 --- ### 6.2.4 失败响应(统一错误结构) ```json { "ok": false, "error_code": "INVALID_IMAGE", "error": "invalid image" } ``` 常见错误码: - `EMPTY_FILE`:上传文件为空 - `INVALID_IMAGE`:图片无法解码 / 格式错误 - `CHECKPOINT_NOT_FOUND`:权重路径不存在 - `INFER_FAILED`:推理过程异常 --- ## 7. 静态文件访问 本服务已挂载静态文件路由,便于前端或 Java 直接访问保存结果。 访问规则: - 原图访问格式:`/files/uploads_api/{filename}` - 输出图访问格式:`/files/outputs_api/{filename}` 例如: ```text http://127.0.0.1:8001/files/uploads_api/abc.png http://127.0.0.1:8001/files/outputs_api/abc_overlay.png ``` 推荐优先使用接口返回的以下字段: - `image_url` - `mask_url` - `overlay_url` --- ## 8. 返回字段优先级说明(给 Java / 前端) 推荐优先使用以下字段: - `injury_type_code` / `injury_type_name`:类型判断结果 - `severity` / `severity_name`:严重程度结果 - `mask_ratio`:前景占比,可用于阈值判断或记录 - `image_url`:原图访问地址 - `mask_url`:mask 图访问地址 - `overlay_url`:叠加图访问地址 说明: - 当 `RETURN_BASE64=false` 时,推荐以 URL / 路径字段为主 - 当 `RETURN_BASE64=true` 时,返回 base64,但不推荐作为默认交付方案 --- ## 9. 联调测试步骤 1. 启动服务: - 本地:`uvicorn api_server:app --host 0.0.0.0 --port 8000` - Docker:`docker compose up -d --build` 2. 打开 Swagger: - 根据端口映射访问,如 `http://127.0.0.1:8001/docs` 3. 调用接口: - `POST /infer` - Body 使用 `multipart/form-data` - 字段名必须为 `file` 4. 检查返回: - `ok == true` - `injury_type_code` 存在 - `severity` 存在 - `mask_ratio` 在 `[0,1]` - `image_url / mask_url / overlay_url` 可直接访问 --- ## 10. Java 对接最简说明 - 请求方式:`POST` - Content-Type:`multipart/form-data` - 文件字段名:`file` - 成功判断:`ok == true` - 结果展示:优先使用 `overlay_url` - 原图回显:使用 `image_url` - 不建议默认走 base64 长字符串 你可以直接把 Python 侧返回结果映射到 Java DTO,再把: - `overlay_url` 给前端显示结果图 - `image_url` 给前端显示原图 - `injury_type_name` 和 `severity_name` 给前端做文字展示 --- ## 11. Apifox / Swagger 测试指南 ### 11.1 Apifox 新建接口:POST /infer - 请求方式:POST - URL:根据实际端口填写,例如 `http://127.0.0.1:8001/infer` - Body:选择 `form-data` - key:`file` - type:File - value:选择一张图片 ### 11.2 断言建议 - `ok == true` - `mask_ratio` 存在且在 `[0,1]` - `injury_type_code` 必为 `ulcer_present` 或 `ulcer_absent` - `severity` 必为 `mild / moderate / severe` - `overlay_url` 可以直接打开 ### 11.3 Swagger 快速测试 打开: ```text http://127.0.0.1:8001/docs ``` 如果你映射的是其他端口,请对应替换。 --- ## 12. 测试样例说明 建议提供少量联调用测试图像(3~6 张)给 Java 同学,而不是整套训练数据集。 建议覆盖三类: - 明显创口样例 - 轻微创口样例 - 无明显创口样例 每张图建议附带: - 文件名 - 预期类型(如 `ulcer_present`) - 预期说明(如“overlay 中红色区域应覆盖创口位置”) 推荐你私下发一个小压缩包,例如: ```text sample_inputs/ sample_expected/README.txt ``` 其中 `README.txt` 写每张图片的预期结果。 --- ## 13. 部署与排障 ### 13.1 模型未加载 常见原因: - `runs/unet_best.pt` 不存在 - Docker volume 未挂载到正确位置 - 权重文件名不一致 排查方法: - 访问 `GET /health` - 查看容器日志: ```bash docker compose logs -f ``` ### 13.2 Java 访问不到 Python 服务 请检查: - Python 服务是否使用 `--host 0.0.0.0` - Docker 端口是否映射正确 - Java 访问的 IP 和端口是否正确 ### 13.3 结果图打不开 请检查: - 是否返回了 `image_url / mask_url / overlay_url` - `uploads_api/`、`outputs_api/` 是否真的生成了文件 - 静态路由 `/files/...` 是否已挂载 ## 14. 不提交文件说明 本仓库默认不提交: - 模型权重:`runs/`、`*.pt`、`*.pth` - 数据集:`data*`、`datasets*` - 上传原图:`uploads_api/` - 推理输出:`outputs_api/` - 虚拟环境:`.venv/` 如需更新模型效果,只需要替换: ```text runs/unet_best.pt ``` 通常无需修改 Java 调用逻辑。 --- ## 15.联调说明模板 ```text Python 侧 /infer 已联调通过。 请求方式:multipart/form-data 字段名:file 当前返回重点字段: - injury_type_code / injury_type_name - severity / severity_name - mask_ratio - image_url / mask_url / overlay_url 优先使用 overlay_url 做结果展示,image_url 做原图回显。 ```