Metadata-Version: 2.4
Name: minimal-seg3d
Version: 0.1.0
Summary: Minimal 3D medical image segmentation with vHeat_Grid backbone + FPN3D + chunked UNet decoder
Requires-Python: >=3.9
Description-Content-Type: text/markdown
Requires-Dist: numpy>=1.21
Requires-Dist: torch>=2.3
Requires-Dist: timm>=0.9
Provides-Extra: viz
Requires-Dist: matplotlib>=3.5; extra == "viz"
Provides-Extra: nii
Requires-Dist: nibabel>=5.0; extra == "nii"

# minimal-seg3d — 最小 3D 医学图像分割包

基于 vHeat_Grid 的最小可运行 3D 分割方案，独立打包发布到 PyPI：
vHeat_Grid backbone + FPN3D neck + 分块 UNet Decoder，单 GPU 训练 / 推理即开即用。

> 与 vHeat3D 仓库的关系：本项目是 vheat3d/models/backbone.py 的**独立发布版**，
> backbone 以 vendored 副本形式放在 `minimal_seg3d/vendor/backbone.py`，
> 不依赖外部 vheat3d 包；若上游 backbone 更新需手动同步该副本。

## 安装

```bash
# 从 PyPI 安装（核心：训练 + 推理）
pip install minimal-seg3d

# 完整功能（推理 PNG 可视化 + .nii.gz 输出）
pip install "minimal-seg3d[viz,nii]"

# 本地源码安装（开发模式）
pip install -e .
```

> `torch>=2.3` 会被自动安装；如需特定 CUDA / CPU 版本，建议先按
> [pytorch.org](https://pytorch.org/get-started/locally/) 的指引自行安装 torch。

## 文件结构

```
minimal-seg3d/
├── pyproject.toml        # 打包 / 发布配置（PyPI 名: minimal-seg3d）
├── README.md
└── minimal_seg3d/
    ├── __init__.py       # 版本号 + 公共 API 导出
    ├── model.py          # MinimalSeg3D：vHeat_Grid backbone + FPN3D + UNet Decoder
    ├── loss.py           # 加权 Dice + CE 损失
    ├── dataset.py        # DummyDataset（smoke test）/ NpzDataset（真实数据）
    ├── metrics.py        # per-class Dice score
    ├── train.py          # 训练 CLI：minimal-seg3d-train
    ├── infer.py          # 推理 + 可视化 CLI：minimal-seg3d-infer
    └── vendor/
        └── backbone.py   # vendored vHeat_Grid backbone
```

## 快速验证（无需数据）

```bash
minimal-seg3d-train --smoke_test
# 等价： python -m minimal_seg3d.train --smoke_test
```

## 真实数据训练

数据格式与 `preprocess_vessel.py` 输出兼容：每个 `.npz` 包含
`image(float16, [0,1])` + `label(uint8)` + `weight(float32)`，
放在 `cache_dir/train/` 和 `cache_dir/valid/` 子目录下。

```bash
minimal-seg3d-train \
    --cache_dir /path/to/npz_cache \
    --vol_size 128 128 128 \
    --num_classes 4 \          # 0=背景 1=动脉 2=静脉 3=支气管
    --out_scale 3 \            # 全分辨率输出
    --epochs 100 \
    --output_dir ./output/minimal_seg
```

可选的 JSONL 训练日志（每行一个合法 JSON 对象）：

```bash
minimal-seg3d-train --cache_dir ... --jsonl_dir /path/to/logs
```

## 推理

```bash
minimal-seg3d-infer \
    --ckpt output/minimal_seg/best_model.pth \
    --cache_dir /path/to/npz_cache \
    --out_dir output/minimal_seg/pred \
    --save_nii
```

## 模型参数（默认 128³ 输入）

| 组件 | 说明 |
|------|------|
| Backbone | vHeat_Grid (patch=8, window=4, dim=[96,192,384,768], depths=[2,2,6,2]) |
| Neck | FPN3D 4 尺度自顶向下融合 → 64 ch |
| Decoder | 3 级 skip-connection + 渐进 2× 上采样（out_scale=3 → 全分辨率）+ **三维分块解码** |
| Loss | 加权 Dice (0.5) + 加权 CE (0.5)，权重来自预处理的骨架权重图 |

## 分块解码（大体积节省显存）

`ChunkedDecoder` 把 f0 特征沿 D/H/W 切成 `chunk_z × chunk_y × chunk_x` 块网格，
每块独立跑 `final_up + head` 并用 `activation checkpoint` 包裹，
峰值显存 ≈ 单块解码激活 + 拼接后的 logits，大幅低于整体解码。

```bash
# 512³ 输入，切成 2×2×2=8 块
minimal-seg3d-train \
    --vol_size 512 512 512 \
    --norm in \              # 切块时必须用 InstanceNorm，避免 BN running stats 发散
    --chunk_z 2 --chunk_y 2 --chunk_x 2 \
    --chunk_overlap 1        # 块间 1 体素重叠，缓解边界伪影
```

chunk 均为 1 时退化为整体解码，行为与非分块完全一致。

## 以库的方式使用

```python
from minimal_seg3d import MinimalSeg3D, seg_loss, NpzDataset

model = MinimalSeg3D(num_classes=4, img_size=(128, 128, 128))
# x: (B, 1, D, H, W) → logits (B, C, D, H, W)
logits = model(x)
```
