Spaces:
Running
Running
| # -*- encoding: utf-8 -*- | |
| # author Victorshengw | |
| import os | |
| import numpy as np | |
| from torchvision import transforms | |
| from torch.autograd import Variable | |
| import torch | |
| from PIL import Image | |
| def get_patch_info(shape, p_size): | |
| ''' | |
| shape: origin image size, (x, y) | |
| p_size: patch size (square) | |
| return: n_x, n_y, step_x, step_y | |
| ''' | |
| x = shape[0] | |
| y = shape[1] | |
| if x==p_size and y==p_size: | |
| return 1, 1, 0, 0 | |
| n = m = 1 | |
| while x > n * p_size: | |
| n += 1 | |
| while p_size - 1.0 * (x - p_size) / (n - 1) < p_size/4: | |
| n += 1 | |
| while y > m * p_size: | |
| m += 1 | |
| while p_size - 1.0 * (y - p_size) / (m - 1) < p_size/4: | |
| m += 1 | |
| return n, m, (x - p_size) * 1.0 / (n - 1), (y - p_size) * 1.0 / (m - 1) | |
| def global2patch(images, p_size): | |
| ''' | |
| image/label => patches | |
| p_size: patch size | |
| return: list of PIL patch images; coordinates: images->patches; ratios: (h, w) | |
| ''' | |
| patches = []; coordinates = []; templates = []; sizes = []; ratios = [(0, 0)] * len(images); patch_ones = np.ones(p_size) | |
| for i in range(len(images)): | |
| w, h = images[i].size | |
| size = (h, w) | |
| sizes.append(size) | |
| ratios[i] = (float(p_size[0]) / size[0], float(p_size[1]) / size[1]) | |
| template = np.zeros(size) | |
| n_x, n_y, step_x, step_y = get_patch_info(size, p_size[0]) | |
| patches.append([images[i]] * (n_x * n_y)) | |
| coordinates.append([(0, 0)] * (n_x * n_y)) | |
| for x in range(n_x): | |
| if x < n_x - 1: top = int(np.round(x * step_x)) | |
| else: top = size[0] - p_size[0] | |
| for y in range(n_y): | |
| if y < n_y - 1: left = int(np.round(y * step_y)) | |
| else: left = size[1] - p_size[1] | |
| template[top:top+p_size[0], left:left+p_size[1]] += patch_ones | |
| coordinates[i][x * n_y + y] = (1.0 * top / size[0], 1.0 * left / size[1]) | |
| patches[i][x * n_y + y] = transforms.functional.crop(images[i], top, left, p_size[0], p_size[1]) | |
| # patches[i][x * n_y + y].show() | |
| templates.append(Variable(torch.Tensor(template).expand(1, 1, -1, -1))) | |
| return patches, coordinates, templates, sizes, ratios | |
| def patch2global(patches, n_class, sizes, coordinates, p_size,flag = 0): | |
| ''' | |
| predicted patches (after classify layer) => predictions | |
| return: list of np.array | |
| ''' | |
| patches = np.array(torch.detach(patches).cpu().numpy()) | |
| predictions = [ np.zeros((n_class, size[0], size[1])) for size in sizes] | |
| for i in range(len(sizes)): | |
| for j in range(len(coordinates[i])): | |
| top, left = coordinates[i][j] | |
| top = int(np.round(top * sizes[i][0])); left = int(np.round(left * sizes[i][1])) | |
| patches_tmp = np.zeros(patches[j][:,:,:].shape) | |
| whole_img_tmp = predictions[i][:, top: top + p_size[0], left: left + p_size[1]] | |
| #俩小块儿最大(max)的成为最终的prediction | |
| #patches[j][:,:,:] 就是每个要贴到大图中的小块儿,whole_img_tmp是整个目标大图中对应patches_tmp的那一小块儿,然后将这俩及逆行比较,谁大就取谁 | |
| if flag == 0: | |
| patches_tmp[patches[j][:, :, :] > whole_img_tmp] = patches[j][:,:,:][patches[j][:, :, :] > whole_img_tmp] # 要贴上去的小块中的值大于大图中的值 patches[j][:, :, :] > whole_img_tmp | |
| patches_tmp[patches[j][:, :, :] < whole_img_tmp] = whole_img_tmp[patches[j][:, :, :] < whole_img_tmp] # 要贴上去的小块中的值小于于大图中的值 patches[j][:, :, :] < whole_img_tmp | |
| predictions[i][:, top: top + p_size[0], left: left + p_size[1]] += patches_tmp | |
| else: | |
| predictions[i][:, top: top + p_size[0], left: left + p_size[1]] += patches[j][:, :, :] | |
| return predictions | |
| if __name__ == '__main__': | |
| images = [] | |
| img = Image.open(os.path.join(r"../train_valid/003DRIVE/image", f"01.png")) | |
| images.append(img) | |
| # print(len(images)) = 3 | |
| p_size = (224,224) | |
| patches, coordinates, templates, sizes, ratios = global2patch(images, p_size) | |
| # predictions = patch2global(patches, 3, sizes, coordinates, p_size) | |
| # print(type(predictions)) |