andreyp89 commited on
Commit
23ed1d9
1 Parent(s): cd3d588

Initial commit

Browse files
.gitattributes CHANGED
@@ -33,3 +33,7 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
 
 
 
 
 
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
36
+ *.jpg filter=lfs diff=lfs merge=lfs -text
37
+ *.jpeg filter=lfs diff=lfs merge=lfs -text
38
+ *.png filter=lfs diff=lfs merge=lfs -text
39
+ *.webp filter=lfs diff=lfs merge=lfs -text
.gitignore ADDED
@@ -0,0 +1,149 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ debug/
2
+ testing/output/
3
+
4
+ # Byte-compiled / optimized / DLL files
5
+ __pycache__/
6
+ *.py[cod]
7
+ *$py.class
8
+
9
+ # C extensions
10
+ *.so
11
+
12
+ # Distribution / packaging
13
+ .Python
14
+ build/
15
+ develop-eggs/
16
+ dist/
17
+ downloads/
18
+ eggs/
19
+ .eggs/
20
+ lib/
21
+ lib64/
22
+ parts/
23
+ sdist/
24
+ var/
25
+ wheels/
26
+ share/python-wheels/
27
+ *.egg-info/
28
+ .installed.cfg
29
+ *.egg
30
+ MANIFEST
31
+
32
+ # PyInstaller
33
+ # Usually these files are written by a python script from a template
34
+ # before PyInstaller builds the exe, so as to inject date/other infos into it.
35
+ *.manifest
36
+ *.spec
37
+
38
+ # Installer logs
39
+ pip-log.txt
40
+ pip-delete-this-directory.txt
41
+
42
+ # Unit test / coverage reports
43
+ htmlcov/
44
+ .tox/
45
+ .nox/
46
+ .coverage
47
+ .coverage.*
48
+ .cache
49
+ nosetests.xml
50
+ coverage.xml
51
+ *.cover
52
+ *.py,cover
53
+ .hypothesis/
54
+ .pytest_cache/
55
+ cover/
56
+
57
+ # Translations
58
+ *.mo
59
+ *.pot
60
+
61
+ # Django stuff:
62
+ *.log
63
+ local_settings.py
64
+ db.sqlite3
65
+ db.sqlite3-journal
66
+
67
+ # Flask stuff:
68
+ instance/
69
+ .webassets-cache
70
+
71
+ # Scrapy stuff:
72
+ .scrapy
73
+
74
+ # Sphinx documentation
75
+ docs/_build/
76
+
77
+ # PyBuilder
78
+ .pybuilder/
79
+ target/
80
+
81
+ # Jupyter Notebook
82
+ .ipynb_checkpoints
83
+
84
+ # IPython
85
+ profile_default/
86
+ ipython_config.py
87
+
88
+ # pyenv
89
+ # For a library or package, you might want to ignore these files since the code is
90
+ # intended to run in multiple environments; otherwise, check them in:
91
+ # .python-version
92
+
93
+ # pipenv
94
+ # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
95
+ # However, in case of collaboration, if having platform-specific dependencies or dependencies
96
+ # having no cross-platform support, pipenv may install dependencies that don't work, or not
97
+ # install all needed dependencies.
98
+ #Pipfile.lock
99
+
100
+ # PEP 582; used by e.g. github.com/David-OConnor/pyflow
101
+ __pypackages__/
102
+
103
+ # Celery stuff
104
+ celerybeat-schedule
105
+ celerybeat.pid
106
+
107
+ # SageMath parsed files
108
+ *.sage.py
109
+
110
+ # Environments
111
+ .env
112
+ .venv
113
+ env/
114
+ venv/
115
+ ENV/
116
+ env.bak/
117
+ venv.bak/
118
+
119
+ # PyCharm
120
+ .idea
121
+
122
+ # Spyder project settings
123
+ .spyderproject
124
+ .spyproject
125
+
126
+ # Rope project settings
127
+ .ropeproject
128
+
129
+ # mkdocs documentation
130
+ /site
131
+
132
+ # mypy
133
+ .mypy_cache/
134
+ .dmypy.json
135
+ dmypy.json
136
+
137
+ # Pyre type checker
138
+ .pyre/
139
+
140
+ # pytype static type analyzer
141
+ .pytype/
142
+
143
+ # Cython debug symbols
144
+ cython_debug/
145
+
146
+ # MacOS filesystem
147
+ .DS_Store
148
+
149
+ .gradio
README.md CHANGED
@@ -1,13 +1,7 @@
1
- ---
2
- title: Try On Diffusion
3
- emoji: 🚀
4
- colorFrom: blue
5
- colorTo: pink
6
- sdk: gradio
7
- sdk_version: 5.3.0
8
- app_file: app.py
9
- pinned: false
10
- short_description: Diffusion-based multi-modal virtual try-on demo
11
- ---
12
 
