Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 15 additions & 11 deletions ZSSRforKernelGAN/zssr_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -174,30 +174,34 @@ def preprocess_kernels(kernels, conf):


def kernel_shift(kernel, sf):
# There are two reasons for shifting the kernel :
# There are two reasons for shifting the kernel:
# 1. Center of mass is not in the center of the kernel which creates ambiguity. There is no possible way to know
# the degradation process included shifting so we always assume center of mass is center of the kernel.
# 2. We further shift kernel center so that top left result pixel corresponds to the middle of the sfXsf first
# pixels. Default is for odd size to be in the middle of the first pixel and for even sized kernel to be at the
# top left corner of the first pixel. that is why different shift size needed between odd and even size.
# top left corner of the first pixel. that is why different shift size needed between od and even size.
# Given that these two conditions are fulfilled, we are happy and aligned, the way to test it is as follows:
# The input image, when interpolated (regular bicubic) is exactly aligned with ground truth.

# First calculate the current center of mass for the kernel
current_center_of_mass = measurements.center_of_mass(kernel)
# calculate the shift due to scale factor
kernel_shape = np.array(kernel.shape, dtype=np.float32)[:2]
scale_factor = np.array([sf] if np.isscalar(sf) else sf, dtype=np.float32)[:2]
shift_scale = 0.5 * (1.0 / scale_factor + (kernel_shape - 1) % 2 - 1.0)

# calculate the shift due to center of mass
current_cm = measurements.center_of_mass(kernel)
shift_cm = (kernel_shape - 1.0) / 2 - current_cm

# The second term ("+ 0.5 * ....") is for applying condition 2 from the comments above
wanted_center_of_mass = np.array(kernel.shape) // 2 + 0.5 * (np.array(sf) - (np.array(kernel.shape) % 2))
# Define the shift vector for the kernel shifting (x,y)
shift_vec = wanted_center_of_mass - current_center_of_mass
shift_vec = shift_scale + shift_cm

# Before applying the shift, we first pad the kernel so that nothing is lost due to the shift
# (biggest shift among dims + 1 for safety)
kernel = np.pad(kernel, np.int(np.ceil(np.max(np.abs(shift_vec)))) + 1, 'constant')
padding = np.int(np.ceil(np.max(np.abs(shift_vec)))) + 1
kernel = np.pad(kernel, padding, 'constant')

# Finally shift the kernel and return
kernel = interpolation.shift(kernel, shift_vec)

return kernel
return interpolation.shift(kernel, shift_vec)


def tensorshave(im, margin):
Expand Down
17 changes: 10 additions & 7 deletions imresize.py
Original file line number Diff line number Diff line change
Expand Up @@ -179,19 +179,22 @@ def kernel_shift(kernel, sf):
# Given that these two conditions are fulfilled, we are happy and aligned, the way to test it is as follows:
# The input image, when interpolated (regular bicubic) is exactly aligned with ground truth.

# First calculate the current center of mass for the kernel
current_center_of_mass = measurements.center_of_mass(kernel)
# calculate the shift due to scale factor
kernel_shape = np.array(kernel.shape, dtype=np.float32)[:2]
scale_factor = np.array([sf] if np.isscalar(sf) else sf, dtype=np.float32)[:2]
shift_scale = 0.5 * (1.0 / scale_factor + (kernel_shape - 1) % 2 - 1.0)

# The second ("+ 0.5 * ....") is for applying condition 2 from the comments above
wanted_center_of_mass = np.array(kernel.shape) // 2 + 0.5 * (sf - (kernel.shape[0] % 2))
# wanted_center_of_mass = np.array(kernel.shape) / 2 + 0.5 * (np.array(sf)[0:2] - (kernel.shape[0] % 2))
# calculate the shift due to center of mass
current_cm = measurements.center_of_mass(kernel)
shift_cm = (kernel_shape - 1.0) / 2 - current_cm

# Define the shift vector for the kernel shifting (x,y)
shift_vec = wanted_center_of_mass - current_center_of_mass
shift_vec = shift_scale + shift_cm

# Before applying the shift, we first pad the kernel so that nothing is lost due to the shift
# (biggest shift among dims + 1 for safety)
kernel = np.pad(kernel, np.int(np.ceil(np.max(shift_vec))) + 1, 'constant')
padding = np.int(np.ceil(np.max(np.abs(shift_vec)))) + 1
kernel = np.pad(kernel, padding, 'constant')

# Finally shift the kernel and return
return interpolation.shift(kernel, shift_vec)
Expand Down
26 changes: 15 additions & 11 deletions util.py
Original file line number Diff line number Diff line change
Expand Up @@ -183,30 +183,34 @@ def analytic_kernel(k):


def kernel_shift(kernel, sf):
# There are two reasons for shifting the kernel :
# There are two reasons for shifting the kernel:
# 1. Center of mass is not in the center of the kernel which creates ambiguity. There is no possible way to know
# the degradation process included shifting so we always assume center of mass is center of the kernel.
# 2. We further shift kernel center so that top left result pixel corresponds to the middle of the sfXsf first
# pixels. Default is for odd size to be in the middle of the first pixel and for even sized kernel to be at the
# top left corner of the first pixel. that is why different shift size needed between odd and even size.
# top left corner of the first pixel. that is why different shift size needed between od and even size.
# Given that these two conditions are fulfilled, we are happy and aligned, the way to test it is as follows:
# The input image, when interpolated (regular bicubic) is exactly aligned with ground truth.

# First calculate the current center of mass for the kernel
current_center_of_mass = measurements.center_of_mass(kernel)
# calculate the shift due to scale factor
kernel_shape = np.array(kernel.shape, dtype=np.float32)[:2]
scale_factor = np.array([sf] if np.isscalar(sf) else sf, dtype=np.float32)[:2]
shift_scale = 0.5 * (1.0 / scale_factor + (kernel_shape - 1) % 2 - 1.0)

# calculate the shift due to center of mass
current_cm = measurements.center_of_mass(kernel)
shift_cm = (kernel_shape - 1.0) / 2 - current_cm

# The second term ("+ 0.5 * ....") is for applying condition 2 from the comments above
wanted_center_of_mass = np.array(kernel.shape) // 2 + 0.5 * (np.array(sf) - (np.array(kernel.shape) % 2))
# Define the shift vector for the kernel shifting (x,y)
shift_vec = wanted_center_of_mass - current_center_of_mass
shift_vec = shift_scale + shift_cm

# Before applying the shift, we first pad the kernel so that nothing is lost due to the shift
# (biggest shift among dims + 1 for safety)
kernel = np.pad(kernel, np.int(np.ceil(np.max(np.abs(shift_vec)))) + 1, 'constant')
padding = np.int(np.ceil(np.max(np.abs(shift_vec)))) + 1
kernel = np.pad(kernel, padding, 'constant')

# Finally shift the kernel and return
kernel = interpolation.shift(kernel, shift_vec)

return kernel
return interpolation.shift(kernel, shift_vec)


def save_final_kernel(k_2, conf):
Expand Down