Josh Brown Kramer commited on
Commit
6409df2
·
1 Parent(s): edd2e49

First attempt at serving model as a space

Browse files
Files changed (3) hide show
  1. app.py +26 -12
  2. requirements.txt +3 -1
  3. zombie.py +163 -0
app.py CHANGED
@@ -1,4 +1,7 @@
1
  import gradio as gr
 
 
 
2
  # import torch
3
  # from your_pix2pixhd_code import YourPix2PixHDModel, load_image, tensor2im # Adapt these imports
4
 
@@ -9,20 +12,31 @@ import gradio as gr
9
  # model.load_state_dict(torch.load('models/your_pix2pixhd_model.pth'))
10
  # model.eval()
11
 
 
 
 
12
  # --- 2. Define the prediction function ---
13
- def predict(input_image):
14
- return input_image[..., ::-1]
15
- # # Pre-process the input image
16
- # processed_image = load_image(input_image)
17
 
18
- # # Run inference
19
- # with torch.no_grad():
20
- # generated_image_tensor = model(processed_image)
21
 
22
- # # Post-process the output tensor to an image
23
- # output_image = tensor2im(generated_image_tensor)
24
 
25
- # return output_image
 
 
 
 
 
 
 
 
26
 
27
  # --- 3. Create the Gradio Interface ---
28
  title = "pix2pixHD Image-to-Image Translation"
@@ -31,8 +45,8 @@ article = "<p style='text-align: center'>Model based on the <a href='https://git
31
 
