计算patch size实际的移动的step步长
#静态方法无需实例化就可以直接调用
@staticmethod
def _compute_steps_for_sliding_window(patch_size: Tuple[int, ...], image_size: Tuple[int, ...], step_size: float) -> List[List[int]]:
assert [i >= j for i, j in zip(image_size, patch_size)], "image size must be as large or larger than patch_size"
assert 0 < step_size <= 1, 'step_size must be larger than 0 and smaller or equal to 1'
# step_size必须小于1是因为patch必须相互覆盖,等于1 就是image size == patch size;step width<== patch_size*step_size
# our step width is patch_size*step_size at most, but can be narrower. For example if we have image size of
# 110, patch size of 64 and step_size of 0.5, then we want to make 3 steps starting at coordinate 0, 23, 46
target_step_sizes_in_voxels = [i * step_size for i in patch_size]
num_steps = [int(np.ceil((i - k) / j)) + 1 for i, j, k in zip(image_size, target_step_sizes_in_voxels, patch_size)]
steps = []
for dim in range(len(patch_size)):
# the highest step value for this dimension is
max_step_value = image_size[dim] - patch_size[dim]
if num_steps[dim] > 1:
actual_step_size = max_step_value / (num_steps[dim] - 1)
else:
actual_step_size = 99999999999 # does not matter because there is only one step at 0
steps_here = [int(np.round(actual_step_size * i)) for i in range(num_steps[dim])]
steps.append(steps_here)
return steps
输入:
-
patch_size
-
image_size
-
step_size:是一个浮点数,也就是patch size的百分比,patch移动肯定是需要相互覆盖的,可以认为是step的最大值。
- image size<=patch size
- step_size是一个百分比。target_step_sizes_in_voxels= step_size * patch_size,计算step_size对应的实际步长
计算多少个步长能够将整个image覆盖
- 计算num_steps对应每一步需要移动的step步长
当num_step=1的时候,其实就是image_size=patch_size,也就是step=0;
- steps[dim][0]=0,要从第一个patch开始。而且steps[dim][-1] + patch_size[dim] == image_size[dim],肯定要涵盖整张图的。
-
[steps[dim][i + 1] <= steps[dim][i] + patch_size[dim] for i in range(num_steps[dim] - 1)]相邻patch之间不能有间隔。
-
[steps[dim][i] + np.ceil(target_step_sizes_in_voxels[dim]) >= steps[dim][i + 1] for i in range(num_steps[dim] -1)]两个相邻的step肯定比target_step_sizes_in_voxels小,因为target_step_sizes_in_voxels本身就是等间隔,也就是最大的那个间隔,相邻的patch不能有空隙。
def _verify_steps(self, steps, patch_size, image_size, step_size):
debug_information = 'steps= %s\nimage_size= %s\npatch_size= %s\nstep_size= %0.4f' % (str(steps),
str(image_size),
str(patch_size), step_size)
target_step_sizes_in_voxels = [i * step_size for i in patch_size]
# this code is copied form the current implementation. Not ideal, but I don't know hoe else to the the
# expected num_steps
num_steps = [int(np.ceil((i - k) / j)) + 1 for i, j, k in zip(image_size, target_step_sizes_in_voxels,
patch_size)]
self.assertTrue(all([len(i) == num_steps[j] for j, i in enumerate(steps)]),
'steps do not match expected num_steps %s. \nDebug: %s' % (str(num_steps), debug_information))
for dim in range(len(steps)):
# first step must start at 0
self.assertTrue(steps[dim][0] == 0)
# last step + patch size must equal to image size
self.assertTrue(steps[dim][-1] + patch_size[dim] == image_size[dim], 'not the whole image is covered. '
'\nDebug: %s' % debug_information)
# there cannot be gaps between adjacent predictions
self.assertTrue(all([steps[dim][i + 1] <= steps[dim][i] + patch_size[dim] for i in
range(num_steps[dim] - 1)]), 'steps are not overlapping or touching. dim: %d, steps:'
' %s, image_size: %s, patch_size: %s, step_size: '
'%0.4f' % (
dim, str(steps[dim]), str(image_size[dim]), str(patch_size[dim]), step_size))
# two successive steps cannot be further apart than target_step_sizes_in_voxels
self.assertTrue(all([steps[dim][i] + np.ceil(target_step_sizes_in_voxels[dim]) >= steps[dim][i + 1] for i
in range(num_steps[dim] -1)]),
'consecutive steps are too far apart. Steps: %s, dim: %d. \nDebug: %s' %
(str(steps[dim]), dim, debug_information))