From 82756d8ce96b7b9cd98f6aa6cda794022b3bf42a Mon Sep 17 00:00:00 2001 From: Ben Feinstein Date: Sun, 22 Dec 2019 14:20:46 +0200 Subject: [PATCH 1/9] Fix 1/4-pixel shift (1/2) --- ZSSRforKernelGAN/zssr_utils.py | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/ZSSRforKernelGAN/zssr_utils.py b/ZSSRforKernelGAN/zssr_utils.py index 0482e00..2261194 100644 --- a/ZSSRforKernelGAN/zssr_utils.py +++ b/ZSSRforKernelGAN/zssr_utils.py @@ -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[:2], dtype=np.float32) + scale_factor = np.array(sf[:2], dtype=np.float32) + 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): From e1a38fa9e6d452ba34384b07a763d4883f4fc3be Mon Sep 17 00:00:00 2001 From: Ben Feinstein Date: Sun, 22 Dec 2019 14:21:32 +0200 Subject: [PATCH 2/9] Fix 1/4-pixel shift (2/2) --- imresize.py | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/imresize.py b/imresize.py index 55a2a41..5f303d7 100644 --- a/imresize.py +++ b/imresize.py @@ -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[:2], dtype=np.float32) + scale_factor = np.array(sf[:2], dtype=np.float32) + 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) From 4ef59bddcc130e5030ce45e2deb219cf5274f164 Mon Sep 17 00:00:00 2001 From: Ben Feinstein Date: Sun, 22 Dec 2019 15:45:50 +0200 Subject: [PATCH 3/9] Fix 1/4-pixel shift (3/3) --- util.py | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/util.py b/util.py index a87385f..9cf1a94 100644 --- a/util.py +++ b/util.py @@ -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[:2], dtype=np.float32) + scale_factor = np.array(sf[:2], dtype=np.float32) + 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): From 6205099151784e548b593544989ec1f2a14c0b89 Mon Sep 17 00:00:00 2001 From: Ben Feinstein Date: Sun, 22 Dec 2019 16:18:20 +0200 Subject: [PATCH 4/9] Update util.py --- util.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/util.py b/util.py index 9cf1a94..5d0c17d 100644 --- a/util.py +++ b/util.py @@ -193,8 +193,8 @@ def kernel_shift(kernel, sf): # The input image, when interpolated (regular bicubic) is exactly aligned with ground truth. # calculate the shift due to scale factor - kernel_shape = np.array(kernel.shape[:2], dtype=np.float32) - scale_factor = np.array(sf[:2], dtype=np.float32) + kernel_shape = np.array(kernel.shape, dtype=np.float32)[:2] + scale_factor = np.array(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 From 8db706f18cf947b3b1f180b0215fc8e9939a7d5f Mon Sep 17 00:00:00 2001 From: Ben Feinstein Date: Sun, 22 Dec 2019 16:18:39 +0200 Subject: [PATCH 5/9] Update imresize.py --- imresize.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/imresize.py b/imresize.py index 5f303d7..aa758db 100644 --- a/imresize.py +++ b/imresize.py @@ -180,8 +180,8 @@ def kernel_shift(kernel, sf): # The input image, when interpolated (regular bicubic) is exactly aligned with ground truth. # calculate the shift due to scale factor - kernel_shape = np.array(kernel.shape[:2], dtype=np.float32) - scale_factor = np.array(sf[:2], dtype=np.float32) + kernel_shape = np.array(kernel.shape, dtype=np.float32)[:2] + scale_factor = np.array(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 From d7c893ca097b57414b5a257c450dffff2de9f191 Mon Sep 17 00:00:00 2001 From: Ben Feinstein Date: Sun, 22 Dec 2019 16:18:56 +0200 Subject: [PATCH 6/9] Update zssr_utils.py --- ZSSRforKernelGAN/zssr_utils.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ZSSRforKernelGAN/zssr_utils.py b/ZSSRforKernelGAN/zssr_utils.py index 2261194..58e26fb 100644 --- a/ZSSRforKernelGAN/zssr_utils.py +++ b/ZSSRforKernelGAN/zssr_utils.py @@ -184,8 +184,8 @@ def kernel_shift(kernel, sf): # The input image, when interpolated (regular bicubic) is exactly aligned with ground truth. # calculate the shift due to scale factor - kernel_shape = np.array(kernel.shape[:2], dtype=np.float32) - scale_factor = np.array(sf[:2], dtype=np.float32) + kernel_shape = np.array(kernel.shape, dtype=np.float32)[:2] + scale_factor = np.array(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 From 739c970b4752ad8e9027087edaba69afe263c40a Mon Sep 17 00:00:00 2001 From: Ben Feinstein Date: Sun, 22 Dec 2019 16:25:08 +0200 Subject: [PATCH 7/9] Update imresize.py --- imresize.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imresize.py b/imresize.py index aa758db..9a0cd6d 100644 --- a/imresize.py +++ b/imresize.py @@ -181,7 +181,7 @@ def kernel_shift(kernel, sf): # calculate the shift due to scale factor kernel_shape = np.array(kernel.shape, dtype=np.float32)[:2] - scale_factor = np.array(sf, 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 From 4e1abf050f5f826cd4309a4a4607d6ba473e032c Mon Sep 17 00:00:00 2001 From: Ben Feinstein Date: Sun, 22 Dec 2019 16:25:24 +0200 Subject: [PATCH 8/9] Update util.py --- util.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/util.py b/util.py index 5d0c17d..e638513 100644 --- a/util.py +++ b/util.py @@ -194,7 +194,7 @@ def kernel_shift(kernel, sf): # calculate the shift due to scale factor kernel_shape = np.array(kernel.shape, dtype=np.float32)[:2] - scale_factor = np.array(sf, 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 From b25ff8ee77d1fb4032cdec36f72fa892d6add64b Mon Sep 17 00:00:00 2001 From: Ben Feinstein Date: Sun, 22 Dec 2019 16:25:52 +0200 Subject: [PATCH 9/9] Update zssr_utils.py --- ZSSRforKernelGAN/zssr_utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ZSSRforKernelGAN/zssr_utils.py b/ZSSRforKernelGAN/zssr_utils.py index 58e26fb..abdfbf3 100644 --- a/ZSSRforKernelGAN/zssr_utils.py +++ b/ZSSRforKernelGAN/zssr_utils.py @@ -185,7 +185,7 @@ def kernel_shift(kernel, sf): # calculate the shift due to scale factor kernel_shape = np.array(kernel.shape, dtype=np.float32)[:2] - scale_factor = np.array(sf, 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