Upload folder using huggingface_hub
Browse files- inference.py +2 -3
- internals/pipelines/pose_detector.py +36 -8
- internals/pipelines/upscaler.py +25 -4
- internals/util/commons.py +4 -2
- requirements.txt +1 -0
inference.py
CHANGED
@@ -293,7 +293,7 @@ def pose(task: Task, s3_outkey: str = "_pose", poses: Optional[list] = None):
|
|
293 |
lora_patcher = lora_style.get_patcher(controlnet.pipe2, task.get_style())
|
294 |
lora_patcher.patch()
|
295 |
|
296 |
-
|
297 |
infered_pose = pose_detector.transform(
|
298 |
image=task.get_imageUrl(),
|
299 |
client_coordinates=task.get_pose_coordinates(),
|
@@ -301,8 +301,7 @@ def pose(task: Task, s3_outkey: str = "_pose", poses: Optional[list] = None):
|
|
301 |
height=task.get_height(),
|
302 |
)
|
303 |
poses = [infered_pose] * num_return_sequences
|
304 |
-
|
305 |
-
print("Failed to detect pose, using Open Pose detector", e)
|
306 |
poses = [controlnet.detect_pose(task.get_imageUrl())] * num_return_sequences
|
307 |
|
308 |
images, has_nsfw = controlnet.process_pose(
|
|
|
293 |
lora_patcher = lora_style.get_patcher(controlnet.pipe2, task.get_style())
|
294 |
lora_patcher.patch()
|
295 |
|
296 |
+
if task.get_pose_coordinates():
|
297 |
infered_pose = pose_detector.transform(
|
298 |
image=task.get_imageUrl(),
|
299 |
client_coordinates=task.get_pose_coordinates(),
|
|
|
301 |
height=task.get_height(),
|
302 |
)
|
303 |
poses = [infered_pose] * num_return_sequences
|
304 |
+
else:
|
|
|
305 |
poses = [controlnet.detect_pose(task.get_imageUrl())] * num_return_sequences
|
306 |
|
307 |
images, has_nsfw = controlnet.process_pose(
|
internals/pipelines/pose_detector.py
CHANGED
@@ -10,7 +10,6 @@ from models.pose.body import Body
|
|
10 |
|
11 |
|
12 |
class PoseDetector:
|
13 |
-
# __det_model = "https://comic-assets.s3.ap-south-1.amazonaws.com/models/faster_rcnn_r50_fpn_1x_coco_20200130-047c8118.pth"
|
14 |
__pose_model = (
|
15 |
"https://comic-assets.s3.ap-south-1.amazonaws.com/models/body_pose_model.pth"
|
16 |
)
|
@@ -41,11 +40,17 @@ class PoseDetector:
|
|
41 |
image = download_image(image)
|
42 |
|
43 |
infer_coordinates = self.infer(image, width, height)
|
|
|
|
|
|
|
|
|
|
|
|
|
44 |
if client_coordinates and client_coordinates["candidate"]:
|
45 |
client_coordinates = self.resize_coordinates(
|
46 |
client_coordinates, 384, 384, width, height
|
47 |
)
|
48 |
-
infer_coordinates = self.
|
49 |
client_coordinates, infer_coordinates
|
50 |
)
|
51 |
|
@@ -90,9 +95,10 @@ class PoseDetector:
|
|
90 |
)
|
91 |
|
92 |
for i, point in enumerate(points):
|
93 |
-
x = point
|
94 |
-
y = point
|
95 |
-
|
|
|
96 |
|
97 |
return image
|
98 |
|
@@ -111,9 +117,9 @@ class PoseDetector:
|
|
111 |
|
112 |
candidate = [item[:2] for item in candidate]
|
113 |
|
114 |
-
return {"candidate": candidate
|
115 |
|
116 |
-
def
|
117 |
self, client_coordinates: dict, infer_coordinates: dict
|
118 |
) -> dict:
|
119 |
client_points = client_coordinates["candidate"]
|
@@ -125,12 +131,34 @@ class PoseDetector:
|
|
125 |
dx = i_neck[0] - c_neck[0]
|
126 |
dy = i_neck[1] - c_neck[1]
|
127 |
|
128 |
-
|
|
|
129 |
point = client_points[i - 1]
|
130 |
infer_points[i - 1] = [point[0] + dx, point[1] + dy]
|
131 |
|
132 |
return {"candidate": infer_points, "subset": infer_coordinates["subset"]}
|
133 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
134 |
def __convert_keypoints(self, keypoints):
|
135 |
return [keypoints[i] for i in self.__kim]
|
136 |
|
|
|
10 |
|
11 |
|
12 |
class PoseDetector:
|
|
|
13 |
__pose_model = (
|
14 |
"https://comic-assets.s3.ap-south-1.amazonaws.com/models/body_pose_model.pth"
|
15 |
)
|
|
|
40 |
image = download_image(image)
|
41 |
|
42 |
infer_coordinates = self.infer(image, width, height)
|
43 |
+
candidate_list = self.make_pose_from_subset(
|
44 |
+
infer_coordinates["candidate"], infer_coordinates["subset"]
|
45 |
+
)
|
46 |
+
# hard check only one person
|
47 |
+
infer_coordinates["candidate"] = candidate_list[0]
|
48 |
+
|
49 |
if client_coordinates and client_coordinates["candidate"]:
|
50 |
client_coordinates = self.resize_coordinates(
|
51 |
client_coordinates, 384, 384, width, height
|
52 |
)
|
53 |
+
infer_coordinates = self.map_coordinates(
|
54 |
client_coordinates, infer_coordinates
|
55 |
)
|
56 |
|
|
|
95 |
)
|
96 |
|
97 |
for i, point in enumerate(points):
|
98 |
+
x = safe_index(point, 0)
|
99 |
+
y = safe_index(point, 1)
|
100 |
+
if x and y:
|
101 |
+
draw.ellipse((x - 3, y - 3, x + 3, y + 3), fill=self.__points_color[i])
|
102 |
|
103 |
return image
|
104 |
|
|
|
117 |
|
118 |
candidate = [item[:2] for item in candidate]
|
119 |
|
120 |
+
return {"candidate": candidate, "subset": subset}
|
121 |
|
122 |
+
def map_coordinates(
|
123 |
self, client_coordinates: dict, infer_coordinates: dict
|
124 |
) -> dict:
|
125 |
client_points = client_coordinates["candidate"]
|
|
|
131 |
dx = i_neck[0] - c_neck[0]
|
132 |
dy = i_neck[1] - c_neck[1]
|
133 |
|
134 |
+
# Considering client coordinates truthy and translate it to the position of infered coordinates
|
135 |
+
for i in range(len(client_points)):
|
136 |
point = client_points[i - 1]
|
137 |
infer_points[i - 1] = [point[0] + dx, point[1] + dy]
|
138 |
|
139 |
return {"candidate": infer_points, "subset": infer_coordinates["subset"]}
|
140 |
|
141 |
+
def make_pose_from_subset(self, candidate, subset):
|
142 |
+
"Maps pose coordinates for subset"
|
143 |
+
|
144 |
+
def make_pose_from_subset_item(candidate, subset_item):
|
145 |
+
pose = []
|
146 |
+
for j in range(18):
|
147 |
+
i = int(subset_item[j])
|
148 |
+
pose.append(
|
149 |
+
None
|
150 |
+
if i < 0 or not safe_index(candidate, i)
|
151 |
+
else list(map(lambda x: x, candidate[i]))
|
152 |
+
)
|
153 |
+
return pose
|
154 |
+
|
155 |
+
return list(
|
156 |
+
map(
|
157 |
+
lambda subset_item: make_pose_from_subset_item(candidate, subset_item),
|
158 |
+
subset,
|
159 |
+
)
|
160 |
+
)
|
161 |
+
|
162 |
def __convert_keypoints(self, keypoints):
|
163 |
return [keypoints[i] for i in self.__kim]
|
164 |
|
internals/pipelines/upscaler.py
CHANGED
@@ -7,16 +7,21 @@ import cv2
|
|
7 |
import numpy as np
|
8 |
from basicsr.archs.rrdbnet_arch import RRDBNet
|
9 |
from basicsr.utils.download_util import load_file_from_url
|
|
|
10 |
from PIL import Image
|
11 |
from realesrgan import RealESRGANer
|
12 |
|
13 |
import internals.util.image as ImageUtil
|
14 |
from internals.util.commons import download_image
|
|
|
15 |
|
16 |
|
17 |
class Upscaler:
|
18 |
__model_esrgan_url = "https://github.com/xinntao/Real-ESRGAN/releases/download/v0.1.0/RealESRGAN_x4plus.pth"
|
19 |
__model_esrgan_anime_url = "https://github.com/xinntao/Real-ESRGAN/releases/download/v0.2.2.4/RealESRGAN_x4plus_anime_6B.pth"
|
|
|
|
|
|
|
20 |
|
21 |
__loaded = False
|
22 |
|
@@ -31,6 +36,9 @@ class Upscaler:
|
|
31 |
self.__model_path_anime = self.__preload_model(
|
32 |
self.__model_esrgan_anime_url, download_dir
|
33 |
)
|
|
|
|
|
|
|
34 |
self.__loaded = True
|
35 |
|
36 |
def upscale(self, image: Union[str, Image.Image], resize_dimension: int) -> bytes:
|
@@ -88,13 +96,26 @@ class Upscaler:
|
|
88 |
if isinstance(image, Image.Image):
|
89 |
image = ImageUtil.to_bytes(image)
|
90 |
|
91 |
-
upsampler = RealESRGANer(
|
92 |
-
scale=4, model_path=model_path, model=rrbdnet, half="fp16", gpu_id="0"
|
93 |
-
)
|
94 |
image_array = np.frombuffer(image, dtype=np.uint8)
|
95 |
input_image = cv2.imdecode(image_array, cv2.IMREAD_COLOR)
|
96 |
dimension = min(input_image.shape[0], input_image.shape[1])
|
97 |
scale = max(math.floor(resize_dimension / dimension), 2)
|
98 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
99 |
out_bytes = cv2.imencode(".png", output)[1].tobytes()
|
100 |
return out_bytes
|
|
|
7 |
import numpy as np
|
8 |
from basicsr.archs.rrdbnet_arch import RRDBNet
|
9 |
from basicsr.utils.download_util import load_file_from_url
|
10 |
+
from gfpgan import GFPGANer
|
11 |
from PIL import Image
|
12 |
from realesrgan import RealESRGANer
|
13 |
|
14 |
import internals.util.image as ImageUtil
|
15 |
from internals.util.commons import download_image
|
16 |
+
from internals.util.config import get_root_dir
|
17 |
|
18 |
|
19 |
class Upscaler:
|
20 |
__model_esrgan_url = "https://github.com/xinntao/Real-ESRGAN/releases/download/v0.1.0/RealESRGAN_x4plus.pth"
|
21 |
__model_esrgan_anime_url = "https://github.com/xinntao/Real-ESRGAN/releases/download/v0.2.2.4/RealESRGAN_x4plus_anime_6B.pth"
|
22 |
+
__model_gfpgan_url = (
|
23 |
+
"https://github.com/TencentARC/GFPGAN/releases/download/v1.3.0/GFPGANv1.3.pth"
|
24 |
+
)
|
25 |
|
26 |
__loaded = False
|
27 |
|
|
|
36 |
self.__model_path_anime = self.__preload_model(
|
37 |
self.__model_esrgan_anime_url, download_dir
|
38 |
)
|
39 |
+
self.__model_path_gfpgan = self.__preload_model(
|
40 |
+
self.__model_gfpgan_url, download_dir
|
41 |
+
)
|
42 |
self.__loaded = True
|
43 |
|
44 |
def upscale(self, image: Union[str, Image.Image], resize_dimension: int) -> bytes:
|
|
|
96 |
if isinstance(image, Image.Image):
|
97 |
image = ImageUtil.to_bytes(image)
|
98 |
|
|
|
|
|
|
|
99 |
image_array = np.frombuffer(image, dtype=np.uint8)
|
100 |
input_image = cv2.imdecode(image_array, cv2.IMREAD_COLOR)
|
101 |
dimension = min(input_image.shape[0], input_image.shape[1])
|
102 |
scale = max(math.floor(resize_dimension / dimension), 2)
|
103 |
+
|
104 |
+
os.chdir(str(Path.home() / ".cache"))
|
105 |
+
upsampler = RealESRGANer(
|
106 |
+
scale=4, model_path=model_path, model=rrbdnet, half="fp16", gpu_id="0"
|
107 |
+
)
|
108 |
+
face_enhancer = GFPGANer(
|
109 |
+
model_path=self.__model_path_gfpgan,
|
110 |
+
upscale=scale,
|
111 |
+
arch="clean",
|
112 |
+
channel_multiplier=2,
|
113 |
+
bg_upsampler=upsampler,
|
114 |
+
)
|
115 |
+
|
116 |
+
_, _, output = face_enhancer.enhance(
|
117 |
+
input_image, has_aligned=False, only_center_face=True, paste_back=True
|
118 |
+
)
|
119 |
+
os.chdir(get_root_dir())
|
120 |
out_bytes = cv2.imencode(".png", output)[1].tobytes()
|
121 |
return out_bytes
|
internals/util/commons.py
CHANGED
@@ -5,7 +5,7 @@ import random
|
|
5 |
import re
|
6 |
from io import BytesIO
|
7 |
from pathlib import Path
|
8 |
-
from typing import Optional, Union
|
9 |
|
10 |
import boto3
|
11 |
import requests
|
@@ -191,7 +191,9 @@ def construct_default_s3_url(key):
|
|
191 |
return "https://comic-assets.s3.ap-south-1.amazonaws.com/" + key
|
192 |
|
193 |
|
194 |
-
def safe_index(array, index) -> Optional:
|
|
|
|
|
195 |
if index < 0:
|
196 |
return None
|
197 |
if index >= len(array):
|
|
|
5 |
import re
|
6 |
from io import BytesIO
|
7 |
from pathlib import Path
|
8 |
+
from typing import Any, Optional, Union
|
9 |
|
10 |
import boto3
|
11 |
import requests
|
|
|
191 |
return "https://comic-assets.s3.ap-south-1.amazonaws.com/" + key
|
192 |
|
193 |
|
194 |
+
def safe_index(array, index) -> Optional[Any]:
|
195 |
+
if not array:
|
196 |
+
return None
|
197 |
if index < 0:
|
198 |
return None
|
199 |
if index >= len(array):
|
requirements.txt
CHANGED
@@ -10,6 +10,7 @@ rembg==2.0.30
|
|
10 |
gfpgan==1.3.8
|
11 |
rembg==2.0.30
|
12 |
controlnet-aux==0.0.5
|
|
|
13 |
realesrgan==0.3.0
|
14 |
compel==1.0.4
|
15 |
scikit-image>=0.19.3
|
|
|
10 |
gfpgan==1.3.8
|
11 |
rembg==2.0.30
|
12 |
controlnet-aux==0.0.5
|
13 |
+
gfpgan>=1.3.4
|
14 |
realesrgan==0.3.0
|
15 |
compel==1.0.4
|
16 |
scikit-image>=0.19.3
|