|
|
import importlib |
|
|
import math |
|
|
import os |
|
|
from pathlib import Path |
|
|
from typing import Optional, Tuple |
|
|
|
|
|
import cv2 |
|
|
import numpy as np |
|
|
import requests |
|
|
import torch |
|
|
|
|
|
import kornia as K |
|
|
|
|
|
|
|
|
def read_img_from_url(url: str, resize_to: Optional[Tuple[int, int]] = None) -> torch.Tensor: |
|
|
|
|
|
response = requests.get(url).content |
|
|
|
|
|
nparr = np.frombuffer(response, np.uint8) |
|
|
|
|
|
img: np.ndarray = cv2.imdecode(nparr, cv2.IMREAD_UNCHANGED)[..., :3] |
|
|
|
|
|
img_t: torch.Tensor = K.utils.image_to_tensor(img, keepdim=False) |
|
|
img_t = img_t.float() / 255.0 |
|
|
if resize_to is None: |
|
|
img_t = K.geometry.resize(img_t, 184) |
|
|
else: |
|
|
img_t = K.geometry.resize(img_t, resize_to) |
|
|
return img_t |
|
|
|
|
|
|
|
|
def main(): |
|
|
|
|
|
BASE_IMAGE_URL1: str = "https://raw.githubusercontent.com/kornia/data/main/panda.jpg" |
|
|
BASE_IMAGE_URL2: str = "https://raw.githubusercontent.com/kornia/data/main/simba.png" |
|
|
BASE_IMAGE_URL3: str = "https://raw.githubusercontent.com/kornia/data/main/girona.png" |
|
|
BASE_IMAGE_URL4: str = "https://raw.githubusercontent.com/kornia/data/main/baby_giraffe.png" |
|
|
BASE_IMAGE_URL5: str = "https://raw.githubusercontent.com/kornia/data/main/persistencia_memoria.jpg" |
|
|
BASE_IMAGE_URL6: str = "https://raw.githubusercontent.com/kornia/data/main/delorean.png" |
|
|
OUTPUT_PATH = Path(__file__).absolute().parent / "source/_static/img" |
|
|
|
|
|
os.makedirs(OUTPUT_PATH, exist_ok=True) |
|
|
print(f"Pointing images to path {OUTPUT_PATH}.") |
|
|
img1 = read_img_from_url(BASE_IMAGE_URL1) |
|
|
img2 = read_img_from_url(BASE_IMAGE_URL2, img1.shape[-2:]) |
|
|
img3 = read_img_from_url(BASE_IMAGE_URL3, img1.shape[-2:]) |
|
|
img4 = read_img_from_url(BASE_IMAGE_URL4) |
|
|
img5 = read_img_from_url(BASE_IMAGE_URL5, (234, 320)) |
|
|
img6 = read_img_from_url(BASE_IMAGE_URL6) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
mod = importlib.import_module("kornia.augmentation") |
|
|
augmentations_list: dict = { |
|
|
"CenterCrop": ((184, 184), 1, 2018), |
|
|
"ColorJitter": ((0.3, 0.3, 0.3, 0.3), 2, 2018), |
|
|
"RandomAffine": (((-15.0, 20.0), (0.1, 0.1), (0.7, 1.3), 20), 2, 2019), |
|
|
"RandomBoxBlur": (((7, 7),), 1, 2020), |
|
|
"RandomCrop": ((img1.shape[-2:], (50, 50)), 2, 2020), |
|
|
"RandomChannelShuffle": ((), 1, 2020), |
|
|
"RandomElasticTransform": (((63, 63), (32, 32), (2.0, 2.0)), 2, 2018), |
|
|
"RandomEqualize": ((), 1, 2020), |
|
|
"RandomErasing": (((0.2, 0.4), (0.3, 1 / 0.3)), 2, 2017), |
|
|
"RandomFisheye": ((torch.tensor([-0.3, 0.3]), torch.tensor([-0.3, 0.3]), torch.tensor([0.9, 1.0])), 2, 2020), |
|
|
"RandomGaussianBlur": (((3, 3), (0.1, 2.0)), 1, 2020), |
|
|
"RandomGaussianNoise": ((0.0, 0.05), 1, 2020), |
|
|
"RandomGrayscale": ((), 1, 2020), |
|
|
"RandomHorizontalFlip": ((), 1, 2020), |
|
|
"RandomInvert": ((), 1, 2020), |
|
|
"RandomMotionBlur": ((7, 35.0, 0.5), 2, 2020), |
|
|
"RandomPerspective": ((0.2,), 2, 2020), |
|
|
"RandomPosterize": (((1, 4),), 2, 2016), |
|
|
"RandomResizedCrop": ((img1.shape[-2:], (1.0, 2.0), (1.0, 2.0)), 2, 2020), |
|
|
"RandomRotation": ((45.0,), 2, 2019), |
|
|
"RandomSharpness": ((16.0,), 1, 2019), |
|
|
"RandomSolarize": ((0.2, 0.2), 2, 2019), |
|
|
"RandomVerticalFlip": ((), 1, 2020), |
|
|
"RandomThinPlateSpline": ((), 1, 2020), |
|
|
} |
|
|
|
|
|
|
|
|
for aug_name, (args, num_samples, seed) in augmentations_list.items(): |
|
|
img_in = img1.repeat(num_samples, 1, 1, 1) |
|
|
|
|
|
cls = getattr(mod, aug_name) |
|
|
aug = cls(*args, p=1.0) |
|
|
|
|
|
torch.manual_seed(seed) |
|
|
|
|
|
out = aug(img_in) |
|
|
|
|
|
if aug_name == "CenterCrop": |
|
|
h, w = img1.shape[-2:] |
|
|
h_new, w_new = out.shape[-2:] |
|
|
h_dif, w_dif = int(h - h_new), int(w - w_new) |
|
|
out = torch.nn.functional.pad(out, (w_dif // 2, w_dif // 2, 0, h_dif)) |
|
|
|
|
|
out = torch.cat([img_in[0], *(out[i] for i in range(out.size(0)))], dim=-1) |
|
|
|
|
|
out_np = K.utils.tensor_to_image((out * 255.0).byte()) |
|
|
cv2.imwrite(str(OUTPUT_PATH / f"{aug_name}.png"), out_np) |
|
|
sig = f"{aug_name}({', '.join([str(a) for a in args])}, p=1.0)" |
|
|
print(f"Generated image example for {aug_name}. {sig}") |
|
|
|
|
|
mod = importlib.import_module("kornia.augmentation") |
|
|
mix_augmentations_list: dict = { |
|
|
"RandomMixUp": (((0.3, 0.4),), 2, 20), |
|
|
"RandomCutMix": ((img1.shape[-2], img1.shape[-1]), 2, 2019), |
|
|
} |
|
|
|
|
|
for aug_name, (args, num_samples, seed) in mix_augmentations_list.items(): |
|
|
img_in = torch.cat([img1, img2]) |
|
|
|
|
|
cls = getattr(mod, aug_name) |
|
|
aug = cls(*args, p=1.0) |
|
|
|
|
|
torch.manual_seed(seed) |
|
|
|
|
|
out, _ = aug(img_in, torch.tensor([0, 1])) |
|
|
out = torch.cat([img_in[0], img_in[1], *(out[i] for i in range(out.size(0)))], dim=-1) |
|
|
|
|
|
out_np = K.utils.tensor_to_image((out * 255.0).byte()) |
|
|
cv2.imwrite(str(OUTPUT_PATH / f"{aug_name}.png"), out_np) |
|
|
sig = f"{aug_name}({', '.join([str(a) for a in args])}, p=1.0)" |
|
|
print(f"Generated image example for {aug_name}. {sig}") |
|
|
|
|
|
mod = importlib.import_module("kornia.color") |
|
|
color_transforms_list: dict = { |
|
|
"grayscale_to_rgb": ((), 3), |
|
|
"rgb_to_bgr": ((), 1), |
|
|
"rgb_to_grayscale": ((), 1), |
|
|
"rgb_to_hsv": ((), 1), |
|
|
"rgb_to_hls": ((), 1), |
|
|
"rgb_to_luv": ((), 1), |
|
|
"rgb_to_lab": ((), 1), |
|
|
|
|
|
"rgb_to_xyz": ((), 1), |
|
|
"rgb_to_ycbcr": ((), 1), |
|
|
"rgb_to_yuv": ((), 1), |
|
|
"rgb_to_linear_rgb": ((), 1), |
|
|
} |
|
|
|
|
|
for fn_name, (args, num_samples) in color_transforms_list.items(): |
|
|
|
|
|
fn = getattr(mod, fn_name) |
|
|
if fn_name == "grayscale_to_rgb": |
|
|
out = fn(K.color.rgb_to_grayscale(img2), *args) |
|
|
else: |
|
|
out = fn(img2, *args) |
|
|
|
|
|
if fn_name == "rgb_to_lab": |
|
|
out = out[:, :1] / 100.0 |
|
|
elif fn_name == "rgb_to_hsv": |
|
|
out[:, :1] = out[:, :1] / 2 * math.pi |
|
|
elif fn_name == "rgb_to_luv": |
|
|
out = out[:, :1] / 116.0 |
|
|
|
|
|
if out.shape[1] != 3: |
|
|
out = out.repeat(1, 3, 1, 1) |
|
|
|
|
|
if fn_name == "grayscale_to_rgb": |
|
|
out = torch.cat( |
|
|
[K.color.rgb_to_grayscale(img2[0]).repeat(3, 1, 1), *(out[i] for i in range(out.size(0)))], dim=-1 |
|
|
) |
|
|
else: |
|
|
out = torch.cat([img2[0], *(out[i] for i in range(out.size(0)))], dim=-1) |
|
|
out_np = K.utils.tensor_to_image((out * 255.0).byte()) |
|
|
cv2.imwrite(str(OUTPUT_PATH / f"{fn_name}.png"), out_np) |
|
|
sig = f"{fn_name}({', '.join([str(a) for a in args])})" |
|
|
print(f"Generated image example for {fn_name}. {sig}") |
|
|
|
|
|
|
|
|
mod = importlib.import_module("kornia.enhance") |
|
|
transforms: dict = { |
|
|
"adjust_brightness": ((torch.tensor([0.25, 0.5]),), 2), |
|
|
"adjust_contrast": ((torch.tensor([0.65, 0.5]),), 2), |
|
|
"adjust_gamma": ((torch.tensor([0.85, 0.75]), 2.0), 2), |
|
|
"adjust_hue": ((torch.tensor([-math.pi / 4, math.pi / 4]),), 2), |
|
|
"adjust_saturation": ((torch.tensor([1.0, 2.0]),), 2), |
|
|
"solarize": ((torch.tensor([0.8, 0.5]), torch.tensor([-0.25, 0.25])), 2), |
|
|
"posterize": ((torch.tensor([4, 2]),), 2), |
|
|
"sharpness": ((torch.tensor([1.0, 2.5]),), 2), |
|
|
"equalize": ((), 1), |
|
|
"invert": ((), 1), |
|
|
"equalize_clahe": ((), 1), |
|
|
"add_weighted": ((0.75, 0.25, 2.0), 1), |
|
|
} |
|
|
|
|
|
for fn_name, (args, num_samples) in transforms.items(): |
|
|
img_in = img3.repeat(num_samples, 1, 1, 1) |
|
|
if fn_name == "add_weighted": |
|
|
args_in = (img_in, args[0], img2, args[1], args[2]) |
|
|
else: |
|
|
args_in = (img_in, *args) |
|
|
|
|
|
fn = getattr(mod, fn_name) |
|
|
out = fn(*args_in) |
|
|
|
|
|
out = torch.cat([img_in[0], *(out[i] for i in range(out.size(0)))], dim=-1) |
|
|
out_np = K.utils.tensor_to_image((out * 255.0).byte()) |
|
|
cv2.imwrite(str(OUTPUT_PATH / f"{fn_name}.png"), out_np) |
|
|
sig = f"{fn_name}({', '.join([str(a) for a in args])})" |
|
|
print(f"Generated image example for {fn_name}. {sig}") |
|
|
|
|
|
|
|
|
mod = importlib.import_module("kornia.morphology") |
|
|
kernel = torch.tensor([[0, 1, 0], [1, 1, 1], [0, 1, 0]]) |
|
|
transforms: dict = { |
|
|
"dilation": ((kernel,), 1), |
|
|
"erosion": ((kernel,), 1), |
|
|
"opening": ((kernel,), 1), |
|
|
"closing": ((kernel,), 1), |
|
|
"gradient": ((kernel,), 1), |
|
|
"top_hat": ((kernel,), 1), |
|
|
"bottom_hat": ((kernel,), 1), |
|
|
} |
|
|
|
|
|
for fn_name, (args, num_samples) in transforms.items(): |
|
|
img_in = img4.repeat(num_samples, 1, 1, 1) |
|
|
args_in = (img_in, *args) |
|
|
|
|
|
|
|
|
fn = getattr(mod, fn_name) |
|
|
out = fn(*args_in) |
|
|
|
|
|
out = torch.cat([img_in[0], *(out[i] for i in range(out.size(0)))], dim=-1) |
|
|
out_np = K.utils.tensor_to_image((out * 255.0).byte()) |
|
|
cv2.imwrite(str(OUTPUT_PATH / f"{fn_name}.png"), out_np) |
|
|
sig = f"{fn_name}({', '.join([str(a) for a in args])})" |
|
|
print(f"Generated image example for {fn_name}. {sig}") |
|
|
|
|
|
|
|
|
mod = importlib.import_module("kornia.filters") |
|
|
kernel = torch.tensor([[0, 1, 0], [1, 1, 1], [0, 1, 0]]) |
|
|
transforms: dict = { |
|
|
"box_blur": (((5, 5),), 1), |
|
|
"median_blur": (((5, 5),), 1), |
|
|
"gaussian_blur2d": (((5, 5), (1.5, 1.5)), 1), |
|
|
"motion_blur": ((5, 90.0, 1.0), 1), |
|
|
"max_blur_pool2d": ((5,), 1), |
|
|
"blur_pool2d": ((5,), 1), |
|
|
"unsharp_mask": (((5, 5), (1.5, 1.5)), 1), |
|
|
"laplacian": ((5,), 1), |
|
|
"sobel": ((), 1), |
|
|
"spatial_gradient": ((), 1), |
|
|
"canny": ((), 1), |
|
|
} |
|
|
|
|
|
for fn_name, (args, num_samples) in transforms.items(): |
|
|
img_in = img5.repeat(num_samples, 1, 1, 1) |
|
|
args_in = (img_in, *args) |
|
|
|
|
|
fn = getattr(mod, fn_name) |
|
|
out = fn(*args_in) |
|
|
if fn_name in ("max_blur_pool2d", "blur_pool2d"): |
|
|
out = K.geometry.resize(out, img_in.shape[-2:]) |
|
|
if fn_name == "canny": |
|
|
out = out[1].repeat(1, 3, 1, 1) |
|
|
if isinstance(out, torch.Tensor): |
|
|
out = out.clamp(min=0.0, max=1.0) |
|
|
if fn_name in ("laplacian", "sobel", "spatial_gradient", "canny"): |
|
|
out = K.enhance.normalize_min_max(out) |
|
|
if fn_name == "spatial_gradient": |
|
|
out = out.permute(2, 1, 0, 3, 4).squeeze() |
|
|
|
|
|
out = torch.cat([img_in[0], *(out[i] for i in range(out.size(0)))], dim=-1) |
|
|
out_np = K.utils.tensor_to_image((out * 255.0).byte()) |
|
|
cv2.imwrite(str(OUTPUT_PATH / f"{fn_name}.png"), out_np) |
|
|
sig = f"{fn_name}({', '.join([str(a) for a in args])})" |
|
|
print(f"Generated image example for {fn_name}. {sig}") |
|
|
|
|
|
|
|
|
mod = importlib.import_module("kornia.geometry.transform") |
|
|
h, w = img6.shape[-2:] |
|
|
|
|
|
def _get_tps_args(): |
|
|
src = torch.tensor([[[-1.0, -1.0], [-1.0, 1.0], [1.0, -1.0], [1.0, -1.0], [0.0, 0.0]]]).repeat(2, 1, 1) |
|
|
dst = src + torch.distributions.Uniform(-0.2, 0.2).rsample((2, 5, 2)) |
|
|
kernel, affine = K.geometry.transform.get_tps_transform(dst, src) |
|
|
return src, kernel, affine |
|
|
|
|
|
transforms: dict = { |
|
|
"warp_affine": ( |
|
|
( |
|
|
K.geometry.transform.get_affine_matrix2d( |
|
|
translations=torch.zeros(2, 2), |
|
|
center=(torch.tensor([w, h]) / 2).repeat(2, 1), |
|
|
scale=torch.distributions.Uniform(0.5, 1.5).rsample((2, 2)), |
|
|
angle=torch.tensor([-25.0, 25.0]), |
|
|
)[:, :2, :3], |
|
|
(h, w), |
|
|
), |
|
|
2, |
|
|
), |
|
|
"remap": ( |
|
|
( |
|
|
*(K.utils.create_meshgrid(h, w, normalized_coordinates=True) - 0.25).unbind(-1), |
|
|
'bilinear', |
|
|
'zeros', |
|
|
True, |
|
|
True, |
|
|
), |
|
|
1, |
|
|
), |
|
|
"warp_image_tps": ((_get_tps_args()), 2), |
|
|
"rotate": ((torch.tensor([-15.0, 25.0]),), 2), |
|
|
"translate": ((torch.tensor([[10.0, -15], [50.0, -25.0]]),), 2), |
|
|
"scale": ((torch.tensor([[0.5, 1.25], [1.0, 1.5]]),), 2), |
|
|
"shear": ((torch.tensor([[0.1, -0.2], [-0.2, 0.1]]),), 2), |
|
|
"rot180": ((), 1), |
|
|
"hflip": ((), 1), |
|
|
"vflip": ((), 1), |
|
|
"resize": (((120, 220),), 1), |
|
|
"rescale": ((0.5,), 1), |
|
|
"elastic_transform2d": ((torch.rand(1, 2, h, w) * 2 - 1, (63, 63), (32, 32), (4.0, 4.0)), 1), |
|
|
"pyrdown": ((), 1), |
|
|
"pyrup": ((), 1), |
|
|
"build_pyramid": ((3,), 1), |
|
|
} |
|
|
|
|
|
for fn_name, (args, num_samples) in transforms.items(): |
|
|
img_in = img6.repeat(num_samples, 1, 1, 1) |
|
|
args_in = (img_in, *args) |
|
|
|
|
|
fn = getattr(mod, fn_name) |
|
|
out = fn(*args_in) |
|
|
if fn_name in ("resize", "rescale", "pyrdown", "pyrup"): |
|
|
h_new, w_new = out.shape[-2:] |
|
|
out = torch.nn.functional.pad(out, (0, (w - w_new), 0, (h - h_new))) |
|
|
if fn_name == "build_pyramid": |
|
|
_out = [] |
|
|
for pyr in out[1:]: |
|
|
h_new, w_new = pyr.shape[-2:] |
|
|
out_tmp = torch.nn.functional.pad(pyr, (0, (w - w_new), 0, (h - h_new))) |
|
|
_out.append(out_tmp) |
|
|
out = torch.cat(_out) |
|
|
|
|
|
out = torch.cat([img_in[0], *(out[i] for i in range(out.size(0)))], dim=-1) |
|
|
out_np = K.utils.tensor_to_image((out * 255.0).byte()) |
|
|
cv2.imwrite(str(OUTPUT_PATH / f"{fn_name}.png"), out_np) |
|
|
sig = f"{fn_name}({', '.join([str(a) for a in args])})" |
|
|
print(f"Generated image example for {fn_name}. {sig}") |
|
|
|
|
|
|
|
|
if __name__ == "__main__": |
|
|
main() |
|
|
|