Commit
·
0d04ccc
1
Parent(s):
f127d9b
Upload app.py
Browse files
app.py
CHANGED
|
@@ -1,139 +1,77 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
|
| 2 |
-
import os
|
| 3 |
import pickle
|
| 4 |
-
import sys
|
| 5 |
-
import subprocess
|
| 6 |
-
import imageio
|
| 7 |
import numpy as np
|
| 8 |
-
import scipy.interpolate
|
| 9 |
import torch
|
| 10 |
-
from tqdm import tqdm
|
| 11 |
import gradio as gr
|
| 12 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 13 |
|
| 14 |
os.system("git clone https://github.com/NVlabs/stylegan3")
|
| 15 |
|
| 16 |
sys.path.append("stylegan3")
|
| 17 |
|
| 18 |
-
def layout_grid(img, grid_w=None, grid_h=1, float_to_uint8=True, chw_to_hwc=True, to_numpy=True):
|
| 19 |
-
batch_size, channels, img_h, img_w = img.shape
|
| 20 |
-
if grid_w is None:
|
| 21 |
-
grid_w = batch_size // grid_h
|
| 22 |
-
assert batch_size == grid_w * grid_h
|
| 23 |
-
if float_to_uint8:
|
| 24 |
-
img = (img * 127.5 + 128).clamp(0, 255).to(torch.uint8)
|
| 25 |
-
img = img.reshape(grid_h, grid_w, channels, img_h, img_w)
|
| 26 |
-
img = img.permute(2, 0, 3, 1, 4)
|
| 27 |
-
img = img.reshape(channels, grid_h * img_h, grid_w * img_w)
|
| 28 |
-
if chw_to_hwc:
|
| 29 |
-
img = img.permute(1, 2, 0)
|
| 30 |
-
if to_numpy:
|
| 31 |
-
img = img.cpu().numpy()
|
| 32 |
-
return img
|
| 33 |
|
| 34 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 35 |
|
| 36 |
|
| 37 |
network_pkl='braingan-400.pkl'
|
| 38 |
with open(network_pkl, 'rb') as f:
|
| 39 |
G = pickle.load(f)['G_ema']
|
| 40 |
-
|
| 41 |
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
|
| 42 |
G.eval()
|
| 43 |
G.to(device)
|
| 44 |
-
def predict(Seed,choices,choices2):
|
| 45 |
-
|
| 46 |
-
shuffle_seed=None
|
| 47 |
-
kind='cubic'
|
| 48 |
-
num_keyframes=None
|
| 49 |
-
wraps=2
|
| 50 |
-
psi=0.5
|
| 51 |
-
s1=Seed
|
| 52 |
-
|
| 53 |
-
|
| 54 |
-
if choices=='4x2':
|
| 55 |
-
grid_w = 4
|
| 56 |
-
grid_h = 2
|
| 57 |
-
if choices2=="Large Video":
|
| 58 |
-
seeds=(np.arange(s1-16,s1)).tolist()
|
| 59 |
-
w_frames=60*4
|
| 60 |
-
if choices2=="Small Video":
|
| 61 |
-
seeds=(np.arange(s1-8,s1)).tolist()
|
| 62 |
-
w_frames=30*4
|
| 63 |
-
|
| 64 |
-
if choices=='2x1':
|
| 65 |
-
grid_w = 2
|
| 66 |
-
grid_h = 1
|
| 67 |
-
if choices2=="Large Video":
|
| 68 |
-
seeds=(np.arange(s1-4,s1)).tolist()
|
| 69 |
-
w_frames=60*4
|
| 70 |
-
if choices2=="Small Video":
|
| 71 |
-
seeds=(np.arange(s1-2,s1)).tolist()
|
| 72 |
-
w_frames=30*4
|
| 73 |
-
|
| 74 |
-
|
| 75 |
-
|
| 76 |
-
mp4='ex.mp4'
|
| 77 |
-
truncation_psi=1
|
| 78 |
-
num_keyframes=None
|
| 79 |
-
|
| 80 |
-
|
| 81 |
-
if num_keyframes is None:
|
| 82 |
-
if len(seeds) % (grid_w*grid_h) != 0:
|
| 83 |
-
raise ValueError('Number of input seeds must be divisible by grid W*H')
|
| 84 |
-
num_keyframes = len(seeds) // (grid_w*grid_h)
|
| 85 |
-
|
| 86 |
-
all_seeds = np.zeros(num_keyframes*grid_h*grid_w, dtype=np.int64)
|
| 87 |
-
for idx in range(num_keyframes*grid_h*grid_w):
|
| 88 |
-
all_seeds[idx] = seeds[idx % len(seeds)]
|
| 89 |
-
|
| 90 |
-
if shuffle_seed is not None:
|
| 91 |
-
rng = np.random.RandomState(seed=shuffle_seed)
|
| 92 |
-
rng.shuffle(all_seeds)
|
| 93 |
-
|
| 94 |
-
zs = torch.from_numpy(np.stack([np.random.RandomState(seed).randn(G.z_dim) for seed in all_seeds])).to(device)
|
| 95 |
-
ws = G.mapping(z=zs, c=None, truncation_psi=psi)
|
| 96 |
-
_ = G.synthesis(ws[:1]) # warm up
|
| 97 |
-
ws = ws.reshape(grid_h, grid_w, num_keyframes, *ws.shape[1:])
|
| 98 |
-
|
| 99 |
-
# Interpolation.
|
| 100 |
-
grid = []
|
| 101 |
-
for yi in range(grid_h):
|
| 102 |
-
row = []
|
| 103 |
-
for xi in range(grid_w):
|
| 104 |
-
x = np.arange(-num_keyframes * wraps, num_keyframes * (wraps + 1))
|
| 105 |
-
y = np.tile(ws[yi][xi].cpu().numpy(), [wraps * 2 + 1, 1, 1])
|
| 106 |
-
interp = scipy.interpolate.interp1d(x, y, kind=kind, axis=0)
|
| 107 |
-
row.append(interp)
|
| 108 |
-
grid.append(row)
|
| 109 |
-
|
| 110 |
-
# Render video.
|
| 111 |
-
video_out = imageio.get_writer(mp4, mode='I', fps=30, codec='libx264')
|
| 112 |
-
for frame_idx in tqdm(range(num_keyframes * w_frames)):
|
| 113 |
-
imgs = []
|
| 114 |
-
for yi in range(grid_h):
|
| 115 |
-
for xi in range(grid_w):
|
| 116 |
-
interp = grid[yi][xi]
|
| 117 |
-
w = torch.from_numpy(interp(frame_idx / w_frames)).to(device)
|
| 118 |
-
img = G.synthesis(ws=w.unsqueeze(0), noise_mode='const')[0]
|
| 119 |
-
imgs.append(img)
|
| 120 |
-
video_out.append_data(layout_grid(torch.stack(imgs), grid_w=grid_w, grid_h=grid_h))
|
| 121 |
-
video_out.close()
|
| 122 |
-
return mp4
|
| 123 |
-
|
| 124 |
-
|
| 125 |
-
|
| 126 |
-
choices=['4x2','2x1']
|
| 127 |
-
choices2=["Large Video","Small Video"]
|
| 128 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 129 |
interface=gr.Interface(fn=predict, title="Brain MR Image Generation with StyleGAN-2",
|
| 130 |
description = "",
|
| 131 |
article = "Author: S.Serdar Helli",
|
| 132 |
-
inputs=[gr.inputs.Slider( minimum=
|
| 133 |
-
|
| 134 |
-
|
| 135 |
-
|
| 136 |
-
|
|
|
|
| 137 |
|
| 138 |
|
| 139 |
-
interface.launch(debug=True
|
|
|
|
| 1 |
+
# -*- coding: utf-8 -*-
|
| 2 |
+
"""
|
| 3 |
+
Created on Tue Apr 26 21:02:31 2022
|
| 4 |
+
|
| 5 |
+
@author: pc
|
| 6 |
+
"""
|
| 7 |
|
|
|
|
| 8 |
import pickle
|
|
|
|
|
|
|
|
|
|
| 9 |
import numpy as np
|
|
|
|
| 10 |
import torch
|
|
|
|
| 11 |
import gradio as gr
|
| 12 |
+
import sys
|
| 13 |
+
import subprocess
|
| 14 |
+
import os
|
| 15 |
+
from typing import Tuple
|
| 16 |
+
import PIL.Image
|
| 17 |
|
| 18 |
os.system("git clone https://github.com/NVlabs/stylegan3")
|
| 19 |
|
| 20 |
sys.path.append("stylegan3")
|
| 21 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 22 |
|
| 23 |
|
| 24 |
+
def make_transform(translate: Tuple[float,float], angle: float):
|
| 25 |
+
m = np.eye(3)
|
| 26 |
+
s = np.sin(angle/360.0*np.pi*2)
|
| 27 |
+
c = np.cos(angle/360.0*np.pi*2)
|
| 28 |
+
m[0][0] = c
|
| 29 |
+
m[0][1] = s
|
| 30 |
+
m[0][2] = translate[0]
|
| 31 |
+
m[1][0] = -s
|
| 32 |
+
m[1][1] = c
|
| 33 |
+
m[1][2] = translate[1]
|
| 34 |
+
return m
|
| 35 |
+
|
| 36 |
|
| 37 |
|
| 38 |
network_pkl='braingan-400.pkl'
|
| 39 |
with open(network_pkl, 'rb') as f:
|
| 40 |
G = pickle.load(f)['G_ema']
|
|
|
|
| 41 |
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
|
| 42 |
G.eval()
|
| 43 |
G.to(device)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 44 |
|
| 45 |
+
def predict(Seed,noise_mode,truncation_psi,trans_x,trans_y,angle):
|
| 46 |
+
|
| 47 |
+
# Generate images.
|
| 48 |
+
z = torch.from_numpy(np.random.RandomState(Seed).randn(1, G.z_dim)).to(device)
|
| 49 |
+
label = torch.zeros([1, G.c_dim], device=device)
|
| 50 |
+
# Construct an inverse rotation/translation matrix and pass to the generator. The
|
| 51 |
+
# generator expects this matrix as an inverse to avoid potentially failing numerical
|
| 52 |
+
# operations in the network.
|
| 53 |
+
if hasattr(G.synthesis, 'input'):
|
| 54 |
+
m = make_transform((trans_x,trans_y), angle)
|
| 55 |
+
m = np.linalg.inv(m)
|
| 56 |
+
G.synthesis.input.transform.copy_(torch.from_numpy(m))
|
| 57 |
+
|
| 58 |
+
img = G(z, label, truncation_psi=truncation_psi, noise_mode=noise_mode)
|
| 59 |
+
img = (img.permute(0, 2, 3, 1) * 127.5 + 128).clamp(0, 255).to(torch.uint8)
|
| 60 |
+
|
| 61 |
+
return PIL.Image.fromarray(img[0].cpu().numpy()[:,:,0])
|
| 62 |
+
|
| 63 |
+
|
| 64 |
+
|
| 65 |
+
noises=['const', 'random', 'none']
|
| 66 |
interface=gr.Interface(fn=predict, title="Brain MR Image Generation with StyleGAN-2",
|
| 67 |
description = "",
|
| 68 |
article = "Author: S.Serdar Helli",
|
| 69 |
+
inputs=[gr.inputs.Slider( minimum=0, maximum=2**10,label='Seed'),gr.inputs.Radio( choices=noises, default='const',label='Noise Mods'),
|
| 70 |
+
gr.inputs.Slider(0, 2, step=0.05, default=1, label='Truncation psi'),
|
| 71 |
+
gr.inputs.Slider(-1, 1, step=0.05, default=0, label='Translate X'),
|
| 72 |
+
gr.inputs.Slider(-1, 1, step=0.05, default=0, label='Translate Y'),
|
| 73 |
+
gr.inputs.Slider(-180, 180, step=5, default=0, label='Angle'),],
|
| 74 |
+
outputs=gr.outputs.Image( type="numpy", label="Output"))
|
| 75 |
|
| 76 |
|
| 77 |
+
interface.launch(debug=True)
|