32
  gr.Interface(
33
  fn=predict,
34
- inputs=gr.Image(type="numpy", label="Input Image"),
35
- outputs=gr.Image(type="numpy", label="Output Image"),
36
  title=title,
37
  description=description,
38
  article=article,
 
1
  import gradio as gr
2
+ import zombie
3
+ from huggingface_hub import hf_hub_download
4
+ import onnxruntime as ort
5
  # import torch
6
  # from your_pix2pixhd_code import YourPix2PixHDModel, load_image, tensor2im # Adapt these imports
7
 
 
12
  # model.load_state_dict(torch.load('models/your_pix2pixhd_model.pth'))
13
  # model.eval()
14
 
15
+ model_path = hf_hub_download(repo_id="jbrownkramer/makemeazombie", filename="smaller512x512_32bit.onnx")
16
+ ort_session = ort.InferenceSession(model_path, providers=['CUDAExecutionProvider'])
17
+
18
  # --- 2. Define the prediction function ---
19
+ # def predict(input_image):
20
+ # return input_image[..., ::-1]
21
+ # # # Pre-process the input image
22
+ # # processed_image = load_image(input_image)
23
 
24
+ # # # Run inference
25
+ # # with torch.no_grad():
26
+ # # generated_image_tensor = model(processed_image)
27
 
28
+ # # # Post-process the output tensor to an image
29
+ # # output_image = tensor2im(generated_image_tensor)
30
 
31
+ # # return output_image
32
+
33
+ def predict(input_image):
34
+ zombie_image = zombie.transition_onnx(input_image,ort_session)
35
+
36
+ if zombie_image is None:
37
+ return "No face found"
38
+
39
+ return zombie_image
40
 
41
  # --- 3. Create the Gradio Interface ---
42
  title = "pix2pixHD Image-to-Image Translation"
 
45
 
46
  gr.Interface(
47
  fn=predict,
48
+ inputs=gr.Image(type="pil", label="Input Image"),
49
+ outputs=gr.Image(type="pil", label="Output Image"),
50
  title=title,
51
  description=description,
52
  article=article,
requirements.txt CHANGED
@@ -1 +1,3 @@
1
- gradio
 
 
 
1
+ gradio
2
+ onnxruntime-gpu
3
+ opencv-python
zombie.py ADDED
@@ -0,0 +1,163 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # import sys
2
+ # sys.path.append("pix2pixHD")
3
+
4
+ from PIL import Image
5
+ import numpy as np
6
+ # import pickle
7
+ # import align
8
+ # import time
9
+ import cv2
10
+
11
+ # sys.path.append(r"..\face-parsing.PyTorch")
12
+ # import inferface
13
+
14
+ # def get_model():
15
+ # with open("opt.pkl","rb") as f:
16
+ # opt = pickle.load(f)
17
+
18
+ # return create_model(opt)
19
+
20
+ def normalized_tensor(pil):
21
+ transform = transforms.Compose([transforms.ToTensor(),transforms.Normalize((0.5, 0.5, 0.5),(0.5, 0.5, 0.5))])
22
+ return transform(pil)
23
+
24
+ def tensor2im(tensor):
25
+ return Image.fromarray((255 * ((tensor.cpu().numpy() * .5) + .5)).astype(np.uint8).transpose((1,2,0)))
26
+
27
+ def normalized_array(image):
28
+ np_array = np.array(image)
29
+ return np.expand_dims(((np_array / 255 - .5)/.5).astype(np.float32).transpose((2,0,1)),0)
30
+
31
+ def array2im(np_array):
32
+ return Image.fromarray((255 * ((np_array * .5) + .5)).astype(np.uint8).transpose((1,2,0)))
33
+
34
+ def square_human_2_zombie(image,model):
35
+ tensor = normalized_tensor(image)
36
+ generated = model(tensor.unsqueeze(0))
37
+ return tensor2im(generated.data[0])
38
+
39
+ def square_human_2_zombie_onnx(image,model):
40
+ np_array = normalized_array(image)
41
+ ort_inputs = {"input": np_array}
42
+ ort_outs = model.run(None, ort_inputs)
43
+ return array2im(ort_outs[0][0])
44
+
45
+ def human_2_zombie_onnx(rgb_image,model,output_size=512):
46
+ square,_ = align.align(rgb_image,enable_padding=False,output_size=output_size)
47
+ if square is None:
48
+ return None
49
+ return square_human_2_zombie_onnx(square,model)
50
+
51
+ def human_2_zombie(rgb_image,model,output_size=512):
52
+ square,_ = align.align(rgb_image,enable_padding=False,output_size=output_size)
53
+ if square is None:
54
+ return None
55
+ return square_human_2_zombie(square,model)
56
+
57
+ def human_path_2_zombie(path):
58
+ rgb_image = ImageOpen(path).convert("RGB")
59
+ return human_2_zombie(rgb_image)
60
+
61
+ def transition(path,model):
62
+ rgb_image = ImageOpen(path).convert("RGB")
63
+ square,_ = align.align(rgb_image,enable_padding=False)
64
+ if square is None:
65
+ return None
66
+ zombie = square_human_2_zombie(square,model)
67
+ return get_concat_h(square,zombie)
68
+
69
+ def transition_onnx(rgb_image,model):
70
+ #square,_ = align.align(rgb_image,enable_padding=False)
71
+ # if square is None:
72
+ # return None
73
+
74
+ #Take the largest square in the upper left corner
75
+ #And resize it to 512x512
76
+ side = min(rgb_image.width,rgb_image.height)
77
+ square = rgb_image.crop((0,0,side,side))
78
+ square = square.resize((512,512))
79
+
80
+ zombie = square_human_2_zombie_onnx(square,model)
81
+
82
+ return get_concat_h(square,zombie)
83
+
84
+ def get_concat_h(im1,im2):
85
+ dst = Image.new('RGB', (im1.width + im2.width, im1.height))
86
+ dst.paste(im1, (0, 0))
87
+ dst.paste(im2, (im1.width, 0))
88
+ return dst
89
+
90
+ def get_concat_multiple_h(*ims):
91
+ to_return = ims[0]
92
+ for i in range(1,len(ims)):
93
+ to_return = get_concat_h(to_return,ims[i])
94
+
95
+ return to_return
96
+
97
+ def ImageOpen(filepath):
98
+ try:
99
+ image=Image.open(filepath)
100
+
101
+ for orientation in ExifTags.TAGS.keys():
102
+ if ExifTags.TAGS[orientation]=='Orientation':
103
+ break
104
+
105
+ exif=dict(image._getexif().items())
106
+
107
+ if exif[orientation] == 3:
108
+ image=image.rotate(180, expand=True)
109
+ elif exif[orientation] == 6:
110
+ image=image.rotate(270, expand=True)
111
+ elif exif[orientation] == 8:
112
+ image=image.rotate(90, expand=True)
113
+
114
+ image = image.convert('RGB')
115
+
116
+ return image
117
+ except (AttributeError, KeyError, IndexError):
118
+ # cases: image don't have getexif
119
+ return Image.open(filepath)
120
+
121
+ def do_face(facenet, aligned, box, im_array, ort_session):
122
+ z = square_human_2_zombie_onnx(aligned,ort_session)
123
+ t1 = time.time()
124
+
125
+ t = cv2.getAffineTransform(np.array([[0,0],[0,511],[511,511]],dtype="float32"),box[:3,:].astype("float32"))
126
+
127
+ h,w,c = im_array.shape
128
+ face_in_place = cv2.warpAffine(np.array(z),t,(w,h))
129
+
130
+ face_classes = inferface.run_net(facenet,aligned)
131
+ face_mask = np.logical_and(face_classes < 14, face_classes > 0)
132
+
133
+ # face_classes_z = inferface.run_net(facenet,z)
134
+ # face_mask_z = np.logical_and(face_classes_z < 14, face_classes > 0)
135
+
136
+ # face_mask = np.logical_or(face_mask,face_mask_z)
137
+
138
+ imagemask = cv2.warpAffine(face_mask.astype("uint8"),t,(w,h))
139
+
140
+ imagemask = imagemask.astype("uint8")
141
+
142
+ cv2.copyTo(face_in_place,imagemask,im_array)
143
+
144
+ def make_faces_zombie(path, facenet, ort_session):
145
+ im = Image.open(path)
146
+ im = im.convert(mode="RGB")
147
+ im_array = np.array(im)
148
+
149
+ return make_faces_zombie_from_array(im_array, facenet, ort_session)
150
+
151
+ def make_faces_zombie_from_array(im_array_rgb, facenet, ort_session):
152
+ im_array_rgb = np.copy(im_array_rgb)
153
+
154
+ t0 = time.time()
155
+ faces = align.aligns(Image.fromarray(im_array_rgb),enable_padding=True,output_size=512)
156
+ print("Find faces",time.time() - t0)
157
+ if faces is None:
158
+ faces = []
159
+
160
+ for aligned,box in faces:
161
+ do_face(facenet,aligned,box,im_array_rgb,ort_session)
162
+
163
+ return Image.fromarray(im_array_rgb)