CV-project / denoise_model.py
3v324v23's picture
First commit
6b5d0d6
Raw History Blame Contribute Delete
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)