diff --git "a/upscaler/RealESRGAN/utils.py" "b/upscaler/RealESRGAN/utils.py" --- "a/upscaler/RealESRGAN/utils.py" +++ "b/upscaler/RealESRGAN/utils.py" @@ -1,4046 +1,147 @@ +import numpy as np +import torch +from PIL import Image +import os +import io - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Swapm/upscaler/RealESRGAN/utils.py at main · G-force78/Swapm - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - -
- Skip to content - - - - - - - - - - - - - - - - - - - -
-
- - - - - - - - - - -
- - -
-
- - - - - - -
-
-
-

- Global navigation -

-
-
-
-
- -
-
-
- -
- - -
- - - - -
-
-
- - -

© 2024 GitHub, Inc.

- -
-
-
- -
- -
-
- - - -
-
- - - - -
-
-
-

- Navigate back to -

-
-
- -
-
-
- - - - -
-
- -
- -
-
- -
-
- - -
- - - Create new... - - - - - - - -Issues - - -Pull requests - -
- - - - - - - Notifications - - - - -
- - - - - - - -
-
-
-

- Account menu -

-
-
- - - G-force78 - -
- - - Create new... - - - - - -
-
-
-
- -
-
-
- -
- - - -
-
-
- -
-
- -
-
- -
- -
- - - - - -
-
-
- - - -
- - - - -
- -
- - - - - - - - -
- - - - - - -
- - - - - - - - - - -
- - - - - - - - - - - - - - - - - -
- -
- - - - G-force78  /   - Swapm  /   - -
-
- - - -
- - -
-
- Clear Command Palette -
-
- - - -
-
- Tip: - Type # to search pull requests -
-
- Type ? for help and tips -
-
-
- -
-
- Tip: - Type # to search issues -
-
- Type ? for help and tips -
-
-
- -
-
- Tip: - Type # to search discussions -
-
- Type ? for help and tips -
-
-
- -
-
- Tip: - Type ! to search projects -
-
- Type ? for help and tips -
-
-
- -
-
- Tip: - Type @ to search teams -
-
- Type ? for help and tips -
-
-
- -
-
- Tip: - Type @ to search people and organizations -
-
- Type ? for help and tips -
-
-
- -
-
- Tip: - Type > to activate command mode -
-
- Type ? for help and tips -
-
-
- -
-
- Tip: - Go to your accessibility settings to change your keyboard shortcuts -
-
- Type ? for help and tips -
-
-
- -
-
- Tip: - Type author:@me to search your content -
-
- Type ? for help and tips -
-
-
- -
-
- Tip: - Type is:pr to filter to pull requests -
-
- Type ? for help and tips -
-
-
- -
-
- Tip: - Type is:issue to filter to issues -
-
- Type ? for help and tips -
-
-
- -
-
- Tip: - Type is:project to filter to projects -
-
- Type ? for help and tips -
-
-
- -
-
- Tip: - Type is:open to filter to open content -
-
- Type ? for help and tips -
-
-
- -
- -
-
- We’ve encountered an error and some results aren't available at this time. Type a new search or try again later. -
-
- - No results matched your search - - - - - - - - - - -
- - - - - Search for issues and pull requests - - # - - - - Search for issues, pull requests, discussions, and projects - - # - - - - Search for organizations, repositories, and users - - @ - - - - Search for projects - - ! - - - - Search for files - - / - - - - Activate command mode - - > - - - - Search your issues, pull requests, and discussions - - # author:@me - - - - Search your issues, pull requests, and discussions - - # author:@me - - - - Filter to pull requests - - # is:pr - - - - Filter to issues - - # is:issue - - - - Filter to discussions - - # is:discussion - - - - Filter to projects - - # is:project - - - - Filter to open issues, pull requests, and discussions - - # is:open - - - - - - - - - - - - - - - - -
-
-
- -
- - - - - - - - - - -
- - -
-
-
- - - -
- This repository has been archived by the owner on Feb 17, 2024. It is now read-only. -
- - - - - - - - - - - - - -
- Open in github.dev - Open in a new github.dev tab - Open in codespace - - - - - - - - - - - - - - - -

Files

t

Latest commit

 

History

History
133 lines (103 loc) · 4.63 KB

utils.py

File metadata and controls

133 lines (103 loc) · 4.63 KB

Symbols

Find definitions and references for functions and other symbols in this file by clicking a symbol below or in the code.
r
  • func
    pad_reflect
  • func
    unpad_image
  • func
    process_array
  • func
    process_output
  • func
    pad_patch
  • func
    unpad_patches
  • func
    split_image_into_overlapping_patches
  • func
    stich_together
