@@ -214,7 +214,7 @@ def __init__(
214214 IEEE Transactions in Medical Imaging. Vol.22, No.1,
215215 January 2003. pp.120-128.
216216
217- num_bins: number of bins for intensity
217+ num_bins: number of bins for intensity. The b-spline kernel requires more than 4 bins.
218218 sigma_ratio: a hyper param for gaussian function
219219 reduction: {``"none"``, ``"mean"``, ``"sum"``}
220220 Specifies the reduction to apply to the output. Defaults to ``"mean"``.
@@ -231,6 +231,8 @@ def __init__(
231231 bin_centers = torch .linspace (0.0 , 1.0 , num_bins ) # (num_bins,)
232232 sigma = torch .mean (bin_centers [1 :] - bin_centers [:- 1 ]) * sigma_ratio
233233 self .kernel_type = look_up_option (kernel_type , ["gaussian" , "b-spline" ])
234+ if self .kernel_type == "b-spline" and num_bins <= 4 :
235+ raise ValueError (f"num_bins must be greater than 4 for b-spline kernel, got { num_bins } " )
234236 self .num_bins = num_bins
235237 # declared as buffers so they move with the module (e.g. ``.to(device)``); only populated for the
236238 # gaussian kernel, hence the ``Tensor`` annotation reflects the type at the use sites in that path.
@@ -283,7 +285,13 @@ def parzen_windowing_b_spline(self, img: torch.Tensor, order: int) -> tuple[torc
283285 # window.
284286 _max , _min = torch .max (img ), torch .min (img )
285287 padding = 2
286- bin_size = (_max - _min ) / (self .num_bins - 2 * padding )
288+ value_range = _max - _min
289+ bin_size = value_range / (self .num_bins - 2 * padding )
290+ bin_size = torch .where (
291+ value_range > 0 ,
292+ bin_size ,
293+ torch .ones_like (bin_size ),
294+ )
287295 norm_min = torch .div (_min , bin_size ) - padding
288296
289297 # assign bin/window index to each voxel
@@ -293,6 +301,8 @@ def parzen_windowing_b_spline(self, img: torch.Tensor, order: int) -> tuple[torc
293301 window_term = window_term .reshape (window_term .shape [0 ], - 1 , 1 ) # (batch, num_sample, 1)
294302 bins = torch .arange (self .num_bins , device = window_term .device ).reshape (1 , 1 , - 1 ) # (1, 1, num_bins)
295303 sample_bin_matrix = torch .abs (bins - window_term ) # (batch, num_sample, num_bins)
304+ if sample_bin_matrix .dtype == torch .float16 :
305+ sample_bin_matrix = sample_bin_matrix .float () # avoid overflow in the cubic polynomial
296306
297307 # b-spleen kernel
298308 # (4 - 6 * abs ** 2 + 3 * abs ** 3) / 6 when 0 <= abs < 1
0 commit comments