This commit is contained in:
Ubuntu
2026-07-03 16:58:28 +08:00
commit 32b43f85bd
6240 changed files with 1987678 additions and 0 deletions
@@ -0,0 +1,128 @@
# Python后端 JSON数据尿检识别 - 技术实施方案
> 基于 C++ `ProcessJsonDataRequest` 逐行翻译到 Python
> 依赖:`/usr/local/Models/ml.json` + `*.data` (OpenCV RTrees 模型)
---
## 1. 可行性验证
| 检查项 | 状态 |
|--------|------|
| OpenCV 版本 | 4.13.0 ✅ |
| cv2.ml.RTrees_load() 加载 .data 文件 | ✅ uro_0, glu_1, glu-rts-M1 均加载成功 |
| RTrees.predict() 预测 | ✅ `predict(sample)` 返回浮点数 |
| /usr/local/Models/ 所有模型文件存在 | ✅ 14项×2+ (Green+Rts) 全部存在 |
| ml.json 配置完整 | ✅ 包含所有14项×21种试纸类型配置 |
---
## 2. 总体架构
```
POST /api/urinecheck/analyze-json
│
├── 接收 JSON body (与txt文件格式一致)
│
├── MLConfigLoader ─── 解析 /usr/local/Models/ml.json
│ ├── 构建 model_lookup[paperType][position] = (model, indexFunc, indexMap)
│ └── 标注 PRO/MAU/SG/pH 的 position
│
├── UrineJsonRecognizer
│ ├── 1. 解析输入JSON
│ ├── 2. extract paperType from extend
│ ├── 3. 逐帧处理
│ │ └── 每帧: mapData[id→[6 floats]] → ML推理 → {position: rawIndex}
│ ├── 4. CountResultsModal (多帧投票)
│ ├── 5. PRO/MAU + SG/PH 关联修正
│ ├── 6. indexMap 映射
│ └── 7. 构建输出JSON
│
└── 返回 {"score":"100", "status":"0", "data": [{id, index}, ...]}
```
---
## 3. 实施步骤
### Step 1: 新建 `ml_config.py` — ML配置加载器
**功能**:解析 `/usr/local/Models/ml.json`,构建运行时查表结构
```python
class MLConfigLoader:
def load(self):
# 解析 ml.json
# 对每个 item (uro/glu/ket/...):
# 对每个 model entry (positon, id, filepath, algorithm, indexmap):
# paperType = j (model数组中的索引)
# if positon >= 0:
# models[paperType][positon] = RTrees.load(filepath)
# result_funcs[paperType][positon] = indexFuncName
# stat_ids[paperType][positon] = id
# index_maps[paperType][positon] = [int(x) for x in indexmap.split(',')]
# if name == 'pro': positionsPro[paperType] = positon
# ... etc
```
### Step 2: 新建 `json_recognizer.py` — JSON数据识别器
**核心类**:`UrineJsonRecognizer`
```python
class UrineJsonRecognizer:
def recognize(self, json_data: dict) -> dict:
# 完整复制 ProcessJsonDataRequest 逻辑
...
def _get14_results(self, map_data: dict, paper_type: int) -> dict:
# 完整复制 UrineCheck14::Get14Results(mapData, X) 逻辑
...
```
**各检测项的结果索引修正函数**(直接翻译C++):
- `_red_pro_index(p, h)` — if ret>0 and (h<25 or h>110) → 0
- `_red_mau_index(p, h)` — if ret>0 and (h<30 or h>115) → 0
- `_red_ket_index(p, h)` — if ret>1 and 45<h<145 → 0
- `_red_nit_index(p, h)` — if ret>0 and 40<h<140 → 0
- `_red_uro_index(p, h)` — if ret>0 and 25<h<150 → 0
- 其余直接 `round(p)`
### Step 3: 添加 API 路由
在 `routers/urinecheck.py` 中添加:
```python
@router.post("/analyze-json")
async def analyze_json(request: JsonDataRequest, ...):
recognizer = get_recognizer() # 全局单例
return recognizer.recognize(request.model_dump())
```
### Step 4: 在 `schemas.py` 中添加请求模型
### Step 5: 在 `app.py` 中初始化识别器(startup event)
---
## 4. 关键差异注意事项
| C++ | Python |
|-----|--------|
| Json::Value | dict/list |
| map<int, Ptr<RTrees>> | dict[int, cv2.ml.RTrees] |
| `atoi()` string→int | `int()` 或 `float()` |
| `split(s, ',', vs)` | `s.split(',')` |
| `GetModal1()` → 众数 | `collections.Counter.most_common(1)` |
| `GetPredictResultVal(data)` | `model.predict(np.array([data], dtype=np.float32))` |
---
## 5. 文件清单
| 文件 | 操作 | 功能 |
|------|------|------|
| `backend/ml_config.py` | **新建** | ML配置加载器 |
| `backend/json_recognizer.py` | **新建** | JSON数据识别核心逻辑 |
| `backend/schemas.py` | **修改** | 添加 JsonDataRequest |
| `backend/routers/urinecheck.py` | **修改** | 添加 /analyze-json 路由 |
| `backend/app.py` | **修改** | 启动时初始化识别器 |