Nguyên tắc: ML định vị vùng — phép tính deterministic ra số. Dưới đây là các thuật toán/filter theo từng giai đoạn,
kèm mục đích & lý do chọn.
1Ingest & HU
| Thuật toán / Filter | Thư viện | Mục đích & lý do |
| Modality LUT (Rescale Slope/Intercept) | GDCM / SimpleITK | Chuyển pixel lưu trữ → HU thật. Điều kiện sống còn cho mọi phép đo mỡ. |
| Spatial sort theo ImagePositionPatient·normal | GDCM | Xếp lát cắt đúng thứ tự không gian (không dựa InstanceNumber dễ sai). |
| Oracle cross-check (SimpleITK vs pydicom) | pydicom | Kiểm chứng HU độc lập voxelwise → bắt bug "rescale không áp". |
| Debounce completeness | watchdog | Gom DICOM theo series, chờ đủ (folder không có tín hiệu "done"). |
2Silver labeling (tạo nhãn pericardium)
| Thuật toán / Filter | Thư viện | Mục đích & lý do |
| TotalSegmentator (nnU-Net 3mm) | TotalSegmentator | Khoanh whole-heart làm mốc localize. |
| Convex hull theo lát cắt | skimage convex_hull_image | Xấp xỉ khoang pericardium (lấp rãnh vành). → sinh rìa dư ở chỗ lõm |
| Dilation bằng Euclidean Distance Transform | scipy distance_transform_edt | Nới ~3mm bắt lớp mỡ sát cơ tim. Thay dilation structuring-element (nhanh O(n), đúng mm — trước đó box 13×19×19 ngốn 3–4× thời gian/ca). |
| HU window [−190, −30] | numpy | Ngưỡng mô mỡ (deterministic). |
3Training — nnU-Net segmenter
| Thuật toán / Filter | Thư viện | Mục đích & lý do |
| CTNormalization (clip p0.5–p99.5 + z-score) | nnU-Net | Chuẩn hóa cường độ CT ổn định theo thống kê foreground. |
| Spline resampling (data order 3, seg order 1) | nnU-Net | Đưa về target spacing đồng nhất trước khi train/infer. |
| 3D U-Net (PlainConvUNet) + deep supervision | nnU-Net | Kiến trúc segment; deep supervision ổn định hội tụ. |
| Data augmentation (xoay/scale/gamma/mirror…) | batchgenerators | Chống overfit trên 200 ca. |
| Loss Dice + Cross-Entropy · LR poly-decay | nnU-Net | Chuẩn segmentation; poly-decay khớp số epoch (250/100). |
| Sliding-window + Gaussian patch weighting | nnU-Net | Ghép patch mượt, giảm sọc biên patch. |
| 3d_lowres vs 3d_fullres | nnU-Net | Đánh đổi độ phân giải ↔ tốc độ inference (~3× nhanh hơn ở lowres). |
4Tối ưu edge (TensorRT)
| Thuật toán / Filter | Thư viện | Mục đích & lý do |
| ONNX export (opset 17) | torch.onnx | Trung gian chuẩn để build engine. Verify argmax vs torch 99.996%. |
| TensorRT FP16 quantization | TensorRT 10.4 | Engine nhanh, self-contained. Parity vs FP32: Dice 0.9997, ΔEAT <0.11 mL. |
| Tắt torch.compile | nnUNet_compile=0 | Triton không có wheel aarch64 → tắt để tránh crash train step. |
5Post-processing — cleanup ROI (mới)
| Thuật toán / Filter | Thư viện | Mục đích & lý do |
| Connected components 26-kề → giữ mảnh lớn nhất | scipy ndimage.label | Bỏ island false-positive (mạch lớn tách rời). Ca 33: bỏ 78.9 mL ROI → EAT 92.7→82.6. |
| Binary fill holes (3D) | scipy binary_fill_holes | Lấp hốc kín bên trong → ROI đặc, đo mỡ nhất quán. |
| remove_small_objects | skimage | Dọn đốm nhỏ khi consolidate mỡ. |
| Binary closing (consolidate mỡ) | scipy | Gộp voxel mỡ gần nhau → mặt 3D mượt, bớt lỗ rỗ. |
An toàn: keep-largest-CC chỉ tác động ca có island (33, 45, 76, 114); ca đã sạch (8, 75, 91, 154) không đổi. EAT giảm trung bình 2.5 mL.
6Trực quan hóa 3D
| Thuật toán / Filter | Thư viện | Mục đích & lý do |
| Gaussian smoothing (pre-marching-cubes) | scipy gaussian_filter | Làm mượt mask nhị phân → mặt cong mịn (kiểu 3D Slicer). |
| Marching Cubes | skimage marching_cubes | Dựng lưới bề mặt (isosurface) từ mask. |
| Downsample bbox (STEP=4) | numpy | Giảm ~15× tam giác → render nhanh (~1.8 phút/ca) mà vẫn mịn. |
| Lambertian shading (normal·light) | matplotlib LightSource | Đổ bóng theo pháp tuyến mặt → chiều sâu, dễ nhìn. |
7Deterministic measure
| Thuật toán / Filter | Thư viện | Mục đích & lý do |
| Voxel counting × thể tích voxel | numpy | EAT (mL) = |voxel mỡ trong ROI| × spacing. Hoàn toàn audit được. |
| Bland-Altman · Dice | numpy | Harness chấm điểm: sai số mL & độ trùng vùng. |