-
- - - - -
- -
- -
-
- -
- - - - - - - - - - - - - - - - - - - - - - -
- -
-
- - - +def pad_reflect(image, pad_size): + imsize = image.shape + height, width = imsize[:2] + new_img = np.zeros([height + pad_size * 2, width + pad_size * 2, imsize[2]]).astype( + np.uint8 + ) + new_img[pad_size:-pad_size, pad_size:-pad_size, :] = image + + new_img[0:pad_size, pad_size:-pad_size, :] = np.flip( + image[0:pad_size, :, :], axis=0 + ) # top + new_img[-pad_size:, pad_size:-pad_size, :] = np.flip( + image[-pad_size:, :, :], axis=0 + ) # bottom + new_img[:, 0:pad_size, :] = np.flip( + new_img[:, pad_size : pad_size * 2, :], axis=1 + ) # left + new_img[:, -pad_size:, :] = np.flip( + new_img[:, -pad_size * 2 : -pad_size, :], axis=1 + ) # right + + return new_img + + +def unpad_image(image, pad_size): + return image[pad_size:-pad_size, pad_size:-pad_size, :] + + +def process_array(image_array, expand=True): + """Process a 3-dimensional array into a scaled, 4 dimensional batch of size 1.""" + + image_batch = image_array / 255.0 + if expand: + image_batch = np.expand_dims(image_batch, axis=0) + return image_batch + + +def process_output(output_tensor): + """Transforms the 4-dimensional output tensor into a suitable image format.""" + + sr_img = output_tensor.clip(0, 1) * 255 + sr_img = np.uint8(sr_img) + return sr_img + + +def pad_patch(image_patch, padding_size, channel_last=True): + """Pads image_patch with with padding_size edge values.""" + + if channel_last: + return np.pad( + image_patch, + ((padding_size, padding_size), (padding_size, padding_size), (0, 0)), + "edge", + ) + else: + return np.pad( + image_patch, + ((0, 0), (padding_size, padding_size), (padding_size, padding_size)), + "edge", + ) + + +def unpad_patches(image_patches, padding_size): + return image_patches[:, padding_size:-padding_size, padding_size:-padding_size, :] + + +def split_image_into_overlapping_patches(image_array, patch_size, padding_size=2): + """Splits the image into partially overlapping patches. + The patches overlap by padding_size pixels. + Pads the image twice: + - first to have a size multiple of the patch size, + - then to have equal padding at the borders. + Args: + image_array: numpy array of the input image. + patch_size: size of the patches from the original image (without padding). + padding_size: size of the overlapping area. + """ + + xmax, ymax, _ = image_array.shape + x_remainder = xmax % patch_size + y_remainder = ymax % patch_size + + # modulo here is to avoid extending of patch_size instead of 0 + x_extend = (patch_size - x_remainder) % patch_size + y_extend = (patch_size - y_remainder) % patch_size + + # make sure the image is divisible into regular patches + extended_image = np.pad(image_array, ((0, x_extend), (0, y_extend), (0, 0)), "edge") + + # add padding around the image to simplify computations + padded_image = pad_patch(extended_image, padding_size, channel_last=True) + + xmax, ymax, _ = padded_image.shape + patches = [] + + x_lefts = range(padding_size, xmax - padding_size, patch_size) + y_tops = range(padding_size, ymax - padding_size, patch_size) + + for x in x_lefts: + for y in y_tops: + x_left = x - padding_size + y_top = y - padding_size + x_right = x + patch_size + padding_size + y_bottom = y + patch_size + padding_size + patch = padded_image[x_left:x_right, y_top:y_bottom, :] + patches.append(patch) + + return np.array(patches), padded_image.shape + + +def stich_together(patches, padded_image_shape, target_shape, padding_size=4): + """Reconstruct the image from overlapping patches. + After scaling, shapes and padding should be scaled too. + Args: + patches: patches obtained with split_image_into_overlapping_patches + padded_image_shape: shape of the padded image contructed in split_image_into_overlapping_patches + target_shape: shape of the final image + padding_size: size of the overlapping area. + """ + + xmax, ymax, _ = padded_image_shape + patches = unpad_patches(patches, padding_size) + patch_size = patches.shape[1] + n_patches_per_row = ymax // patch_size + + complete_image = np.zeros((xmax, ymax, 3)) + + row = -1 + col = 0 + for i in range(len(patches)): + if i % n_patches_per_row == 0: + row += 1 + col = 0 + complete_image[ + row * patch_size : (row + 1) * patch_size, + col * patch_size : (col + 1) * patch_size, + :, + ] = patches[i] + col += 1 + return complete_image[0 : target_shape[0], 0 : target_shape[1], :]