13
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
 
 
 
 
1
+ # Virtual Try-On Diffusion [VTON-D] by Texel.Moda
 
 
 
 
 
 
 
 
 
 
2
 
3
+ Virtual Try-On Diffusion [VTON-D] by [Texel.Moda](https://texelmoda.com/) is a custom diffusion-based pipeline for fast
4
+ and flexible multi-modal virtual try-on. Clothing, avatar and background can be specified by reference images or text
5
+ prompts allowing for clothing transfer, avatar replacement, fashion image generation and other virtual try-on related
6
+ tasks. Feel free to [contact us](https://texelmoda.com/contact/) if you are interested in commercial API usage or
7
+ partnership.
app.py ADDED
@@ -0,0 +1,276 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import logging
2
+ import gradio as gr
3
+ import numpy as np
4
+ import cv2
5
+ import os
6
+ import base64
7
+
8
+ from try_on_diffusion_client import TryOnDiffusionClient
9
+
10
+ LOG_LEVEL = logging.INFO
11
+ LOG_FORMAT = "%(asctime)s %(thread)-8s %(name)-16s %(levelname)-8s %(message)s"
12
+ LOG_DATE_FORMAT = "%Y-%m-%d %H:%M:%S"
13
+
14
+ EXAMPLE_PATH = os.path.join(os.path.dirname(__file__), "examples")
15
+
16
+ API_URL = os.getenv("TRY_ON_DIFFUSION_DEMO_API_URL", "http://localhost:8000")
17
+ API_KEY = os.getenv("TRY_ON_DIFFUSION_DEMO_API_KEY", "")
18
+
19
+ CONCURRENCY_LIMIT = int(os.getenv("TRY_ON_DIFFUSION_DEMO_CONCURRENCY_LIMIT", "2"))
20
+
21
+ logging.basicConfig(level=LOG_LEVEL, format=LOG_FORMAT, datefmt=LOG_DATE_FORMAT)
22
+
23
+ client = TryOnDiffusionClient(base_url=API_URL, api_key=API_KEY)
24
+
25
+
26
+ def get_image_base64(file_name: str) -> str:
27
+ _, ext = os.path.splitext(file_name.lower())
28
+
29
+ content_type = "image/jpeg"
30
+
31
+ if ext == ".png":
32
+ content_type = "image/png"
33
+ elif ext == ".webp":
34
+ content_type = "image/webp"
35
+ elif ext == ".gif":
36
+ content_type = "image/gif"
37
+
38
+ with open(file_name, "rb") as f:
39
+ return f"data:{content_type};base64," + base64.b64encode(f.read()).decode("utf-8")
40
+
41
+
42
+ def get_examples(example_dir: str) -> list[str]:
43
+ file_list = [f for f in os.listdir(os.path.join(EXAMPLE_PATH, example_dir)) if f.endswith(".jpg")]
44
+ file_list.sort()
45
+
46
+ return [os.path.join(EXAMPLE_PATH, example_dir, f) for f in file_list]
47
+
48
+
49
+ def try_on(
50
+ clothing_image: np.ndarray = None,
51
+ clothing_prompt: str = None,
52
+ avatar_image: np.ndarray = None,
53
+ avatar_prompt: str = None,
54
+ avatar_sex: str = None,
55
+ background_image: np.ndarray = None,
56
+ background_prompt: str = None,
57
+ seed: int = -1,
58
+ ) -> tuple:
59
+ result = client.try_on_file(
60
+ clothing_image=cv2.cvtColor(clothing_image, cv2.COLOR_RGB2BGR) if clothing_image is not None else None,
61
+ clothing_prompt=clothing_prompt,
62
+ avatar_image=cv2.cvtColor(avatar_image, cv2.COLOR_RGB2BGR) if avatar_image is not None else None,
63
+ avatar_prompt=avatar_prompt,
64
+ avatar_sex=avatar_sex if avatar_sex in ["male", "female"] else None,
65
+ background_image=cv2.cvtColor(background_image, cv2.COLOR_RGB2BGR) if background_image is not None else None,
66
+ background_prompt=background_prompt,
67
+ seed=seed,
68
+ )
69
+
70
+ if result.status_code == 200:
71
+ return cv2.cvtColor(result.image, cv2.COLOR_RGB2BGR), f"<h3>Success</h3><p>Seed: {result.seed}</p>"
72
+ else:
73
+ error_message = f"<h3>Error {result.status_code}</h3>"
74
+
75
+ if result.error_details is not None:
76
+ error_message += f"<p>{result.error_details}</p>"
77
+
78
+ return None, error_message
79
+
80
+
81
+ with gr.Blocks(theme=gr.themes.Soft()) as app:
82
+ gr.HTML(
83
+ f"""
84
+ <div style="width: 100%; background-color: #001537; border-radius: 10px; padding-left: 10px">
85
+ <a href="https://texelmoda.com/" target="_blank">
86
+ <img src="{get_image_base64("images/logo.png")}" title="Texel.Moda" alt="Texel.Moda" style="float: left; margin-right: 10px; margin-left: -10px; border-radius: 10px; max-height: 50px;"/>
87
+ </a>
88
+ <h1 style="margin: 0; margin-right: 10px; line-height: 50px; color: #8cecd5; text-transform: uppercase">Virtual Try-On Diffusion</h1>
89
+ </div>
90
+ <br/>
91
+ <p>
92
+ Virtual Try-On Diffusion [VTON-D] by <a href="https://texelmoda.com/" target="_blank">Texel.Moda</a> is a
93
+ custom diffusion-based pipeline for fast and flexible multi-modal virtual try-on.
94
+ Clothing, avatar and background can be specified by reference images or text prompts allowing for clothing
95
+ transfer, avatar replacement, fashion image generation and other virtual try-on related tasks.
96
+ Feel free to <a href="https://texelmoda.com/contact/" target="_blank">contact us</a> if you are interested
97
+ in commercial API usage or partnership.
98
+ </p>
99
+ <br/>
100
+ """
101
+ )
102
+
103
+ with gr.Row():
104
+ with gr.Column():
105
+ gr.HTML(
106
+ """
107
+ <h2>Clothing</h2>
108
+ <p>
109
+ Clothing may be specified with a reference image or a text prompt.
110
+ For more exotic use cases image and prompt can be also used together.
111
+ If both image and prompt are empty the model will generate random clothing.
112
+ <br/><br/>
113
+ </p>
114
+ """
115
+ )
116
+
117
+ with gr.Tab("Image"):
118
+ clothing_image = gr.Image(label="Clothing Image", sources=["upload"], type="numpy")
119
+
120
+ clothing_image_examples = gr.Examples(
121
+ inputs=clothing_image, examples_per_page=12, examples=get_examples("clothing")
122
+ )
123
+
124
+ with gr.Tab("Prompt"):
125
+ clothing_prompt = gr.TextArea(
126
+ label="Clothing Prompt",
127
+ info='Compel weighting <a href="https://github.com/damian0815/compel/blob/main/doc/syntax.md">syntax</a> is supported.',
128
+ )
129
+
130
+ clothing_prompt_examples = gr.Examples(
131
+ inputs=clothing_prompt,
132
+ examples_per_page=8,
133
+ examples=[
134
+ "a sheer blue sleeveless mini dress",
135
+ "a beige woolen sweater and white pleated skirt",
136
+ "a black leather jacket and dark blue slim-fit jeans",
137
+ "a floral pattern blouse and leggings",
138
+ "a paisley pattern purple shirt and beige chinos",
139
+ "a striped white and blue polo shirt and blue jeans",
140
+ "a colorful t-shirt and black shorts",
141
+ "a checked pattern shirt and dark blue cargo pants",
142
+ ],
143
+ )
144
+
145
+ with gr.Column():
146
+ gr.HTML(
147
+ """
148
+ <h2>Avatar</h2>
149
+ <p>
150
+ Avatar may be specified with a subject photo or a text prompt.
151
+ Latter can be used, for example, to replace person while preserving clothing.
152
+ For more exotic use cases image and prompt can be also used together.
153
+ If both image and prompt are empty the model will generate random avatars.
154
+ </p>
155
+ """
156
+ )
157
+
158
+ with gr.Tab("Image"):
159
+ avatar_image = gr.Image(label="Avatar Image", sources=["upload"], type="numpy")
160
+
161
+ avatar_image_examples = gr.Examples(
162
+ inputs=avatar_image,
163
+ examples_per_page=12,
164
+ examples=get_examples("avatar"),
165
+ )
166
+
167
+ with gr.Tab("Prompt"):
168
+ avatar_prompt = gr.TextArea(
169
+ label="Avatar Prompt",
170
+ info='Compel weighting <a href="https://github.com/damian0815/compel/blob/main/doc/syntax.md">syntax</a> is supported.',
171
+ )
172
+
173
+ avatar_prompt_examples = gr.Examples(
174
+ inputs=avatar_prompt,
175
+ examples_per_page=8,
176
+ examples=[
177
+ "a beautiful blond girl with long hair",
178
+ "a cute redhead girl with freckles",
179
+ "a plus size female model wearing sunglasses",
180
+ "a woman with dark hair and blue eyes",
181
+ "a fit man with dark beard and blue eyes",
182
+ "a young blond man posing for a photo",
183
+ "a gentleman with beard and mustache",
184
+ "a plus size man walking",
185
+ ],
186
+ )
187
+
188
+ avatar_sex = gr.Dropdown(
189
+ label="Avatar Sex",
190
+ choices=[("Auto", ""), ("Male", "male"), ("Female", "female")],
191
+ value="",
192
+ info="Avatar sex selector can be used to enforce a specific sex of the avatar.",
193
+ )
194
+
195
+ with gr.Column():
196
+ gr.HTML(
197
+ """
198
+ <h2>Background</h2>
199
+ <p>
200
+ Replacing background is optional.
201
+ Background may be specified with a reference image or a text prompt.
202
+ If omitted original avatar background will be preserved.
203
+ <br/><br/><br/>
204
+ </p>
205
+ """
206
+ )
207
+
208
+ with gr.Tab("Image"):
209
+ background_image = gr.Image(label="Background Image", sources=["upload"], type="numpy")
210
+
211
+ background_image_examples = gr.Examples(
212
+ inputs=background_image, examples_per_page=12, examples=get_examples("background")
213
+ )
214
+
215
+ with gr.Tab("Prompt"):
216
+ background_prompt = gr.TextArea(
217
+ label="Background Prompt",
218
+ info='Compel weighting <a href="https://github.com/damian0815/compel/blob/main/doc/syntax.md">syntax</a> is supported.',
219
+ )
220
+
221
+ background_prompt_examples = gr.Examples(
222
+ inputs=background_prompt,
223
+ examples_per_page=8,
224
+ examples=[
225
+ "in an autumn park",
226
+ "in front of a brick wall",
227
+ "near an old tree",
228
+ "on a busy city street",
229
+ "in front of a staircase",
230
+ "on an ocean beach with palm trees",
231
+ "in a shopping mall",
232
+ "in a modern office",
233
+ ],
234
+ )
235
+
236
+ with gr.Column():
237
+ gr.HTML(
238
+ """
239
+ <h2>Generation</h2>
240
+ """
241
+ )
242
+
243
+ seed = gr.Number(
244
+ label="Seed",
245
+ value=-1,
246
+ minimum=-1,
247
+ info="Seed used for generation, specify -1 for random seed for each generation.",
248
+ )
249
+
250
+ generate_button = gr.Button(value="Generate", elem_id="button")
251
+
252
+ result_image = gr.Image(label="Result", show_share_button=False)
253
+ result_details = gr.HTML(label="Details")
254
+
255
+ generate_button.click(
256
+ fn=try_on,
257
+ inputs=[
258
+ clothing_image,
259
+ clothing_prompt,
260
+ avatar_image,
261
+ avatar_prompt,
262
+ avatar_sex,
263
+ background_image,
264
+ background_prompt,
265
+ seed,
266
+ ],
267
+ outputs=[result_image, result_details],
268
+ api_name=False,
269
+ concurrency_limit=CONCURRENCY_LIMIT,
270
+ )
271
+
272
+ app.title = "Virtual Try-On Diffusion by Texel.Moda"
273
+
274
+
275
+ if __name__ == "__main__":
276
+ app.queue(api_open=False).launch(show_api=False)
examples/avatar/female_01.jpg ADDED

Git LFS Details

  • SHA256: feb60696275f5276bcc0dc65e14bd972440b7973baa41609d0b6334d8b1c9880
  • Pointer size: 131 Bytes
  • Size of remote file: 211 kB
examples/avatar/female_02.jpg ADDED

Git LFS Details

  • SHA256: 0b02efe2043a9af0fa79bdc892b2e8535cc9fe83e3887e6ae49f14bff2f6faa0
  • Pointer size: 131 Bytes
  • Size of remote file: 294 kB
examples/avatar/female_03.jpg ADDED

Git LFS Details

  • SHA256: 70653888c42588a919f5eec01f7ce861cb19dd906f97f0c446d266d4c791b51b
  • Pointer size: 131 Bytes
  • Size of remote file: 195 kB
examples/avatar/female_04.jpg ADDED

Git LFS Details

  • SHA256: 4711e7d8e08cda7b29f331c1a790c729bbe264587c59dd76b6370c9e6491845c
  • Pointer size: 131 Bytes
  • Size of remote file: 416 kB
examples/avatar/female_05.jpg ADDED

Git LFS Details

  • SHA256: 1291a821607d3630318961f184987c8a494bfcc70ac93a315d5aeb8842475b50
  • Pointer size: 131 Bytes
  • Size of remote file: 425 kB
examples/avatar/female_06.jpg ADDED

Git LFS Details

  • SHA256: a8f92656f1243d3d9562f91807fa8d3ca11bf66ad9dd3736630f88862d76110b
  • Pointer size: 131 Bytes
  • Size of remote file: 262 kB
examples/avatar/male_01.jpg ADDED

Git LFS Details

  • SHA256: d9226c7ff9b67969cfa413c77c4c07974806009d59a96a15c4fbecdee1a5c8e2
  • Pointer size: 131 Bytes
  • Size of remote file: 191 kB
examples/avatar/male_02.jpg ADDED

Git LFS Details

  • SHA256: 02831ba12b974525a94e439c353fd720a7dae14c102b4b11baf38c56822807f9
  • Pointer size: 131 Bytes
  • Size of remote file: 352 kB
examples/avatar/male_03.jpg ADDED

Git LFS Details

  • SHA256: 2d9441acd683a497d4108582abb99bc333643de3368c05fffb9e911c7d3d1106
  • Pointer size: 131 Bytes
  • Size of remote file: 123 kB
examples/avatar/male_04.jpg ADDED

Git LFS Details

  • SHA256: 99ecc2bf9d21bdd22d1c42bfeab8537ee3dd1ce7139c3d15c6be9e782040a0fb
  • Pointer size: 131 Bytes
  • Size of remote file: 361 kB
examples/avatar/male_05.jpg ADDED

Git LFS Details

  • SHA256: bf364572f22b23c3567dc8f169e329a20f3e3def7cf1bc2e4349d98f16351d87
  • Pointer size: 131 Bytes
  • Size of remote file: 170 kB
examples/avatar/male_06.jpg ADDED

Git LFS Details

  • SHA256: bba21beb25ff292a6917e9cd377ccd53a63b46c97a4bb1e87d8c324a0187a52a
  • Pointer size: 131 Bytes
  • Size of remote file: 308 kB
examples/background/01.jpg ADDED

Git LFS Details

  • SHA256: cc6ad7187561a6a29044accc996aa242c48ea92f707d245dfdd75d545affd0bf
  • Pointer size: 131 Bytes
  • Size of remote file: 492 kB
examples/background/02.jpg ADDED

Git LFS Details

  • SHA256: 7a92ab3827aecf1c683f2a5c3f44ae546ede0769e74bbae238ca0380a50fcc6b
  • Pointer size: 131 Bytes
  • Size of remote file: 700 kB
examples/background/03.jpg ADDED

Git LFS Details

  • SHA256: 0f7f1044891103c2e5697c3b7cbd36ca869c63982f11a266077601b51549b74c
  • Pointer size: 131 Bytes
  • Size of remote file: 336 kB
examples/background/04.jpg ADDED

Git LFS Details

  • SHA256: 661a22b8d8442ad42d6dfa3e0ff563ed421ee7afab07d9bcf4ff5359f41c9d5f
  • Pointer size: 131 Bytes
  • Size of remote file: 511 kB
examples/background/05.jpg ADDED

Git LFS Details

  • SHA256: e311072b112866f7201474d83ba49eaa0fa695f2e589e83fd922d05e0c28195d
  • Pointer size: 131 Bytes
  • Size of remote file: 392 kB
examples/background/06.jpg ADDED

Git LFS Details

  • SHA256: f7b35a710cfba95a2816aacac8dc9d1bec3ff52ced993417c418d6d0c0ac562a
  • Pointer size: 131 Bytes
  • Size of remote file: 389 kB
examples/background/07.jpg ADDED

Git LFS Details

  • SHA256: 90f336f9b994a9f641d833d2f7e9f73002b0bfb08f2744171741fb862c5ffa24
  • Pointer size: 131 Bytes
  • Size of remote file: 553 kB
examples/background/08.jpg ADDED

Git LFS Details

  • SHA256: ef2954e7043187da9f54d1674cf4a31199edb258a19f12001b6e18c15bde7d57
  • Pointer size: 131 Bytes
  • Size of remote file: 384 kB
examples/background/09.jpg ADDED

Git LFS Details

  • SHA256: 2c23c1e456b78be12fca054820222678905d9e775a8f9d3c95bcf885248deb90
  • Pointer size: 131 Bytes
  • Size of remote file: 438 kB
examples/background/10.jpg ADDED

Git LFS Details

  • SHA256: 1a8a1342c72651307168618178dac0db65550af33e73a10e64e3d24428988434
  • Pointer size: 131 Bytes
  • Size of remote file: 315 kB
examples/background/11.jpg ADDED

Git LFS Details

  • SHA256: e865e32c08a6f98fb92e9da07d646f927f08aa577b8fa30283ec7624474d5286
  • Pointer size: 131 Bytes
  • Size of remote file: 357 kB
examples/background/12.jpg ADDED

Git LFS Details

  • SHA256: 4aa0f4dc7d148d55082c34534c382642e67b454c199befb7531c8b2b05145cd1
  • Pointer size: 131 Bytes
  • Size of remote file: 407 kB
examples/clothing/female_01.jpg ADDED

Git LFS Details

  • SHA256: 185a51562b6b04b8bc52eaf56c21451325af4379f6cfde4a7dcca8a15f1575c3
  • Pointer size: 131 Bytes
  • Size of remote file: 398 kB
examples/clothing/female_02.jpg ADDED

Git LFS Details

  • SHA256: 533de7bd0e3ae1862304523e2035d8ba0015109e8a39368a017a9a757144bafa
  • Pointer size: 131 Bytes
  • Size of remote file: 434 kB
examples/clothing/female_03.jpg ADDED

Git LFS Details

  • SHA256: d2531c286cfd8a25214691a4ed3f78bf6f9a3ea9d95a026784fe1b61482310ea
  • Pointer size: 131 Bytes
  • Size of remote file: 306 kB
examples/clothing/female_04.jpg ADDED

Git LFS Details

  • SHA256: 37a9c7f329ea51deaf80fd7592484ea065fbe7e0486aa2913fc0a85e48383004
  • Pointer size: 131 Bytes
  • Size of remote file: 278 kB
examples/clothing/female_05.jpg ADDED

Git LFS Details

  • SHA256: dac6b6ca50e3a81fe1c01f6a5975f894cdd2c5553705325d5d8dfa66447f41f4
  • Pointer size: 131 Bytes
  • Size of remote file: 245 kB
examples/clothing/female_06.jpg ADDED

Git LFS Details

  • SHA256: 790d96ee414267ccd3255b9aae12aa4946a5f452eace0413ca0bea508694c03f
  • Pointer size: 131 Bytes
  • Size of remote file: 445 kB
examples/clothing/male_01.jpg ADDED

Git LFS Details

  • SHA256: 3152b0a7e9b869f19aae0deb156359ffc87ce7efbf3a7a8cc35722b38c93853b
  • Pointer size: 131 Bytes
  • Size of remote file: 444 kB
examples/clothing/male_02.jpg ADDED

Git LFS Details

  • SHA256: 9495af8b97285a3456bfbb684881cd8c1ba9bfd76e215843d24caeb22c64c9f8
  • Pointer size: 131 Bytes
  • Size of remote file: 313 kB
examples/clothing/male_03.jpg ADDED

Git LFS Details

  • SHA256: dfee3b092114533daf468a03707da516433acfc2076ced135e604ba4a7904512
  • Pointer size: 131 Bytes
  • Size of remote file: 407 kB
examples/clothing/male_04.jpg ADDED

Git LFS Details

  • SHA256: 237d41460b8e53c4aa1f0f6c41ff99247215edb762c25f0ffd8a0b59842063a5
  • Pointer size: 131 Bytes
  • Size of remote file: 447 kB
examples/clothing/male_05.jpg ADDED

Git LFS Details

  • SHA256: 42da86578bacd3b16e4ad764a641a4f79034cb23227151fa3285d95c33083c3c
  • Pointer size: 131 Bytes
  • Size of remote file: 525 kB
examples/clothing/male_06.jpg ADDED

Git LFS Details

  • SHA256: c7af38fbc2886c265fb534a9684f60aad842cf83ee99696a56094c66267080df
  • Pointer size: 131 Bytes
  • Size of remote file: 399 kB
images/logo.png ADDED

Git LFS Details

  • SHA256: 7ef4aeca425cb5a3fe10ac0e291cd0512200822ca5a52bf41e8c086b6bdfb19b
  • Pointer size: 130 Bytes
  • Size of remote file: 20.3 kB
requirements.txt ADDED
@@ -0,0 +1,4 @@
 
 
 
 
 
1
+ requests==2.32.3
2
+ requests_toolbelt==1.0.0
3
+ numpy==1.26.4
4
+ opencv-python-headless==4.10.0.84
try_on_diffusion_client.py ADDED
@@ -0,0 +1,119 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import cv2
2
+ import numpy as np
3
+ import requests
4
+ from requests_toolbelt.multipart.encoder import MultipartEncoder
5
+ import logging
6
+ import json
7
+ from io import BytesIO
8
+ from dataclasses import dataclass
9
+
10
+
11
+ @dataclass
12
+ class TryOnDiffusionAPIResponse:
13
+ status_code: int
14
+ image: np.ndarray = None
15
+ response_data: bytes = None
16
+ error_details: str = None
17
+ seed: int = None
18
+
19
+
20
+ class TryOnDiffusionClient:
21
+ def __init__(self, base_url: str = "http://localhost:8000/", api_key: str = ""):
22
+ self._logger = logging.getLogger("try_on_diffusion_client")
23
+ self._base_url = base_url
24
+ self._api_key = api_key
25
+
26
+ if self._base_url[-1] == "/":
27
+ self._base_url = self._base_url[:-1]
28
+
29
+ @staticmethod
30
+ def _image_to_upload_file(image: np.ndarray) -> tuple:
31
+ _, jpeg_data = cv2.imencode(".jpg", image, [int(cv2.IMWRITE_JPEG_QUALITY), 99])
32
+ jpeg_data = jpeg_data.tobytes()
33
+
34
+ fp = BytesIO(jpeg_data)
35
+
36
+ return "image.jpg", fp, "image/jpeg"
37
+
38
+ def try_on_file(
39
+ self,
40
+ clothing_image: np.ndarray = None,
41
+ clothing_prompt: str = None,
42
+ avatar_image: np.ndarray = None,
43
+ avatar_prompt: str = None,
44
+ avatar_sex: str = None,
45
+ background_image: np.ndarray = None,
46
+ background_prompt: str = None,
47
+ negative_prompt: str = None,
48
+ num_images: int = 1,
49
+ seed: int = -1,
50
+ raw_response: bool = False,
51
+ ) -> TryOnDiffusionAPIResponse:
52
+ url = self._base_url + "/try-on-file"
53
+
54
+ request_data = {"num_images": str(num_images), "seed": str(seed)}
55
+
56
+ if clothing_image is not None:
57
+ request_data["clothing_image"] = self._image_to_upload_file(clothing_image)
58
+
59
+ if clothing_prompt is not None:
60
+ request_data["clothing_prompt"] = clothing_prompt
61
+
62
+ if avatar_image is not None:
63
+ request_data["avatar_image"] = self._image_to_upload_file(avatar_image)
64
+
65
+ if avatar_prompt is not None:
66
+ request_data["avatar_prompt"] = avatar_prompt
67
+
68
+ if avatar_sex is not None:
69
+ request_data["avatar_sex"] = avatar_sex
70
+
71
+ if background_image is not None:
72
+ request_data["background_image"] = self._image_to_upload_file(background_image)
73
+
74
+ if background_prompt is not None:
75
+ request_data["background_prompt"] = background_prompt
76
+
77
+ if negative_prompt is not None:
78
+ request_data["negative_prompt"] = negative_prompt
79
+
80
+ multipart_data = MultipartEncoder(fields=request_data)
81
+
82
+ try:
83
+ response = requests.post(
84
+ url,
85
+ data=multipart_data,
86
+ headers={"Content-Type": multipart_data.content_type, "X-API-Key": self._api_key},
87
+ )
88
+ except Exception as e:
89
+ self._logger.error(e, exc_info=True)
90
+ return TryOnDiffusionAPIResponse(status_code=0)
91
+
92
+ if response.status_code != 200:
93
+ self._logger.warning(f"Request failed, status code: {response.status_code}, response: {response.content}")
94
+
95
+ result = TryOnDiffusionAPIResponse(status_code=response.status_code)
96
+
97
+ if not raw_response and response.status_code == 200:
98
+ try:
99
+ result.image = cv2.imdecode(np.frombuffer(response.content, np.uint8), cv2.IMREAD_COLOR)
100
+ except:
101
+ result.image = None
102
+ else:
103
+ result.response_data = response.content
104
+
105
+ if result.status_code == 200:
106
+ if "X-Seed" in response.headers:
107
+ result.seed = int(response.headers["X-Seed"])
108
+ else:
109
+ try:
110
+ response_json = (
111
+ json.loads(result.response_data.decode("utf-8")) if result.response_data is not None else None
112
+ )
113
+
114
+ if response_json is not None and "detail" in response_json:
115
+ result.error_details = response_json["detail"]
116
+ except:
117
+ result.error_details = None
118
+
119
+ return result