Spaces:
Sleeping
Sleeping
Download denoise_model.py from tr251202/CV-project: direct link, hf CLI and curl.
- Browser
- Download file 3.12 kB
-
https://huggingface.co/spaces/tr251202/CV-project/resolve/main/denoise_model.py
- Command line
-
hf download hf://spaces/tr251202/CV-project/denoise_model.py
-
curl -L -o denoise_model.py https://huggingface.co/spaces/tr251202/CV-project/resolve/main/denoise_model.py
3.12 kB
| import torch | |
| import torch.nn as nn | |
| import torch.nn.functional as F | |
| import numpy as np | |
| from invertnet import InvNet | |
| import cv2 | |
| from utils import cut_image, recover_image | |
| class Denoise(nn.Module): | |
| def __init__(self): | |
| super(Denoise, self).__init__() | |
| self.net = InvNet() | |
| self.device = torch.device("cuda" if torch.cuda.is_available() else "cpu") | |
| def forward(self, x): | |
| if self.training: | |
| return self.forward_train(x) | |
| else: | |
| return self.forward_test(x) | |
| def forward_train(self, x): | |
| output_forward = self.net(x, reverse=False) | |
| output_lr = output_forward[:, :3, :, :] | |
| gaussian_noise = torch.randn(output_forward[:, 3:, :, :].shape, device=self.device) | |
| x_backward = torch.cat([output_lr, gaussian_noise], dim=1) | |
| y_backward = self.net(x_backward, reverse=True) | |
| output_denoise = y_backward[:, :3, :, :] | |
| return output_lr, output_denoise | |
| def forward_test(self, x): | |
| x = x.cpu().numpy() | |
| xs = [x] | |
| xs.append(x[:, :, :, ::-1].copy()) | |
| xs.append(x[:, :, ::-1, :].copy()) | |
| xs.append(x.transpose((0, 1, 3, 2)).copy()) | |
| output_forward = [self.net(torch.tensor(aug, device=self.device), reverse=False) for aug in xs] | |
| x_backwards = [] | |
| for data in output_forward: | |
| output_lr = data[:, :3, :, :] | |
| gaussian_noise = torch.randn(data[:, 3:, :, :].shape, device=self.device) | |
| x_backward = torch.cat([output_lr, gaussian_noise], dim=1) | |
| x_backwards.append(x_backward) | |
| output_denoise = [self.net(data, reverse=True) for data in x_backwards] | |
| output_denoise[0] = np.array(output_denoise[0].cpu()) | |
| output_denoise[1] = np.array(output_denoise[1].cpu())[:, :, :, ::-1].copy() | |
| output_denoise[2] = np.array(output_denoise[2].cpu())[:, :, ::-1, :].copy() | |
| output_denoise[3] = np.array(output_denoise[3].cpu()).transpose((0, 1, 3, 2)).copy() | |
| output_cat = np.concatenate(output_denoise, axis=0) | |
| output = output_cat.mean(axis=0, keepdims=True) | |
| return output | |
| def inference_invdn(img_dir): | |
| model = Denoise() | |
| model.eval() | |
| model.net.load_state_dict(torch.load("invdn_checkpoint.pth", map_location=torch.device("cuda" if torch.cuda.is_available() else "cpu"))) | |
| image = cv2.imread(img_dir) | |
| image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB) / 255 | |
| cuts, indexes = cut_image(image, (256, 256)) | |
| h, w = image.shape[:2] | |
| outputs = [] | |
| with torch.no_grad(): | |
| for cut in cuts: | |
| h1, w1 = cut.shape[:2] | |
| cut = cv2.resize(cut, (256, 256), interpolation=cv2.INTER_LINEAR) | |
| cut = cut.transpose(2, 0, 1) | |
| output = model(torch.tensor(cut).unsqueeze(0).float()) | |
| output = output[0].transpose(1, 2, 0) * 255 | |
| output = output.astype(dtype=np.uint8) | |
| output = cv2.resize(output, (w1, h1), interpolation=cv2.INTER_LINEAR) | |
| outputs.append(output) | |
| full = recover_image(outputs, indexes, (h, w), (256, 256)) | |
| return full.astype(np.uint8) | |