Spaces:
Runtime error
Runtime error
Update app.py
Browse files
app.py
CHANGED
|
@@ -90,32 +90,30 @@ def swap_hair(face, shape, color, blending, poisson_iters, poisson_erosion):
|
|
| 90 |
|
| 91 |
def get_demo():
|
| 92 |
with gr.Blocks() as demo:
|
| 93 |
-
gr.Markdown("## Hair
|
| 94 |
-
|
| 95 |
with gr.Row():
|
| 96 |
with gr.Column():
|
|
|
|
| 97 |
with gr.Row():
|
| 98 |
-
|
| 99 |
-
shape = gr.Image(label="Shape photo with desired hairstyle (optional)", type="pil")
|
| 100 |
color = gr.Image(label="Color photo with desired hair color (optional)", type="pil")
|
| 101 |
-
with gr.
|
| 102 |
-
|
| 103 |
-
|
| 104 |
-
|
| 105 |
-
|
| 106 |
-
|
| 107 |
-
|
| 108 |
-
|
| 109 |
-
|
| 110 |
-
|
| 111 |
-
|
| 112 |
-
btn = gr.Button("Design Now!")
|
| 113 |
with gr.Column():
|
| 114 |
output = gr.Image(label="Your result")
|
| 115 |
-
error_message = gr.Textbox(label="⚠️ Error ⚠️", visible=
|
| 116 |
|
| 117 |
-
gr.Examples(examples=[["input/0.png", "input/1.png", "input/2.png"],
|
| 118 |
-
["input/6.png", "input/7.png", None],
|
| 119 |
["input/10.jpg", None, "input/11.jpg"]],
|
| 120 |
inputs=[source, shape, color], outputs=output)
|
| 121 |
|
|
@@ -126,11 +124,147 @@ def get_demo():
|
|
| 126 |
btn.click(fn=swap_hair, inputs=[source, shape, color, blending, poisson_iters, poisson_erosion],
|
| 127 |
outputs=[output, error_message])
|
| 128 |
|
| 129 |
-
|
| 130 |
return demo
|
| 131 |
|
| 132 |
|
| 133 |
if __name__ == '__main__':
|
| 134 |
align_cache = LRUCache(maxsize=10)
|
| 135 |
demo = get_demo()
|
| 136 |
-
demo.launch(server_name="0.0.0.0", server_port=7860
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 90 |
|
| 91 |
def get_demo():
|
| 92 |
with gr.Blocks() as demo:
|
| 93 |
+
gr.Markdown("## Hair")
|
| 94 |
+
|
| 95 |
with gr.Row():
|
| 96 |
with gr.Column():
|
| 97 |
+
source = gr.Image(label="Source photo to try on the hairstyle", type="pil")
|
| 98 |
with gr.Row():
|
| 99 |
+
shape = gr.Image(label="Shape photo with desired hairstyle (optional)", type="pil")
|
|
|
|
| 100 |
color = gr.Image(label="Color photo with desired hair color (optional)", type="pil")
|
| 101 |
+
with gr.Accordion("Advanced Options", open=False):
|
| 102 |
+
blending = gr.Radio(["Article", "Alternative_v1", "Alternative_v2"], value='Article',
|
| 103 |
+
label="Color Encoder version", info="Selects a model for hair color transfer.")
|
| 104 |
+
poisson_iters = gr.Slider(0, 2500, value=0, step=1, label="Poisson iters",
|
| 105 |
+
info="The power of blending with the original image, helps to recover more details. Not included in the article, disabled by default.")
|
| 106 |
+
poisson_erosion = gr.Slider(1, 100, value=15, step=1, label="Poisson erosion",
|
| 107 |
+
info="Smooths out the blending area.")
|
| 108 |
+
align = gr.CheckboxGroup(["Face", "Shape", "Color"], value=["Face", "Shape", "Color"],
|
| 109 |
+
label="Image cropping [recommended]",
|
| 110 |
+
info="Selects which images to crop by face")
|
| 111 |
+
btn = gr.Button("Get the haircut")
|
|
|
|
| 112 |
with gr.Column():
|
| 113 |
output = gr.Image(label="Your result")
|
| 114 |
+
error_message = gr.Textbox(label="⚠️ Error ⚠️", visible=False, elem_classes="error-message")
|
| 115 |
|
| 116 |
+
gr.Examples(examples=[["input/0.png", "input/1.png", "input/2.png"], ["input/6.png", "input/7.png", None],
|
|
|
|
| 117 |
["input/10.jpg", None, "input/11.jpg"]],
|
| 118 |
inputs=[source, shape, color], outputs=output)
|
| 119 |
|
|
|
|
| 124 |
btn.click(fn=swap_hair, inputs=[source, shape, color, blending, poisson_iters, poisson_erosion],
|
| 125 |
outputs=[output, error_message])
|
| 126 |
|
| 127 |
+
|
| 128 |
return demo
|
| 129 |
|
| 130 |
|
| 131 |
if __name__ == '__main__':
|
| 132 |
align_cache = LRUCache(maxsize=10)
|
| 133 |
demo = get_demo()
|
| 134 |
+
demo.launch(server_name="0.0.0.0", server_port=7860)
|
| 135 |
+
# import hashlib
|
| 136 |
+
# import os
|
| 137 |
+
# from io import BytesIO
|
| 138 |
+
|
| 139 |
+
# import gradio as gr
|
| 140 |
+
# import grpc
|
| 141 |
+
# from PIL import Image
|
| 142 |
+
# from cachetools import LRUCache
|
| 143 |
+
|
| 144 |
+
# from inference_pb2 import HairSwapRequest, HairSwapResponse
|
| 145 |
+
# from inference_pb2_grpc import HairSwapServiceStub
|
| 146 |
+
# from utils.shape_predictor import align_face
|
| 147 |
+
|
| 148 |
+
|
| 149 |
+
# def get_bytes(img):
|
| 150 |
+
# if img is None:
|
| 151 |
+
# return img
|
| 152 |
+
|
| 153 |
+
# buffered = BytesIO()
|
| 154 |
+
# img.save(buffered, format="JPEG")
|
| 155 |
+
# return buffered.getvalue()
|
| 156 |
+
|
| 157 |
+
|
| 158 |
+
# def bytes_to_image(image: bytes) -> Image.Image:
|
| 159 |
+
# image = Image.open(BytesIO(image))
|
| 160 |
+
# return image
|
| 161 |
+
|
| 162 |
+
|
| 163 |
+
# def center_crop(img):
|
| 164 |
+
# width, height = img.size
|
| 165 |
+
# side = min(width, height)
|
| 166 |
+
|
| 167 |
+
# left = (width - side) / 2
|
| 168 |
+
# top = (height - side) / 2
|
| 169 |
+
# right = (width + side) / 2
|
| 170 |
+
# bottom = (height + side) / 2
|
| 171 |
+
|
| 172 |
+
# img = img.crop((left, top, right, bottom))
|
| 173 |
+
# return img
|
| 174 |
+
|
| 175 |
+
|
| 176 |
+
# def resize(name):
|
| 177 |
+
# def resize_inner(img, align):
|
| 178 |
+
# global align_cache
|
| 179 |
+
|
| 180 |
+
# if name in align:
|
| 181 |
+
# img_hash = hashlib.md5(get_bytes(img)).hexdigest()
|
| 182 |
+
|
| 183 |
+
# if img_hash not in align_cache:
|
| 184 |
+
# img = align_face(img, return_tensors=False)[0]
|
| 185 |
+
# align_cache[img_hash] = img
|
| 186 |
+
# else:
|
| 187 |
+
# img = align_cache[img_hash]
|
| 188 |
+
|
| 189 |
+
# elif img.size != (1024, 1024):
|
| 190 |
+
# img = center_crop(img)
|
| 191 |
+
# img = img.resize((1024, 1024), Image.Resampling.LANCZOS)
|
| 192 |
+
|
| 193 |
+
# return img
|
| 194 |
+
|
| 195 |
+
# return resize_inner
|
| 196 |
+
|
| 197 |
+
|
| 198 |
+
# def swap_hair(face, shape, color, blending, poisson_iters, poisson_erosion):
|
| 199 |
+
# if not face and not shape and not color:
|
| 200 |
+
# return gr.update(visible=False), gr.update(value="Need to upload a face and at least a shape or color ❗", visible=True)
|
| 201 |
+
# elif not face:
|
| 202 |
+
# return gr.update(visible=False), gr.update(value="Need to upload a face ❗", visible=True)
|
| 203 |
+
# elif not shape and not color:
|
| 204 |
+
# return gr.update(visible=False), gr.update(value="Need to upload at least a shape or color ❗", visible=True)
|
| 205 |
+
|
| 206 |
+
# face_bytes, shape_bytes, color_bytes = map(lambda item: get_bytes(item), (face, shape, color))
|
| 207 |
+
|
| 208 |
+
# if shape_bytes is None:
|
| 209 |
+
# shape_bytes = b'face'
|
| 210 |
+
# if color_bytes is None:
|
| 211 |
+
# color_bytes = b'shape'
|
| 212 |
+
|
| 213 |
+
# with grpc.insecure_channel(os.environ['SERVER']) as channel:
|
| 214 |
+
# stub = HairSwapServiceStub(channel)
|
| 215 |
+
|
| 216 |
+
# output: HairSwapResponse = stub.swap(
|
| 217 |
+
# HairSwapRequest(face=face_bytes, shape=shape_bytes, color=color_bytes, blending=blending,
|
| 218 |
+
# poisson_iters=poisson_iters, poisson_erosion=poisson_erosion, use_cache=True)
|
| 219 |
+
# )
|
| 220 |
+
|
| 221 |
+
# output = bytes_to_image(output.image)
|
| 222 |
+
# return gr.update(value=output, visible=True), gr.update(visible=False)
|
| 223 |
+
|
| 224 |
+
|
| 225 |
+
# def get_demo():
|
| 226 |
+
# with gr.Blocks() as demo:
|
| 227 |
+
# gr.Markdown("## Hair Designer")
|
| 228 |
+
|
| 229 |
+
# with gr.Row():
|
| 230 |
+
# with gr.Column():
|
| 231 |
+
# with gr.Row():
|
| 232 |
+
# source = gr.Image(label="Source photo to try on the hairstyle", type="pil")
|
| 233 |
+
# shape = gr.Image(label="Shape photo with desired hairstyle (optional)", type="pil")
|
| 234 |
+
# color = gr.Image(label="Color photo with desired hair color (optional)", type="pil")
|
| 235 |
+
# with gr.Row():
|
| 236 |
+
# with gr.Accordion("Advanced Options", open=False):
|
| 237 |
+
# blending = gr.Radio(["Article", "Alternative_v1", "Alternative_v2"], value='Article',
|
| 238 |
+
# label="Color Encoder version", info="Selects a model for hair color transfer.")
|
| 239 |
+
# poisson_iters = gr.Slider(0, 2500, value=0, step=1, label="Poisson iters",
|
| 240 |
+
# info="The power of blending with the original image, helps to recover more details. Not included in the article, disabled by default.")
|
| 241 |
+
# poisson_erosion = gr.Slider(1, 100, value=15, step=1, label="Poisson erosion",
|
| 242 |
+
# info="Smooths out the blending area.")
|
| 243 |
+
# align = gr.CheckboxGroup(["Face", "Shape", "Color"], value=["Face", "Shape", "Color"],
|
| 244 |
+
# label="Image cropping [recommended]",
|
| 245 |
+
# info="Selects which images to crop by face")
|
| 246 |
+
# btn = gr.Button("Design Now!")
|
| 247 |
+
# with gr.Column():
|
| 248 |
+
# output = gr.Image(label="Your result")
|
| 249 |
+
# error_message = gr.Textbox(label="⚠️ Error ⚠️", visible=True, elem_classes="error-message")
|
| 250 |
+
|
| 251 |
+
# gr.Examples(examples=[["input/0.png", "input/1.png", "input/2.png"],
|
| 252 |
+
# ["input/6.png", "input/7.png", None],
|
| 253 |
+
# ["input/10.jpg", None, "input/11.jpg"]],
|
| 254 |
+
# inputs=[source, shape, color], outputs=output)
|
| 255 |
+
|
| 256 |
+
# source.upload(fn=resize('Face'), inputs=[source, align], outputs=source)
|
| 257 |
+
# shape.upload(fn=resize('Shape'), inputs=[shape, align], outputs=shape)
|
| 258 |
+
# color.upload(fn=resize('Color'), inputs=[color, align], outputs=color)
|
| 259 |
+
|
| 260 |
+
# btn.click(fn=swap_hair, inputs=[source, shape, color, blending, poisson_iters, poisson_erosion],
|
| 261 |
+
# outputs=[output, error_message])
|
| 262 |
+
|
| 263 |
+
|
| 264 |
+
# return demo
|
| 265 |
+
|
| 266 |
+
|
| 267 |
+
# if __name__ == '__main__':
|
| 268 |
+
# align_cache = LRUCache(maxsize=10)
|
| 269 |
+
# demo = get_demo()
|
| 270 |
+
# demo.launch(server_name="0.0.0.0", server_port=7860, debug=True)
|