estusgroup commited on
Commit
9a45519
·
0 Parent(s):

Duplicate from estusgroup/ai-qr-generator-earlybeta

Browse files
Files changed (5) hide show
  1. .gitattributes +37 -0
  2. .gitignore +3 -0
  3. README.md +15 -0
  4. app.py +289 -0
  5. requirements.txt +8 -0
.gitattributes ADDED
@@ -0,0 +1,37 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ *.7z filter=lfs diff=lfs merge=lfs -text
2
+ *.arrow filter=lfs diff=lfs merge=lfs -text
3
+ *.bin filter=lfs diff=lfs merge=lfs -text
4
+ *.bz2 filter=lfs diff=lfs merge=lfs -text
5
+ *.ckpt filter=lfs diff=lfs merge=lfs -text
6
+ *.ftz filter=lfs diff=lfs merge=lfs -text
7
+ *.gz filter=lfs diff=lfs merge=lfs -text
8
+ *.h5 filter=lfs diff=lfs merge=lfs -text
9
+ *.joblib filter=lfs diff=lfs merge=lfs -text
10
+ *.lfs.* filter=lfs diff=lfs merge=lfs -text
11
+ *.mlmodel filter=lfs diff=lfs merge=lfs -text
12
+ *.model filter=lfs diff=lfs merge=lfs -text
13
+ *.msgpack filter=lfs diff=lfs merge=lfs -text
14
+ *.npy filter=lfs diff=lfs merge=lfs -text
15
+ *.npz filter=lfs diff=lfs merge=lfs -text
16
+ *.onnx filter=lfs diff=lfs merge=lfs -text
17
+ *.ot filter=lfs diff=lfs merge=lfs -text
18
+ *.parquet filter=lfs diff=lfs merge=lfs -text
19
+ *.pb filter=lfs diff=lfs merge=lfs -text
20
+ *.pickle filter=lfs diff=lfs merge=lfs -text
21
+ *.pkl filter=lfs diff=lfs merge=lfs -text
22
+ *.pt filter=lfs diff=lfs merge=lfs -text
23
+ *.pth filter=lfs diff=lfs merge=lfs -text
24
+ *.rar filter=lfs diff=lfs merge=lfs -text
25
+ *.safetensors filter=lfs diff=lfs merge=lfs -text
26
+ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
27
+ *.tar.* filter=lfs diff=lfs merge=lfs -text
28
+ *.tflite filter=lfs diff=lfs merge=lfs -text
29
+ *.tgz filter=lfs diff=lfs merge=lfs -text
30
+ *.wasm filter=lfs diff=lfs merge=lfs -text
31
+ *.xz filter=lfs diff=lfs merge=lfs -text
32
+ *.zip filter=lfs diff=lfs merge=lfs -text
33
+ *.zst filter=lfs diff=lfs merge=lfs -text
34
+ *tfevents* filter=lfs diff=lfs merge=lfs -text
35
+ *.png 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
.gitignore ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ __pycache__
2
+ venv
3
+ gradio_cached_examples/
README.md ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ title: AI QR Generator BETA V2
3
+ emoji: null
4
+ colorFrom: pink
5
+ colorTo: pink
6
+ sdk: gradio
7
+ sdk_version: 3.35.2
8
+ app_file: app.py
9
+ pinned: false
10
+ suggested_hardware: t4-medium
11
+ startup_duration_timeout: 1h
12
+ duplicated_from: estusgroup/ai-qr-generator-earlybeta
13
+ ---
14
+
15
+ Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
app.py ADDED
@@ -0,0 +1,289 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #derivative and edit from QR-code-AI-art-generator by patrickvonplaten - customized AND COPYRIGHTED UNDER COMMERCIAL LICENSE
2
+ #ControlNet model is controlnet_qrcode-control_v1p_sd15
3
+ #to do - remove stable diff 2 API and use a different model for generation for init image
4
+ #add init image !!!
5
+ #Change controlnetmodel
6
+ #--------------changelog-----------------
7
+ #Changed all sizes to 512 to line with sd 1.5
8
+ #removed examples
9
+ #changed description text for model
10
+ #changed sliders to set easier limits
11
+ #forced QR as INIT image temp
12
+ #removed some options and sliders by commenting out, may reenable
13
+
14
+
15
+ import torch
16
+ import gradio as gr
17
+ from PIL import Image
18
+ import qrcode
19
+ from pathlib import Path
20
+ from multiprocessing import cpu_count
21
+ import requests
22
+ import io
23
+ import os
24
+ from PIL import Image
25
+
26
+ from diffusers import (
27
+ StableDiffusionPipeline,
28
+ StableDiffusionControlNetImg2ImgPipeline,
29
+ ControlNetModel,
30
+ DDIMScheduler,
31
+ DPMSolverMultistepScheduler,
32
+ DEISMultistepScheduler,
33
+ HeunDiscreteScheduler,
34
+ EulerDiscreteScheduler,
35
+ )
36
+
37
+ API_URL = "https://api-inference.huggingface.co/models/stabilityai/stable-diffusion-2-1"
38
+ HF_TOKEN = os.environ.get("HF_TOKEN")
39
+
40
+ headers = {"Authorization": f"Bearer {HF_TOKEN}"}
41
+
42
+ def query(payload):
43
+ response = requests.post(API_URL, headers=headers, json=payload)
44
+ return response.content
45
+
46
+ qrcode_generator = qrcode.QRCode(
47
+ version=1,
48
+ error_correction=qrcode.ERROR_CORRECT_H,
49
+ box_size=10,
50
+ border=4,
51
+ )
52
+
53
+ controlnet = ControlNetModel.from_pretrained(
54
+ "DionTimmer/controlnet_qrcode-control_v1p_sd15", torch_dtype=torch.float16
55
+ )
56
+
57
+ pipe = StableDiffusionControlNetImg2ImgPipeline.from_pretrained(
58
+ "runwayml/stable-diffusion-v1-5",
59
+ controlnet=controlnet,
60
+ safety_checker=None,
61
+ torch_dtype=torch.float16,
62
+ ).to("cuda")
63
+ pipe.enable_xformers_memory_efficient_attention()
64
+
65
+
66
+
67
+ def resize_for_condition_image(input_image: Image.Image, resolution: int = 512):
68
+ input_image = input_image.convert("RGB")
69
+ W, H = input_image.size
70
+ k = float(resolution) / min(H, W)
71
+ H *= k
72
+ W *= k
73
+ H = int(round(H / 32.0)) * 32
74
+ W = int(round(W / 32.0)) * 32
75
+ img = input_image.resize((W, H), resample=Image.LANCZOS)
76
+ return img
77
+
78
+
79
+ SAMPLER_MAP = {
80
+ "DPM++ Karras SDE": lambda config: DPMSolverMultistepScheduler.from_config(config, use_karras=True, algorithm_type="sde-dpmsolver++"),
81
+ "DPM++ Karras": lambda config: DPMSolverMultistepScheduler.from_config(config, use_karras=True),
82
+ "Heun": lambda config: HeunDiscreteScheduler.from_config(config),
83
+ "Euler": lambda config: EulerDiscreteScheduler.from_config(config),
84
+ "DDIM": lambda config: DDIMScheduler.from_config(config),
85
+ "DEIS": lambda config: DEISMultistepScheduler.from_config(config),
86
+ }
87
+
88
+
89
+ def inference(
90
+ qr_code_content: str,
91
+ prompt: str,
92
+ negative_prompt: str,
93
+ guidance_scale: float = 10.0,
94
+ controlnet_conditioning_scale: float = 2.0,
95
+ strength: float = 0.8,
96
+ seed: int = -1,
97
+ init_image: Image.Image | None = None,
98
+ qrcode_image: Image.Image | None = None,
99
+ use_qr_code_as_init_image = True,
100
+ sampler = "DDIM",
101
+ ):
102
+ if prompt is None or prompt == "":
103
+ raise gr.Error("Prompt is required")
104
+
105
+ if qrcode_image is None and qr_code_content == "":
106
+ raise gr.Error("QR Code Image or QR Code Content is required")
107
+
108
+ pipe.scheduler = SAMPLER_MAP[sampler](pipe.scheduler.config)
109
+
110
+ generator = torch.manual_seed(seed) if seed != -1 else torch.Generator()
111
+
112
+ if qr_code_content != "" or qrcode_image.size == (1, 1):
113
+ print("Generating QR Code from content")
114
+ qr = qrcode.QRCode(
115
+ version=1,
116
+ error_correction=qrcode.constants.ERROR_CORRECT_H,
117
+ box_size=10,
118
+ border=4,
119
+ )
120
+ qr.add_data(qr_code_content)
121
+ qr.make(fit=True)
122
+
123
+ qrcode_image = qr.make_image(fill_color="black", back_color="white")
124
+ qrcode_image = resize_for_condition_image(qrcode_image, 512)
125
+ else:
126
+ print("Using QR Code Image")
127
+ qrcode_image = resize_for_condition_image(qrcode_image, 512)
128
+
129
+ # hack due to gradio examples
130
+ if use_qr_code_as_init_image:
131
+ init_image = qrcode_image
132
+ elif init_image is None or init_image.size == (1, 1):
133
+ print("Generating random image from prompt using Stable Diffusion 2.1 via Inference API")
134
+ # generate image from prompt
135
+ image_bytes = query({"inputs": prompt})
136
+ init_image = Image.open(io.BytesIO(image_bytes))
137
+ else:
138
+ print("Using provided init image")
139
+ init_image = resize_for_condition_image(init_image, 512)
140
+
141
+ #promptstart = ""
142
+ promptend = ", high quality, high resolution"
143
+ prompt += promptend
144
+
145
+ negative_promptend = ", butt, nipple, nsfw, nude, nudity, naked"
146
+ negative_prompt += negative_promptend
147
+
148
+ out = pipe(
149
+ prompt=prompt,
150
+ negative_prompt=negative_prompt,
151
+ image=qrcode_image,
152
+ control_image=qrcode_image, # type: ignore
153
+ width=512, # type: ignore
154
+ height=512, # type: ignore
155
+ guidance_scale=float(guidance_scale),
156
+ controlnet_conditioning_scale=float(controlnet_conditioning_scale), # type: ignore
157
+ generator=generator,
158
+ strength=float(strength),
159
+ num_inference_steps=30,
160
+ )
161
+ return out.images[0] # type: ignore
162
+
163
+ #removed text
164
+ with gr.Blocks() as blocks:
165
+ gr.Markdown(
166
+ """
167
+ ====================================================EARLY BETA - PUBLIC ACCESS V1.02===========================================================================
168
+ ***DISCLAIMER - By using this model you agree to waive any liability and are assuming all responsibility for generated images.***
169
+ ***IMAGES GENERATED BY THIS PUBLIC VERISON ARE NOT INTENDED FOR COMMERCIAL USE***
170
+
171
+ First, type in what you want the QR code to look like. Use major subjects seperated by commas like the example below.
172
+ Ex. Mountian, snow, morning, trees
173
+
174
+ Then, type your QR code information such as a website link or enter your own QR code.
175
+
176
+ Hit generate!
177
+
178
+
179
+ ===========================================================CUSTOM SETTINGS====================================================================================
180
+ The default settings should work for testing. We are currently working on improving the model and offering more customization!
181
+
182
+ QR High Pass - QR Passover -Change this to affect how much the QR code is overlayed to your image in a second pass.
183
+ **Higher setting is more QR code, lower setting is less QR code.**
184
+
185
+ QR Initial Weight - this is the initial image - Change this to affect how much your image starts looking like a QR code!
186
+ **Higher settings mean your image starts with less QR, lower means the QR will appear sharper**
187
+
188
+ Prompt Weight - This determines how much the AI "Listens" to your prompt and try to put what you described into your image.
189
+ **Lower means it is more absract and higher follows your direction more.**
190
+
191
+ Seed - This is a randomizer! Use the same seed to generate the same image over and over. Change the seed to change up your image!
192
+
193
+ """
194
+ )
195
+ prompt = gr.Textbox(
196
+ label="Prompt",
197
+ info="Prompt that describes your image - Ex. Mountian, snow, morning, trees",
198
+ )
199
+
200
+ negative_prompt = gr.Textbox(visible=True, label="Negative Prompt",
201
+ info="Input things you don't want to see in your image for the model.",
202
+ value="poorly drawn, blurry image, deformed, low resolution, disfigured, low quality, blurry")
203
+
204
+ with gr.Row():
205
+ with gr.Column():
206
+ qr_code_content = gr.Textbox(
207
+ label="QR Code Content",
208
+ info="QR Code Content or URL",
209
+ value="",
210
+ )
211
+ with gr.Accordion(label="QR Code Image (Optional)", open=False):
212
+ qr_code_image = gr.Image(
213
+ label="QR Code Image (Optional). Leave blank to automatically generate QR code",
214
+ type="pil",
215
+ )
216
+
217
+ #negative_prompt = gr.Textbox(
218
+ # label="Negative Prompt",
219
+ # value="disfigured, low quality, blurry, nsfw",
220
+ #)
221
+
222
+ use_qr_code_as_init_image = gr.Checkbox(visible= False, label="QR Code is used as initial image.", value=True, interactive=False, info="Whether init image should be QR code. Unclick to pass init image or generate init image with Stable Diffusion 2.1")
223
+
224
+ with gr.Accordion(label="Init Images (Optional)", open=False, visible=False) as init_image_acc:
225
+ init_image = gr.Image(visible=False, label="Init Image (Optional). Leave blank to generate image with SD 2.1", type="pil")
226
+
227
+ #def change_view(qr_code_as_image: bool):
228
+ # if not qr_code_as_image:
229
+ # return {init_image_acc: gr.update(visible=True)}
230
+ # else:
231
+ # return {init_image_acc: gr.update(visible=False)}
232
+
233
+ #use_qr_code_as_init_image.change(change_view, inputs=[use_qr_code_as_init_image], outputs=[init_image_acc])
234
+
235
+ with gr.Accordion(
236
+ label="You can modify the generation slightly using the below sliders. See details above. \n ",
237
+ open=True,
238
+ ):
239
+ controlnet_conditioning_scale = gr.Slider(
240
+ minimum=0.6,
241
+ maximum=2.0,
242
+ step=0.01,
243
+ value=0.65,
244
+ label="QR High Pass",
245
+ )
246
+ strength = gr.Slider(
247
+ minimum=0.8, maximum=.95, step=0.01, value=0.9, label="QR Initial Weight"
248
+ )
249
+ guidance_scale = gr.Slider(
250
+ minimum=5.0,
251
+ maximum=15.0,
252
+ step=0.25,
253
+ value=7.5,
254
+ label="Prompt Weight",
255
+ )
256
+ sampler = gr.Textbox(visible=False, value="DDIM") #gr.Dropdown(choices=list(SAMPLER_MAP.keys()), value="DPM++ Karras SDE")
257
+ seed = gr.Slider(
258
+ minimum=-1,
259
+ maximum=9999999999,
260
+ step=1,
261
+ value=2313123,
262
+ label="Seed (-1 is Randomized)",
263
+ randomize=True,
264
+ )
265
+ with gr.Row():
266
+ run_btn = gr.Button("Run")
267
+ with gr.Column():
268
+ result_image = gr.Image(label="Result Image")
269
+ run_btn.click(
270
+ inference,
271
+ inputs=[
272
+ qr_code_content,
273
+ prompt,
274
+ negative_prompt,
275
+ guidance_scale,
276
+ controlnet_conditioning_scale,
277
+ strength,
278
+ seed,
279
+ init_image,
280
+ qr_code_image,
281
+ use_qr_code_as_init_image,
282
+ sampler,
283
+ ],
284
+ outputs=[result_image],
285
+ )
286
+
287
+
288
+ blocks.queue(concurrency_count=1, max_size=20)
289
+ blocks.launch(share=False)
requirements.txt ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
 
1
+ diffusers
2
+ transformers
3
+ accelerate
4
+ torch
5
+ xformers
6
+ gradio
7
+ Pillow
8
+ qrcode