def generate_q_u_matrix(x_coordinate: cp.array, y_coordinate: cp.array) -> tuple: flatten_flag = x_coordinate.ndim > 1 if flatten_flag: x_coordinate = x_coordinate.flatten() y_coordinate = y_coordinate.flatten() t, u = cp.modf(y_coordinate) u = u.astype(int) uy = cp.vstack([ cp.minimum(cp.maximum(u - 1, 0), h - 1), cp.minimum(cp.maximum(u, 0), h - 1), cp.minimum(cp.maximum(u + 1, 0), h - 1), cp.minimum(cp.maximum(u + 2, 0), h - 1), ]).astype(int) Qy = cp.dot( coeff, cp.vstack([ cp.ones_like(t, dtype=cp.float32), t, cp.power(t, 2), cp.power(t, 3) ])) t, u = cp.modf(x_coordinate) u = u.astype(int) ux = cp.vstack([ cp.minimum(cp.maximum(u - 1, 0), w - 1), cp.minimum(cp.maximum(u, 0), w - 1), cp.minimum(cp.maximum(u + 1, 0), w - 1), cp.minimum(cp.maximum(u + 2, 0), w - 1), ]) Qx = cp.dot( coeff, cp.vstack([ cp.ones_like(t, dtype=cp.float32), t, cp.power(t, 2), cp.power(t, 3) ])) if flatten_flag: Qx = Qx.reshape(4, frame_n, int(w * mag)).transpose(1, 0, 2).copy() Qy = Qy.reshape(4, frame_n, int(h * mag)).transpose(1, 0, 2).copy() ux = ux.reshape(4, frame_n, int(w * mag)).transpose(1, 0, 2).copy() uy = uy.reshape(4, frame_n, int(h * mag)).transpose(1, 0, 2).copy() return Qx, Qy, ux, uy
def g(x): return cupy.modf(x)
def lanczos4_zoom_wrapper(images: cp.array, mag: float): """closure. It will return a function to zoom the images, but the parameters will not be calculated again""" # init the parameters for lanczos image resize afterwards h, w = images.shape[1:3] lanczos4_core_lut = generate_lanczos4_weights_lut() yCoordinate = cp.linspace(0, h - 1 / mag, int(h * mag), dtype=cp.float32) t, u = cp.modf(yCoordinate) u = u.astype(int) # select 8 sampling points uy = [ cp.maximum(u - 3, 0), cp.maximum(u - 2, 0), cp.maximum(u - 1, 0), cp.minimum(u, h - 1), cp.minimum(u + 1, h - 1), cp.minimum(u + 2, h - 1), cp.minimum(u + 3, h - 1), cp.minimum(u + 4, h - 1), ] Q = cp.take(lanczos4_core_lut, (t * 1024).astype(int), axis=0) Qy = [cp.take(Q, i, axis=1) for i in range(8)] xCoordinate = cp.linspace(0, w - 1 / mag, int(w * mag), dtype=cp.float32) del t, u, xCoordinate t, u = cp.modf(xCoordinate) u = u.astype(int) # select 8 sampling points ux = [ cp.maximum(u - 3, 0), cp.maximum(u - 2, 0), cp.maximum(u - 1, 0), cp.minimum(u, w - 1), cp.minimum(u + 1, w - 1), cp.minimum(u + 2, w - 1), cp.minimum(u + 3, w - 1), cp.minimum(u + 4, w - 1), ] Q = cp.take(lanczos4_core_lut, (t * 1024).astype(int), axis=0) Qx = [cp.take(Q, i, axis=1) for i in range(8)] del t, u, yCoordinate, Q, lanczos4_core_lut def lanczos4_zoom(image_mat: cp.array) -> cp.array: """the function to zoom image matrix""" number_of_files = image_mat.shape[0] # First interpolate in Y direction mat_temp = cp.zeros((number_of_files, w, int(h * mag)), dtype=cp.float32) for Qi, ui in zip(Qy, uy): cp.add(mat_temp, cp.transpose(cp.take(image_mat, ui, axis=1), (0, 2, 1)) * Qi, out=mat_temp) del image_mat # Then interpolate in X direction mat_zoomed = cp.zeros((number_of_files, int(h * mag), int(w * mag)), dtype=cp.float32) for Qi, ui in zip(Qx, ux): cp.add(mat_zoomed, cp.transpose(cp.take(mat_temp, ui, axis=1), (0, 2, 1)) * Qi, out=mat_zoomed) del mat_temp return mat_zoomed return lanczos4_zoom