nnibras commited on
Commit
d1eb1d4
·
verified ·
1 Parent(s): eac4855

Upload app.py

Browse files
Files changed (1) hide show
  1. app.py +122 -0
app.py ADDED
@@ -0,0 +1,122 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import cv2
2
+ import numpy as np
3
+ import gradio as gr
4
+ from skimage.metrics import structural_similarity as compare_ssim
5
+
6
+
7
+ def ascii_art_generator(input_image, contrast, threshold1, threshold2, ascii_chars):
8
+ # Resize the image
9
+ new_width = 100
10
+ height, width = input_image.shape[:2]
11
+ aspect_ratio = height / width
12
+ new_height = int(aspect_ratio * new_width * 0.55)
13
+ resized_image = cv2.resize(input_image, (new_width, int(new_height)))
14
+
15
+ # Convert to grayscale
16
+ gray_image = cv2.cvtColor(resized_image, cv2.COLOR_BGR2GRAY)
17
+
18
+ # Apply transformation algorithm with user parameters
19
+ adjusted_image = cv2.convertScaleAbs(gray_image, alpha=contrast, beta=0)
20
+ edges = cv2.Canny(
21
+ adjusted_image, threshold1=int(threshold1), threshold2=int(threshold2)
22
+ )
23
+ processed_image = cv2.bitwise_not(edges)
24
+
25
+ # Map intensities to ASCII characters
26
+ def pixel_to_ascii(pixel_value):
27
+ num_chars = len(ascii_chars)
28
+ index = int(pixel_value / 255 * (num_chars - 1))
29
+ return ascii_chars[index]
30
+
31
+ # Generate the ASCII art string
32
+ ascii_art_lines = []
33
+ for row in processed_image:
34
+ line = "".join([pixel_to_ascii(pixel) for pixel in row])
35
+ ascii_art_lines.append(line)
36
+ ascii_art = "\n".join(ascii_art_lines)
37
+
38
+ # Save the ASCII art to a text file
39
+ with open("ascii_art.txt", "w") as f:
40
+ f.write(ascii_art)
41
+
42
+ # Convert processed_image to RGB format for display
43
+ processed_image_rgb = cv2.cvtColor(processed_image, cv2.COLOR_GRAY2RGB)
44
+
45
+ # Convert ASCII art back to image
46
+ def ascii_to_image(ascii_art, ascii_chars):
47
+ # Create a mapping from characters to grayscale values
48
+ char_to_intensity = {
49
+ char: int(i / (len(ascii_chars) - 1) * 255)
50
+ for i, char in enumerate(ascii_chars)
51
+ }
52
+ ascii_lines = ascii_art.split("\n")
53
+ height = len(ascii_lines)
54
+ width = len(ascii_lines[0]) if height > 0 else 0
55
+ ascii_image = np.zeros((height, width), dtype=np.uint8)
56
+ for y, line in enumerate(ascii_lines):
57
+ for x, char in enumerate(line):
58
+ ascii_image[y, x] = char_to_intensity.get(char, 0)
59
+ return ascii_image
60
+
61
+ ascii_image = ascii_to_image(ascii_art, ascii_chars)
62
+
63
+ # Normalize the original image
64
+ def normalize_images(original_image, ascii_image_shape):
65
+ resized_original = cv2.resize(
66
+ original_image, (ascii_image_shape[1], ascii_image_shape[0])
67
+ )
68
+ if len(resized_original.shape) == 3:
69
+ resized_original = cv2.cvtColor(resized_original, cv2.COLOR_BGR2GRAY)
70
+ return resized_original
71
+
72
+ normalized_original = normalize_images(gray_image, ascii_image.shape)
73
+
74
+ # Calculate similarity metrics
75
+ def calculate_mse(image1, image2):
76
+ mse = np.mean((image1.astype("float") - image2.astype("float")) ** 2)
77
+ return mse
78
+
79
+ def calculate_ssim(image1, image2):
80
+ ssim, _ = compare_ssim(image1, image2, full=True)
81
+ return ssim
82
+
83
+ def calculate_psnr(image1, image2):
84
+ mse = calculate_mse(image1, image2)
85
+ if mse == 0:
86
+ return float("inf")
87
+ PIXEL_MAX = 255.0
88
+ psnr = 20 * np.log10(PIXEL_MAX / np.sqrt(mse))
89
+ return psnr
90
+
91
+ mse = calculate_mse(normalized_original, ascii_image)
92
+ ssim = calculate_ssim(normalized_original, ascii_image)
93
+ psnr = calculate_psnr(normalized_original, ascii_image)
94
+
95
+ # Prepare metrics output
96
+ metrics_text = f"MSE: {mse:.2f}\nSSIM: {ssim:.4f}\nPSNR: {psnr:.2f} dB"
97
+
98
+ return ascii_art, "ascii_art.txt", processed_image_rgb, metrics_text
99
+
100
+
101
+ # Define the Gradio interface using the updated components
102
+ iface = gr.Interface(
103
+ fn=ascii_art_generator,
104
+ inputs=[
105
+ gr.Image(type="numpy", label="Upload Image"),
106
+ gr.Slider(0.5, 3.0, step=0.1, value=1.5, label="Contrast"),
107
+ gr.Slider(0, 255, step=1, value=50, label="Edge Detection Threshold1"),
108
+ gr.Slider(0, 255, step=1, value=150, label="Edge Detection Threshold2"),
109
+ gr.Textbox(value="@%#*+=-:. ", label="ASCII Characters (Dark to Light)"),
110
+ ],
111
+ outputs=[
112
+ gr.Textbox(label="ASCII Art"),
113
+ gr.File(label="Download ASCII Art as Text File"),
114
+ gr.Image(type="numpy", label="Processed Image"),
115
+ gr.Textbox(label="Performance Metrics"),
116
+ ],
117
+ title="Interactive ASCII Art Generator with Performance Metric",
118
+ description="Upload an image and adjust parameters to convert it into ASCII art. The performance metric quantifies the similarity between the original image and the ASCII art.",
119
+ allow_flagging="never",
120
+ )
121
+
122
+ iface.launch(debug=True, share=True)