Last active
August 23, 2023 16:53
-
-
Save ZJUGuoShuai/1e4c9da9955cdf018006cfeadf760710 to your computer and use it in GitHub Desktop.
Bilinear Resize Implementation (Python)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| def sample(img, x: float, y: float): | |
| h, w = img.shape | |
| left = math.floor(x) | |
| top = math.floor(y) | |
| right = left + 1 | |
| bottom = top + 1 | |
| # top left corner | |
| if (0 <= left < w) and (0 <= top < h): | |
| a = img[top, left] | |
| else: | |
| a = 0 | |
| # top right corner | |
| if (0 <= right < w) and (0 <= top < h): | |
| b = img[top, right] | |
| else: | |
| b = 0 | |
| # bottom left corner | |
| if (0 <= left < w) and (0 <= bottom < h): | |
| c = img[bottom, left] | |
| else: | |
| c = 0 | |
| # bottom right corner | |
| if (0 <= right < w) and (0 <= bottom < h): | |
| d = img[bottom, right] | |
| else: | |
| d = 0 | |
| # linear interpolation of top two points | |
| top_interleaved = (right - x) * a + (x - left) * b | |
| # linear interpolation of bottom two points | |
| bottom_interleaved = (right - x) * c + (x - left) * d | |
| # linear interpolation of top and bottom points | |
| return (bottom - y) * top_interleaved + (y - top) * bottom_interleaved | |
| def saturate(value, low, high): | |
| if value < low: | |
| return low | |
| if value > high: | |
| return high | |
| return value | |
| def get_source_index( | |
| i: int, scale: float, low: int, high: int, align_corners: bool = False | |
| ): | |
| if align_corners: | |
| return scale * i | |
| else: | |
| return saturate((i + 0.5) * scale - 0.5, low, high) | |
| def bilinear_resize(x: np.ndarray, size: Tuple[int, int], align_corners: bool = False): | |
| y = np.empty(size, dtype=x.dtype) | |
| if align_corners: | |
| scale_h = (x.shape[0] - 1) / (y.shape[0] - 1) | |
| scale_w = (x.shape[1] - 1) / (y.shape[1] - 1) | |
| else: | |
| scale_h = x.shape[0] / y.shape[0] | |
| scale_w = x.shape[1] / y.shape[1] | |
| for i in range(y.shape[0]): | |
| for j in range(y.shape[1]): | |
| i_src = get_source_index(i, scale_h, 0, x.shape[0] - 1, align_corners) | |
| j_src = get_source_index(j, scale_w, 0, x.shape[1] - 1, align_corners) | |
| y[i, j] = sample(x, j_src, i_src) | |
| return y |
Author
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
TODO
It is still not exactly aligned with OpenCV when data type is UINT8.
Reference