gaoshutao 1aa282a08e feat: 接入特性曲线识别算法并支持批量并行处理 1 lună în urmă
..
vendor 1aa282a08e feat: 接入特性曲线识别算法并支持批量并行处理 1 lună în urmă
README.md 1aa282a08e feat: 接入特性曲线识别算法并支持批量并行处理 1 lună în urmă
UPSTREAM.json 1aa282a08e feat: 接入特性曲线识别算法并支持批量并行处理 1 lună în urmă
__init__.py 1aa282a08e feat: 接入特性曲线识别算法并支持批量并行处理 1 lună în urmă
batch.py 1aa282a08e feat: 接入特性曲线识别算法并支持批量并行处理 1 lună în urmă
service.py 1aa282a08e feat: 接入特性曲线识别算法并支持批量并行处理 1 lună în urmă
worker.py 1aa282a08e feat: 接入特性曲线识别算法并支持批量并行处理 1 lună în urmă

README.md

特性曲线识别 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 连接。

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 秒查询一次:

# 将 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 中配置,修改后重启:

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。

# 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 后重启服务即可。

.venv/bin/python -m pytest tests/test_algorithms.py tests/test_algorithm_batches.py