# 特性曲线识别 API 支持批量后台并行识别,以及单图同步识别。 调用上游 `current_image_pipeline.process_new_image`,完成坐标轴检测、矫正、 网格识别、曲线提取、端点补全与分段二次拟合,不调用大模型。 ## 批量并行接口 `POST /api/algorithms/characteristic-curve-recognition/batches`,multipart 使用多个 同名 `files` 字段上传,1~20 张 PNG/JPEG;单张最多 20 MiB,整批最多 100 MiB。 返回 HTTP **202** 和任务 `id`,计算在后台进行。上传结束后不必保持 HTTP 连接。 ```bash curl --fail-with-body \ 'http://127.0.0.1:8080/api/algorithms/characteristic-curve-recognition/batches?detailed=true' \ -F 'files=@/path/to/chart-a.png' \ -F 'files=@/path/to/chart-b.jpg' ``` 响应包含 `id`、`status_url`、`download_url`、`progress` 和 `items`, `Location` 响应头也指向状态接口。可以每 1~2 秒查询一次: ```bash # 将 JOB_ID 替换成提交响应的 id curl --fail-with-body \ 'http://127.0.0.1:8080/api/algorithms/characteristic-curve-recognition/batches/JOB_ID' # 成功图片的 JSON 结果:也可直接使用 items[].result_url curl --fail-with-body \ 'http://127.0.0.1:8080/api/algorithms/characteristic-curve-recognition/batches/JOB_ID/items/0001/result' # 整批结束后下载结果 curl --fail-with-body \ 'http://127.0.0.1:8080/api/algorithms/characteristic-curve-recognition/batches/JOB_ID/download' \ -o characteristic-curves.zip ``` ### 状态和进度 - 批次:`queued → running → packaging → completed / partial_failed / failed`。 - 单图:`queued → running → completed / failed`;服务停机或重启还可能是 `interrupted`。 - `progress` 包含 `total`、`queued`、`running`、`completed`、`failed`、`interrupted`、`finished`。 - `items` 按上传顺序排列,包含独立 `id`、原始文件名、状态、`stage`、起止时间、错误和成功结果链接。 - `stage` 展示当前步骤,例如 `geometry`、`current_image_evidence`、`endpoint_completion`、 `piecewise_c1_fit`。`waiting_for_slot` 表示工作线程正在等待共享计算名额。 - 单张失败、图片损坏或超时不影响其他图片。格式/识别错误写入该图的 `error`; 文件数或大小超限时整批拒绝,队列满返回 429,均不创建任务。 - 同名文件按 `0001`、`0002` 等编号分开存放,不会互相覆盖。 ZIP 内含 `summary.json`(状态和失败清单)及成功图片的 `items/0001/` 等目录; 每图目录内有 `result.json`、原算法输出及离线 `index.html`。即使全部图片失败, 也可下载失败清单。打包未完成时下载返回 409;打包失败时仍可逐图读取成功结果。 每张图成功后即可读取其 JSON,不必等待整个批次结束。 ### 并行、存储和生命周期 服务仍使用一个 HTTP worker,由后台工作线程调度多个独立算法子进程。 单图请求和所有批次共享 `ALGORITHM_MAX_PARALLEL`,不会各自无限启动进程。 批量任务等待空位;同步单图接口在名额占满时返回 429。 在 `.env` 中配置,修改后重启: ```dotenv ALGORITHM_MAX_PARALLEL=2 ALGORITHM_MAX_PENDING_IMAGES=100 ALGORITHM_RESULT_TTL_HOURS=24 ALGORITHM_JOB_DIR=data/algorithm_jobs ``` 待处理上限包括所有批次中排队及执行中的图片。单图超时从取得计算名额开始计时, 每张最多 180 秒;整批可能因排队需要更久。增加并行数会增加 CPU 和内存占用。 任务状态与结果保存到 `ALGORITHM_JOB_DIR`,每个批次独立目录;默认在批次完成后 保留 24 小时。每分钟以及访问任务时清理过期结果,过期后查询返回 404。 已开始的下载可继续。处理结束后移除上传暂存文件;成功结果包中保留原图供复核。 正常关闭服务时等待已开始的图片计算结束,将未开始图片标为 `interrupted`。 服务重启会恢复已完成结果,把遗留的排队或运行任务标为中断,不自动重跑。 可按失败/中断清单重新提交。任务 ID 是当前接口的访问凭据;沿用项目现有的内网 部署方式,没有新增用户鉴权。不要用多个 HTTP worker 共用此目录。 ## 单图同步接口 `POST /api/algorithms/characteristic-curve-recognition`,multipart 字段 `file`。 ```bash # JSON:模型、坐标轴、变换矩阵、网格线/单元、耗时 curl --fail-with-body -X POST \ 'http://127.0.0.1:8080/api/algorithms/characteristic-curve-recognition' \ -F 'file=@/path/to/chart.png' -o result.json # ZIP:完整结果及阶段图片;解压后打开 index.html curl --fail-with-body -X POST \ 'http://127.0.0.1:8080/api/algorithms/characteristic-curve-recognition?output=zip&detailed=true' \ -F 'file=@/path/to/chart.png' -o characteristic-curve-recognition.zip ``` 也可在 `/docs` 的 algorithms 分组上传测试。 ### 单图返回值 默认 `output=json`,返回: - `algorithm`:`characteristic_curve_recognition`。 - `model`:原算法模型,包括 `pipeline_version`、`curves`、拟合与 QC 状态。 - `geometry`:`axes`、`rectification`、`plot_bounds` 和 `grid`。 - `timing`:总耗时及各阶段耗时。 `geometry.grid.mode` 为 `detected`(检测到真实网格)或 `generated` (根据刻度生成几何网格)。几何中的矫正信息保留正逆变换矩阵。 最终曲线使用矫正图像素坐标,物理坐标尚未标定。`execution_status=completed` 表示计算完成;`quality_status=needs_review`、警告及曲线质量状态均按原算法保留。 `output=zip` 返回 `application/zip`,包含 `result.json`、`final_model.json`、 矫正图、最终叠图、重绘图、诊断文件及离线检查页。`detailed=true` 增加阶段 检查图片,不改变识别结果;默认 false。JSON 内的诊断相对路径仅在 ZIP 中可用。 文件只在请求期间保存,JSON 请求不会生成可供随后下载的长期记录。 ## 执行限制与错误 单图同步接口的客户端和反向代理读取超时应大于 180 秒。共享并行名额占满时 返回 429(`Retry-After: 5`)。计算在独立子进程中进行,超过 180 秒终止。请求临时目录在成功、失败、超时后清理;客户端提前断开时,已开始 的计算可能继续,仍受上述超时限制。 图片最多 20 MiB、1600 万像素,宽高均至少 32 像素。服务端检查实际文件内容, 不使用上传文件名作为磁盘路径。当前接口不接收服务端路径、历史标注或 OCR 密钥。 | HTTP | detail.code | 含义 | | --- | --- | --- | | 413 | image_too_large | 超过文件大小限制 | | 422 | invalid_image | 格式、解码或图片尺寸不合法 | | 422 | detection_failed | 算法无法从图片识别图表 | | 429 | algorithm_busy | 已有计算运行 | | 429 | algorithm_queue_full | 批量队列容量不足 | | 422 | invalid_batch_size | 批次图片数不合法 | | 413 | batch_too_large | 整批上传超过 100 MiB | | 404 | batch_not_found / item_not_found | 任务已过期或不存在 | | 409 | result_unavailable / batch_not_finished / archive_unavailable | 结果尚未就绪或不可用 | | 503 | algorithm_unavailable | 未安装算法依赖 | | 504 | algorithm_timeout | 计算超时 | | 500 | algorithm_failed | 未预期的算法错误,查看服务日志 | FastAPI 对缺少 file 或非法查询参数的校验仍返回标准 422 错误数组。 ## 来源与维护 `vendor/chart_axis_detector/` 是 2026-09-30 从“网格查找”工作区复制的源码快照, 包含该工作区尚未提交的算法修改;没有复制桌面 UI、配置密钥或历史数据。 `UPSTREAM.json` 记录基础 commit 和复制时每个原文件的 SHA-256。 唯一的本地算法改动是在 `diagnostics/geometry.json` 增加 `grid.to_dict()` 导出, 不改变计算过程。 使用 `numpy` 和 `opencv-contrib-python-headless`,后者保留 thinning 功能, 无需服务器 GUI 库。不要同时安装其他 OpenCV Python 发行包。 在项目根目录安装 `release/requirements.lock` 后重启服务即可。 ```bash .venv/bin/python -m pytest tests/test_algorithms.py tests/test_algorithm_batches.py ```