Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
@@ -12,6 +12,7 @@ import spaces
|
|
12 |
import numpy as np
|
13 |
import cv2
|
14 |
from pyzxing import BarCodeReader
|
|
|
15 |
|
16 |
from diffusers import (
|
17 |
StableDiffusionPipeline,
|
@@ -33,14 +34,14 @@ qrcode_generator = qrcode.QRCode(
|
|
33 |
)
|
34 |
|
35 |
controlnet = ControlNetModel.from_pretrained(
|
36 |
-
|
37 |
-
"DionTimmer/controlnet_qrcode-control_v1p_sd15",
|
38 |
torch_dtype=torch.float16
|
39 |
).to("cuda")
|
40 |
|
41 |
pipe = StableDiffusionControlNetImg2ImgPipeline.from_pretrained(
|
42 |
-
"digiplay/GhostMixV1.2VAE",
|
43 |
-
|
44 |
controlnet = controlnet,
|
45 |
torch_dtype = torch.float16,
|
46 |
safety_checker = None,
|
@@ -80,34 +81,59 @@ def scan_qr_code(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 |
-
|
89 |
-
except Exception:
|
90 |
-
|
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 |
-
|
98 |
-
except Exception:
|
99 |
-
|
100 |
|
101 |
-
# Method 3:
|
102 |
try:
|
103 |
reader = BarCodeReader()
|
104 |
results = reader.decode(np_image)
|
105 |
if results:
|
106 |
-
|
107 |
-
|
108 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
109 |
|
110 |
-
return None
|
111 |
|
112 |
@spaces.GPU()
|
113 |
def inference(
|
@@ -175,7 +201,7 @@ def inference(
|
|
175 |
|
176 |
|
177 |
|
178 |
-
with gr.Blocks(theme=
|
179 |
gr.Markdown(
|
180 |
"""
|
181 |

|
@@ -252,7 +278,7 @@ with gr.Blocks(theme='Hev832/Applio') as blocks:
|
|
252 |
minimum=0.0,
|
253 |
maximum=5.0,
|
254 |
step=0.01,
|
255 |
-
value=1.
|
256 |
label="QR Code Visibility",
|
257 |
)
|
258 |
gr.Markdown(
|
@@ -261,9 +287,9 @@ with gr.Blocks(theme='Hev832/Applio') as blocks:
|
|
261 |
|
262 |
- **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.
|
263 |
|
264 |
-
- **Medium settings (0.6-
|
265 |
|
266 |
-
- **High settings (
|
267 |
|
268 |
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.
|
269 |
"""
|
@@ -292,7 +318,7 @@ with gr.Blocks(theme='Hev832/Applio') as blocks:
|
|
292 |
minimum=0.0,
|
293 |
maximum=50.0,
|
294 |
step=0.25,
|
295 |
-
value=
|
296 |
label="Follow the Prompt",
|
297 |
)
|
298 |
gr.Markdown(
|
@@ -372,11 +398,14 @@ with gr.Blocks(theme='Hev832/Applio') as blocks:
|
|
372 |
if image is None:
|
373 |
return "No image to scan"
|
374 |
|
375 |
-
|
376 |
-
|
377 |
-
|
378 |
-
|
379 |
-
|
|
|
|
|
|
|
380 |
|
381 |
scan_button.click(
|
382 |
scan_and_display,
|
@@ -404,5 +433,65 @@ with gr.Blocks(theme='Hev832/Applio') as blocks:
|
|
404 |
concurrency_limit=20
|
405 |
)
|
406 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
407 |
blocks.queue(max_size=20,api_open=False)
|
408 |
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 |
+
import tempfile
|
16 |
|
17 |
from diffusers import (
|
18 |
StableDiffusionPipeline,
|
|
|
34 |
)
|
35 |
|
36 |
controlnet = ControlNetModel.from_pretrained(
|
37 |
+
"monster-labs/control_v1p_sd15_qrcode_monster",
|
38 |
+
#"DionTimmer/controlnet_qrcode-control_v1p_sd15",
|
39 |
torch_dtype=torch.float16
|
40 |
).to("cuda")
|
41 |
|
42 |
pipe = StableDiffusionControlNetImg2ImgPipeline.from_pretrained(
|
43 |
+
#"digiplay/GhostMixV1.2VAE",
|
44 |
+
"benjamin-paine/stable-diffusion-v1-5",
|
45 |
controlnet = controlnet,
|
46 |
torch_dtype = torch.float16,
|
47 |
safety_checker = None,
|
|
|
81 |
# Convert to numpy array
|
82 |
np_image = np.array(gray_image)
|
83 |
|
84 |
+
# Preprocess the image
|
85 |
+
_, binary_image = cv2.threshold(np_image, 128, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)
|
86 |
+
|
87 |
+
# List to store successful scans
|
88 |
+
successful_scans = []
|
89 |
+
|
90 |
# Method 1: Using qrcode library
|
91 |
try:
|
92 |
qr = qrcode.QRCode()
|
93 |
qr.add_data('')
|
94 |
qr.decode(gray_image)
|
95 |
+
successful_scans.append(qr.data.decode('utf-8'))
|
96 |
+
except Exception as e:
|
97 |
+
print(f"qrcode library failed: {str(e)}")
|
98 |
|
99 |
# Method 2: Using OpenCV
|
100 |
try:
|
101 |
qr_detector = cv2.QRCodeDetector()
|
102 |
retval, decoded_info, points, straight_qrcode = qr_detector.detectAndDecodeMulti(np_image)
|
103 |
if retval:
|
104 |
+
successful_scans.extend(decoded_info)
|
105 |
+
except Exception as e:
|
106 |
+
print(f"OpenCV failed: {str(e)}")
|
107 |
|
108 |
+
# Method 3: Using zxing-cpp
|
109 |
try:
|
110 |
reader = BarCodeReader()
|
111 |
results = reader.decode(np_image)
|
112 |
if results:
|
113 |
+
successful_scans.extend([result.parsed for result in results])
|
114 |
+
|
115 |
+
# If no results, try with the binary image
|
116 |
+
if not results:
|
117 |
+
results = reader.decode(binary_image)
|
118 |
+
if results:
|
119 |
+
successful_scans.extend([result.parsed for result in results])
|
120 |
+
except Exception as e:
|
121 |
+
print(f"zxing-cpp failed: {str(e)}")
|
122 |
+
|
123 |
+
# If still no successful scans, try saving the image and scanning from file
|
124 |
+
if not successful_scans:
|
125 |
+
try:
|
126 |
+
with tempfile.NamedTemporaryFile(delete=False, suffix='.png') as temp_file:
|
127 |
+
image.save(temp_file.name)
|
128 |
+
reader = BarCodeReader()
|
129 |
+
results = reader.decode(temp_file.name)
|
130 |
+
if results:
|
131 |
+
successful_scans.extend([result.parsed for result in results])
|
132 |
+
os.unlink(temp_file.name)
|
133 |
+
except Exception as e:
|
134 |
+
print(f"Temporary file scanning failed: {str(e)}")
|
135 |
|
136 |
+
return successful_scans[0] if successful_scans else None
|
137 |
|
138 |
@spaces.GPU()
|
139 |
def inference(
|
|
|
201 |
|
202 |
|
203 |
|
204 |
+
with gr.Blocks(theme=gr.themes.Monochrome()) as blocks:
|
205 |
gr.Markdown(
|
206 |
"""
|
207 |

|
|
|
278 |
minimum=0.0,
|
279 |
maximum=5.0,
|
280 |
step=0.01,
|
281 |
+
value=1.5,
|
282 |
label="QR Code Visibility",
|
283 |
)
|
284 |
gr.Markdown(
|
|
|
287 |
|
288 |
- **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.
|
289 |
|
290 |
+
- **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.
|
291 |
|
292 |
+
- **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.
|
293 |
|
294 |
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.
|
295 |
"""
|
|
|
318 |
minimum=0.0,
|
319 |
maximum=50.0,
|
320 |
step=0.25,
|
321 |
+
value=10,
|
322 |
label="Follow the Prompt",
|
323 |
)
|
324 |
gr.Markdown(
|
|
|
398 |
if image is None:
|
399 |
return "No image to scan"
|
400 |
|
401 |
+
try:
|
402 |
+
scanned_text = scan_qr_code(image)
|
403 |
+
if scanned_text:
|
404 |
+
return f"Scanned successfully: {scanned_text}"
|
405 |
+
else:
|
406 |
+
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."
|
407 |
+
except Exception as e:
|
408 |
+
return f"An error occurred while scanning: {str(e)}"
|
409 |
|
410 |
scan_button.click(
|
411 |
scan_and_display,
|
|
|
433 |
concurrency_limit=20
|
434 |
)
|
435 |
|
436 |
+
gr.Examples(
|
437 |
+
examples=[
|
438 |
+
[
|
439 |
+
"https://huggingface.co/",
|
440 |
+
"A sky view of a colorful lakes and rivers flowing through the desert",
|
441 |
+
"ugly, disfigured, low quality, blurry, nsfw",
|
442 |
+
7.5,
|
443 |
+
1.3,
|
444 |
+
0.9,
|
445 |
+
5392011833,
|
446 |
+
None,
|
447 |
+
None,
|
448 |
+
True,
|
449 |
+
"DPM++ Karras SDE",
|
450 |
+
],
|
451 |
+
[
|
452 |
+
"https://huggingface.co/",
|
453 |
+
"Bright sunshine coming through the cracks of a wet, cave wall of big rocks",
|
454 |
+
"ugly, disfigured, low quality, blurry, nsfw",
|
455 |
+
7.5,
|
456 |
+
1.11,
|
457 |
+
0.9,
|
458 |
+
2523992465,
|
459 |
+
None,
|
460 |
+
None,
|
461 |
+
True,
|
462 |
+
"DPM++ Karras SDE",
|
463 |
+
],
|
464 |
+
[
|
465 |
+
"https://huggingface.co/",
|
466 |
+
"Sky view of highly aesthetic, ancient greek thermal baths in beautiful nature",
|
467 |
+
"ugly, disfigured, low quality, blurry, nsfw",
|
468 |
+
7.5,
|
469 |
+
1.5,
|
470 |
+
0.9,
|
471 |
+
2523992465,
|
472 |
+
None,
|
473 |
+
None,
|
474 |
+
True,
|
475 |
+
"DPM++ Karras SDE",
|
476 |
+
],
|
477 |
+
],
|
478 |
+
fn=inference,
|
479 |
+
inputs=[
|
480 |
+
qr_code_content,
|
481 |
+
prompt,
|
482 |
+
negative_prompt,
|
483 |
+
guidance_scale,
|
484 |
+
controlnet_conditioning_scale,
|
485 |
+
strength,
|
486 |
+
seed,
|
487 |
+
init_image,
|
488 |
+
qr_code_image,
|
489 |
+
use_qr_code_as_init_image,
|
490 |
+
sampler,
|
491 |
+
],
|
492 |
+
outputs=[result_image],
|
493 |
+
cache_examples=False,
|
494 |
+
)
|
495 |
+
|
496 |
blocks.queue(max_size=20,api_open=False)
|
497 |
blocks.launch(share=bool(os.environ.get("SHARE", False)), show_api=True)
|