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
|