Severian commited on
Commit
b2c7457
·
verified ·
1 Parent(s): 2f9ae86

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +38 -136
app.py CHANGED
@@ -12,9 +12,6 @@ import spaces
12
  import numpy as np
13
  import cv2
14
  from pyzxing import BarCodeReader
15
- import tempfile
16
- from io import BytesIO
17
- import base64
18
 
19
  from diffusers import (
20
  StableDiffusionPipeline,
@@ -36,8 +33,8 @@ qrcode_generator = qrcode.QRCode(
36
  )
37
 
38
  controlnet = ControlNetModel.from_pretrained(
39
- #"monster-labs/control_v1p_sd15_qrcode_monster",
40
- "DionTimmer/controlnet_qrcode-control_v1p_sd15",
41
  torch_dtype=torch.float16
42
  ).to("cuda")
43
 
@@ -72,7 +69,7 @@ SAMPLER_MAP = {
72
  "DEIS": lambda config: DEISMultistepScheduler.from_config(config),
73
  }
74
 
75
- def scan_qr_code(image, sensitivity=0.5):
76
  # Convert gradio image to PIL Image if necessary
77
  if isinstance(image, np.ndarray):
78
  image = Image.fromarray(image)
@@ -83,85 +80,34 @@ def scan_qr_code(image, sensitivity=0.5):
83
  # Convert to numpy array
84
  np_image = np.array(gray_image)
85
 
86
- # Preprocess the image
87
- _, binary_image = cv2.threshold(np_image, int(255 * sensitivity), 255, cv2.THRESH_BINARY)
88
-
89
- # List to store successful scans
90
- successful_scans = []
91
-
92
  # Method 1: Using qrcode library
93
  try:
94
  qr = qrcode.QRCode()
95
  qr.add_data('')
96
  qr.decode(gray_image)
97
- successful_scans.append(("qrcode library", qr.data.decode('utf-8')))
98
- except Exception as e:
99
- print(f"qrcode library failed: {str(e)}")
100
 
101
  # Method 2: Using OpenCV
102
  try:
103
  qr_detector = cv2.QRCodeDetector()
104
  retval, decoded_info, points, straight_qrcode = qr_detector.detectAndDecodeMulti(np_image)
105
  if retval:
106
- successful_scans.extend([("OpenCV", info) for info in decoded_info if info])
107
- except Exception as e:
108
- print(f"OpenCV failed: {str(e)}")
109
 
110
- # Method 3: Using zxing-cpp
111
  try:
112
  reader = BarCodeReader()
113
  results = reader.decode(np_image)
114
  if results:
115
- successful_scans.extend([("zxing-cpp", result.parsed) for result in results])
116
-
117
- # If no results, try with the binary image
118
- if not results:
119
- results = reader.decode(binary_image)
120
- if results:
121
- successful_scans.extend([("zxing-cpp (binary)", result.parsed) for result in results])
122
- except Exception as e:
123
- print(f"zxing-cpp failed: {str(e)}")
124
 
125
- # If still no successful scans, try saving the image and scanning from file
126
- if not successful_scans:
127
- try:
128
- with tempfile.NamedTemporaryFile(delete=False, suffix='.png') as temp_file:
129
- image.save(temp_file.name)
130
- reader = BarCodeReader()
131
- results = reader.decode(temp_file.name)
132
- if results:
133
- successful_scans.extend([("zxing-cpp (file)", result.parsed) for result in results])
134
- os.unlink(temp_file.name)
135
- except Exception as e:
136
- print(f"Temporary file scanning failed: {str(e)}")
137
-
138
- return successful_scans
139
-
140
- def generate_qr_code(
141
- data,
142
- version=None,
143
- error_correction=qrcode.constants.ERROR_CORRECT_H,
144
- box_size=10,
145
- border=4,
146
- fill_color="black",
147
- back_color="white"
148
- ):
149
- qr = qrcode.QRCode(
150
- version=version,
151
- error_correction=error_correction,
152
- box_size=box_size,
153
- border=border,
154
- )
155
- qr.add_data(data)
156
- qr.make(fit=True)
157
-
158
- img = qr.make_image(fill_color=fill_color, back_color=back_color)
159
- return img
160
-
161
- def image_to_base64(img):
162
- buffered = BytesIO()
163
- img.save(buffered, format="PNG")
164
- return base64.b64encode(buffered.getvalue()).decode()
165
 
166
  @spaces.GPU()
167
  def inference(
@@ -176,13 +122,6 @@ def inference(
176
  qrcode_image: Image.Image | None = None,
177
  use_qr_code_as_init_image = True,
178
  sampler = "DPM++ Karras SDE",
179
- verify_sensitivity: float = 0.5,
180
- qr_version: int = 1,
181
- qr_error_correction: str = "H",
182
- qr_box_size: int = 10,
183
- qr_border: int = 4,
184
- qr_fill_color: str = "black",
185
- qr_back_color: str = "white",
186
  ):
187
  try:
188
  if prompt is None or prompt == "":
@@ -197,29 +136,21 @@ def inference(
197
 
198
  if qr_code_content != "" or qrcode_image.size == (1, 1):
199
  print("Generating QR Code from content")
200
- error_correction_map = {
201
- "L": qrcode.constants.ERROR_CORRECT_L,
202
- "M": qrcode.constants.ERROR_CORRECT_M,
203
- "Q": qrcode.constants.ERROR_CORRECT_Q,
204
- "H": qrcode.constants.ERROR_CORRECT_H,
205
- }
206
- qrcode_image = generate_qr_code(
207
- qr_code_content,
208
- version=qr_version,
209
- error_correction=error_correction_map[qr_error_correction],
210
- box_size=qr_box_size,
211
- border=qr_border,
212
- fill_color=qr_fill_color,
213
- back_color=qr_back_color,
214
  )
 
 
 
 
215
  qrcode_image = resize_for_condition_image(qrcode_image, 768)
216
  else:
217
  print("Using QR Code Image")
218
  qrcode_image = resize_for_condition_image(qrcode_image, 768)
219
 
220
- # Generate base64 string of the initial QR code
221
- initial_qr_base64 = image_to_base64(qrcode_image)
222
-
223
  # hack due to gradio examples
224
  init_image = qrcode_image
225
 
@@ -236,19 +167,15 @@ def inference(
236
  strength=float(strength),
237
  num_inference_steps=50,
238
  )
239
-
240
- # Verify the generated QR code
241
- verify_result = scan_qr_code(out.images[0], sensitivity=verify_sensitivity)
242
-
243
- return out.images[0], verify_result, initial_qr_base64
244
  except Exception as e:
245
  print(f"Error in inference: {str(e)}")
246
  # Return a blank image in case of an error
247
- return Image.new('RGB', (768, 768), color='white'), [], ""
248
 
249
 
250
 
251
- with gr.Blocks(theme=gr.themes.Monochrome()) as blocks:
252
  gr.Markdown(
253
  """
254
  ![Yamamoto Logo](https://cdn-uploads.huggingface.co/production/uploads/64740cf7485a7c8e1bd51ac9/_VyYxp5qE_nRZ_LJqBxmL.webp)
@@ -302,7 +229,7 @@ with gr.Blocks(theme=gr.themes.Monochrome()) as blocks:
302
  use_qr_code_as_init_image = gr.Checkbox(
303
  label="Use QR code as init image",
304
  value=True,
305
- interactive=True,
306
  info="Whether init image should be QR code. Unclick to pass init image or generate init image with Stable Diffusion 2.1"
307
  )
308
  with gr.Accordion(label="Init Images (Optional)", open=False, visible=True) as init_image_acc:
@@ -315,7 +242,7 @@ with gr.Blocks(theme=gr.themes.Monochrome()) as blocks:
315
  minimum=0.0,
316
  maximum=5.0,
317
  step=0.01,
318
- value=1.5,
319
  label="QR Code Visibility",
320
  )
321
  gr.Markdown(
@@ -324,9 +251,9 @@ with gr.Blocks(theme=gr.themes.Monochrome()) as blocks:
324
 
325
  - **Low settings (0.0-0.5)**: If you choose a lower value, the QR code will blend more into the art, and it might be hard to scan with a phone. This setting is great if you want the image to look amazing, but you might lose some of the scannability. Try this if you care more about art and less about the QR code being easily recognized.
326
 
327
- - **Medium settings (0.6-2)**: This is the sweet spot where the QR code remains clearly visible while still blending in with the art. You can still scan it easily with a phone, but it looks more creative. For most users, setting it around **1.1** is a great start to balance both art and function.
328
 
329
- - **High settings (2-5.0)**: If you need to make sure that the QR code is super easy to scan, even if it means the image looks less like art and more like a regular QR code, then choose a higher value. This is ideal when functionality is the main goal, and the artistic side can take a backseat.
330
 
331
  Start with **1.3** if you're unsure, and adjust up or down depending on whether you want the QR code to be more artistic or more functional.
332
  """
@@ -355,7 +282,7 @@ with gr.Blocks(theme=gr.themes.Monochrome()) as blocks:
355
  minimum=0.0,
356
  maximum=50.0,
357
  step=0.25,
358
- value=10,
359
  label="Follow the Prompt",
360
  )
361
  gr.Markdown(
@@ -410,28 +337,11 @@ with gr.Blocks(theme=gr.themes.Monochrome()) as blocks:
410
  Try **-1** if you want to explore and generate different designs. If you find something you really love, write down the seed number and use it again to recreate the same design.
411
  """
412
  )
413
-
414
- verify_sensitivity = gr.Slider(
415
- minimum=0.1,
416
- maximum=1.0,
417
- step=0.05,
418
- value=0.5,
419
- label="Verify Sensitivity",
420
- )
421
- gr.Markdown(
422
- """
423
- **Verify Sensitivity** controls how sensitive the QR code scanner is when verifying the generated image.
424
- A lower value (closer to 0.1) makes the scanner more sensitive and able to detect less clear QR codes,
425
- while a higher value (closer to 1.0) requires clearer, more distinct QR codes to be detected.
426
- """
427
- )
428
  with gr.Row():
429
  run_btn = gr.Button("🎨 Create Your QR Art", variant="primary")
430
 
431
  with gr.Column():
432
  result_image = gr.Image(label="Your Artistic QR Code")
433
- initial_qr_image = gr.Image(label="Initial QR Code", visible=False)
434
- download_initial_qr = gr.Button("Download Initial QR Code")
435
  scan_button = gr.Button("Scan QR Code")
436
  scan_result = gr.Textbox(label="Scan Result", interactive=False)
437
 
@@ -452,14 +362,11 @@ with gr.Blocks(theme=gr.themes.Monochrome()) as blocks:
452
  if image is None:
453
  return "No image to scan"
454
 
455
- try:
456
- scanned_text = scan_qr_code(image)
457
- if scanned_text:
458
- return f"Scanned successfully: {scanned_text}"
459
- else:
460
- return "Failed to scan QR code. The image might be too artistic or the QR code might not be clear enough. Try adjusting the 'QR Code Visibility' setting for better results."
461
- except Exception as e:
462
- return f"An error occurred while scanning: {str(e)}"
463
 
464
  scan_button.click(
465
  scan_and_display,
@@ -467,9 +374,7 @@ with gr.Blocks(theme=gr.themes.Monochrome()) as blocks:
467
  outputs=[scan_result]
468
  )
469
 
470
- def update_initial_qr(base64_string):
471
- return gr.Image.update(value=base64_string, visible=True)
472
-
473
  run_btn.click(
474
  inference,
475
  inputs=[
@@ -484,13 +389,10 @@ with gr.Blocks(theme=gr.themes.Monochrome()) as blocks:
484
  qr_code_image,
485
  use_qr_code_as_init_image,
486
  sampler,
487
- verify_sensitivity,
488
  ],
489
- outputs=[result_image, scan_result, initial_qr_image],
490
  concurrency_limit=20
491
  )
492
 
493
- download_initial_qr.click(lambda x: x, inputs=[initial_qr_image], outputs=[initial_qr_image])
494
-
495
  blocks.queue(max_size=20,api_open=False)
496
  blocks.launch(share=bool(os.environ.get("SHARE", False)), show_api=True)
 
12
  import numpy as np
13
  import cv2
14
  from pyzxing import BarCodeReader
 
 
 
15
 
16
  from diffusers import (
17
  StableDiffusionPipeline,
 
33
  )
34
 
35
  controlnet = ControlNetModel.from_pretrained(
36
+ "monster-labs/control_v1p_sd15_qrcode_monster",
37
+ #"DionTimmer/controlnet_qrcode-control_v1p_sd15",
38
  torch_dtype=torch.float16
39
  ).to("cuda")
40
 
 
69
  "DEIS": lambda config: DEISMultistepScheduler.from_config(config),
70
  }
71
 
72
+ def scan_qr_code(image):
73
  # Convert gradio image to PIL Image if necessary
74
  if isinstance(image, np.ndarray):
75
  image = Image.fromarray(image)
 
80
  # Convert to numpy array
81
  np_image = np.array(gray_image)
82
 
 
 
 
 
 
 
83
  # Method 1: Using qrcode library
84
  try:
85
  qr = qrcode.QRCode()
86
  qr.add_data('')
87
  qr.decode(gray_image)
88
+ return qr.data.decode('utf-8')
89
+ except Exception:
90
+ pass
91
 
92
  # Method 2: Using OpenCV
93
  try:
94
  qr_detector = cv2.QRCodeDetector()
95
  retval, decoded_info, points, straight_qrcode = qr_detector.detectAndDecodeMulti(np_image)
96
  if retval:
97
+ return decoded_info[0]
98
+ except Exception:
99
+ pass
100
 
101
+ # Method 3: Fallback to zxing-cpp
102
  try:
103
  reader = BarCodeReader()
104
  results = reader.decode(np_image)
105
  if results:
106
+ return results[0].parsed
107
+ except Exception:
108
+ pass
 
 
 
 
 
 
109
 
110
+ return None
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
111
 
112
  @spaces.GPU()
113
  def inference(
 
122
  qrcode_image: Image.Image | None = None,
123
  use_qr_code_as_init_image = True,
124
  sampler = "DPM++ Karras SDE",
 
 
 
 
 
 
 
125
  ):
126
  try:
127
  if prompt is None or prompt == "":
 
136
 
137
  if qr_code_content != "" or qrcode_image.size == (1, 1):
138
  print("Generating QR Code from content")
139
+ qr = qrcode.QRCode(
140
+ version=1,
141
+ error_correction=qrcode.constants.ERROR_CORRECT_H,
142
+ box_size=10,
143
+ border=4,
 
 
 
 
 
 
 
 
 
144
  )
145
+ qr.add_data(qr_code_content)
146
+ qr.make(fit=True)
147
+
148
+ qrcode_image = qr.make_image(fill_color="black", back_color="white")
149
  qrcode_image = resize_for_condition_image(qrcode_image, 768)
150
  else:
151
  print("Using QR Code Image")
152
  qrcode_image = resize_for_condition_image(qrcode_image, 768)
153
 
 
 
 
154
  # hack due to gradio examples
155
  init_image = qrcode_image
156
 
 
167
  strength=float(strength),
168
  num_inference_steps=50,
169
  )
170
+ return out.images[0] # type: ignore
 
 
 
 
171
  except Exception as e:
172
  print(f"Error in inference: {str(e)}")
173
  # Return a blank image in case of an error
174
+ return Image.new('RGB', (768, 768), color='white')
175
 
176
 
177
 
178
+ with gr.Blocks(theme='Hev832/Applio') as blocks:
179
  gr.Markdown(
180
  """
181
  ![Yamamoto Logo](https://cdn-uploads.huggingface.co/production/uploads/64740cf7485a7c8e1bd51ac9/_VyYxp5qE_nRZ_LJqBxmL.webp)
 
229
  use_qr_code_as_init_image = gr.Checkbox(
230
  label="Use QR code as init image",
231
  value=True,
232
+ interactive=False,
233
  info="Whether init image should be QR code. Unclick to pass init image or generate init image with Stable Diffusion 2.1"
234
  )
235
  with gr.Accordion(label="Init Images (Optional)", open=False, visible=True) as init_image_acc:
 
242
  minimum=0.0,
243
  maximum=5.0,
244
  step=0.01,
245
+ value=1.3,
246
  label="QR Code Visibility",
247
  )
248
  gr.Markdown(
 
251
 
252
  - **Low settings (0.0-0.5)**: If you choose a lower value, the QR code will blend more into the art, and it might be hard to scan with a phone. This setting is great if you want the image to look amazing, but you might lose some of the scannability. Try this if you care more about art and less about the QR code being easily recognized.
253
 
254
+ - **Medium settings (0.6-1.5)**: This is the sweet spot where the QR code remains clearly visible while still blending in with the art. You can still scan it easily with a phone, but it looks more creative. For most users, setting it around **1.1** is a great start to balance both art and function.
255
 
256
+ - **High settings (1.6-5.0)**: If you need to make sure that the QR code is super easy to scan, even if it means the image looks less like art and more like a regular QR code, then choose a higher value. This is ideal when functionality is the main goal, and the artistic side can take a backseat.
257
 
258
  Start with **1.3** if you're unsure, and adjust up or down depending on whether you want the QR code to be more artistic or more functional.
259
  """
 
282
  minimum=0.0,
283
  maximum=50.0,
284
  step=0.25,
285
+ value=7.5,
286
  label="Follow the Prompt",
287
  )
288
  gr.Markdown(
 
337
  Try **-1** if you want to explore and generate different designs. If you find something you really love, write down the seed number and use it again to recreate the same design.
338
  """
339
  )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
340
  with gr.Row():
341
  run_btn = gr.Button("🎨 Create Your QR Art", variant="primary")
342
 
343
  with gr.Column():
344
  result_image = gr.Image(label="Your Artistic QR Code")
 
 
345
  scan_button = gr.Button("Scan QR Code")
346
  scan_result = gr.Textbox(label="Scan Result", interactive=False)
347
 
 
362
  if image is None:
363
  return "No image to scan"
364
 
365
+ scanned_text = scan_qr_code(image)
366
+ if scanned_text:
367
+ return f"Scanned successfully: {scanned_text}"
368
+ else:
369
+ return "Failed to scan QR code. Try adjusting the settings for better visibility."
 
 
 
370
 
371
  scan_button.click(
372
  scan_and_display,
 
374
  outputs=[scan_result]
375
  )
376
 
377
+
 
 
378
  run_btn.click(
379
  inference,
380
  inputs=[
 
389
  qr_code_image,
390
  use_qr_code_as_init_image,
391
  sampler,
 
392
  ],
393
+ outputs=[result_image],
394
  concurrency_limit=20
395
  )
396
 
 
 
397
  blocks.queue(max_size=20,api_open=False)
398
  blocks.launch(share=bool(os.environ.get("SHARE", False)), show_api=True)