feat(ceus,segment): 任务书 02 第二阶段——分割和后半段算法

- ceus 迁入 polygons、dark_region、reference_region、tic_fitting、tic、anchor_frames、
  perfusion_metrics、trajectory、tic_curves、tic_plot、overlay,旧测试照搬(改 import 与配置读取)。
- 对外两段接口:prepare_segmentation(第 1–2 步)与 quantify_case(第 4–9 步)。
- 第 3 条:删掉 D1 取医生标注时刻的模式,D1 只从拟合曲线算。
- 第 4 条:F1/F2 取视频第 20−X、60−X 秒(X 为视频第 0 秒时已推注的秒数),落在视频外记未定位。
- 绿框融合权重、紫圈颜色阈值照搬;关键帧容差窗口的出处写进 ceus.yaml 注释。
- segment:同一进程调用 MedSAM2,设置写进 ceus.yaml 的 segment 段,全部必填;gpu 测试真跑通过。
- 依赖加 scipy、matplotlib、medsam2(可编辑安装,不编译 CUDA 扩展);uv 只解析 linux x86_64。
- 导入契约:只有 segment 引用 torch、sam2;segment 不引用其他 cadx 模块。

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-16 05:07:02 -04:00
parent 9a916c65a5
commit 150eb5f6ae
35 changed files with 10655 additions and 505 deletions
+29 -4
View File
@@ -4,12 +4,15 @@ version = "0.0.0"
description = "胰腺囊性肿瘤多模态会诊诊断的研究代码"
requires-python = ">=3.12"
dependencies = [
"matplotlib>=3.11.2",
"medsam2",
"numpy>=2.5.4",
"opencv-python-headless>=5.0.0.93",
"openpyxl>=3.1.5",
"pillow>=12.3.0",
"pydantic>=2.14.1",
"pyyaml>=6.0.3",
"scipy>=1.18.1",
]
[dependency-groups]
@@ -23,6 +26,14 @@ dev = [
"types-openpyxl>=3.1.5.20260827",
]
[tool.uv]
# 只在本机和远程服务器(都是 Linux x86_64)上跑;只为这一种平台解析依赖,
# 免得 torch 的各平台 CUDA 轮子都要下载一遍。
environments = ["sys_platform == 'linux' and platform_machine == 'x86_64'"]
[tool.uv.sources]
medsam2 = { path = "reference/MedSAM2", editable = true }
[build-system]
requires = ["hatchling>=1.26"]
build-backend = "hatchling.build"
@@ -50,7 +61,8 @@ pythonVersion = "3.12"
typeCheckingMode = "strict"
venvPath = "."
venv = ".venv"
extraPaths = ["tests"]
# medsam2 以 setuptools 的导入钩子方式可编辑安装,pyright 跟不过去,直接指给它源码目录。
extraPaths = ["tests", "reference/MedSAM2"]
[tool.pytest.ini_options]
testpaths = ["tests"]
@@ -69,12 +81,25 @@ root_packages = ["cadx"]
include_external_packages = true
[[tool.importlinter.contracts]]
# design 0001:torch 与 MedSAM2 只许出现在分割模块(模块落地时在这里放行 cadx.segment)。
name = "torch 与 sam2 不进 cadx"
# design 0001:torch 与 MedSAM2 只许出现在分割模块。import-linter 不能写「除 segment 外的 cadx」
# (只有 ignore_imports 能开例外),所以逐个列出其余模块;新模块落地时加进 source_modules。
name = "cadx 里只有 segment 引用 torch、sam2"
type = "forbidden"
source_modules = ["cadx"]
source_modules = [
"cadx.delivery", "cadx.library", "cadx.answers", "cadx.runs", "cadx.build", "cadx.ceus",
]
forbidden_modules = ["torch", "sam2"]
[[tool.importlinter.contracts]]
# 结构.md 第三部分依赖表:segment 不引用其他 cadx 模块(它不认识分屏和绿框)。
name = "segment 不引用其他 cadx 模块"
type = "forbidden"
source_modules = ["cadx.segment"]
forbidden_modules = [
"cadx.delivery", "cadx.library", "cadx.answers", "cadx.runs", "cadx.build",
"cadx.ceus", "cadx.llm", "cadx.ledger", "cadx.consult", "cadx.evaluate", "cadx.verdicts",
]
[[tool.importlinter.contracts]]
# 结构.md 第三部分依赖表:外部层与格式层的模块不依赖其他 cadx 模块。
name = "delivery、library、answers、runs 互不依赖"