CBT_project/imaging/resample.py

50 lines
2.7 KiB
Python
Raw Normal View History

2026-04-10 05:25:27 +00:00
import numpy as np
import SimpleITK as sitk
from config.constant import LABEL_MAP
def resample_img(sitk_image, out_spacing=[0.5, 0.5, 0.5], is_label=False,
interpolator=None, cval=None):
"""重採樣到 out_spacing完整保留物理範圍邊界 margin 不裁剪):
- CTis_label=False线性插值本流程是上採樣~0.75-1mm -> 0.5mm
线性即無漣波的理想重建B-spline 會在身體 margin 等強邊界產生
非物理的 undershoot/overshoot量測~0.5% 體素低於 air floor
-1024 HU最低 -1274沿體輪廓形成黑暈
- 預設填充值 = 影像最小值air而非 GetPixelIDValue()
int16 CT 回傳佔位值 2 軟組織會把 margin 填成軟組織
- 輸出尺寸用 ceil 覆蓋原物理尺寸round 會讓遠端端點被裁 0.25mm
labelis_label=True最近邻填充 0
interpolator明確指定插值器None = is_label Linear / NearestNeighbor
例如 SMD piecewise-linear 場用 sitk.sitkBSpline三阶 B 样条对分段
线性场为精确重建無漣波
cval明確指定填充值None = 上述預設
"""
original_spacing = np.array(sitk_image.GetSpacing(), dtype=float)
original_size = np.array(sitk_image.GetSize())
out_spacing = np.array(out_spacing, dtype=float)
physical = original_size * original_spacing
out_size = [max(1, int(np.ceil(physical[i] / out_spacing[i] - 1e-6)))
for i in range(3)]
2026-04-10 05:25:27 +00:00
resample = sitk.ResampleImageFilter()
resample.SetOutputSpacing(out_spacing.tolist())
2026-04-10 05:25:27 +00:00
resample.SetSize(out_size)
resample.SetOutputDirection(sitk_image.GetDirection())
resample.SetOutputOrigin(sitk_image.GetOrigin())
resample.SetTransform(sitk.Transform())
if is_label:
resample.SetInterpolator(interpolator or sitk.sitkNearestNeighbor)
resample.SetDefaultPixelValue(cval if cval is not None else 0)
elif interpolator is not None:
resample.SetInterpolator(interpolator)
# SMD 等 signed 場的填充:預設 0 = 表面層值(比影像 min/max 安全,
# 不會製造假的零穿越環);可用品值可用 cval 覆蓋
resample.SetDefaultPixelValue(float(cval) if cval is not None else 0.0)
2026-04-10 05:25:27 +00:00
else:
resample.SetInterpolator(sitk.sitkLinear)
# air 值 = 影像最小 HUstatistics 濾波器 streaming 計算,不載入整張 array
stats = sitk.StatisticsImageFilter()
stats.Execute(sitk_image)
resample.SetDefaultPixelValue(float(stats.GetMinimum()))
2026-04-10 05:25:27 +00:00
return resample.Execute(sitk_image)