File size: 5,599 Bytes
452e643
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
import gradio as gr
import cv2
import numpy as np
from PIL import Image, ImageDraw, ImageFont, ImageFilter, ImageEnhance
from skimage.metrics import structural_similarity as ssim
import tempfile

# ASCII characters to map pixel intensity
ASCII_CHARS = [
    ' ', '.', ',', ':', ';', 'i', 'l', '!', 'I', '1', 't', 'o', 'r', 'x', 'z', 'v', 
    'u', 'n', 'm', 'w', 'Q', 'B', 'N', 'M', '@'
]

# Step 1: Resize image and perform general Sobel edge detection

def preprocess_image(image_path, new_width=150):
    # Open the image and convert to grayscale
    image = Image.open(image_path)
    print(type(image))
    # Step 1: Resize the image for ASCII aspect ratio
    width, height = image.size
    aspect_ratio = height / width * 0.55  # Adjusting for ASCII aspect ratio
    new_height = int(aspect_ratio * new_width)
    
    # # Step 3: Show the equalized image
    # equalized_image.show(title="Equalized Image")
    opencv_image = np.array(image)
    clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8, 8))
    equalized_image = clahe.apply(opencv_image)

    # Convert to OpenCV format for Sobel edge detection
    opencv_image = np.array(equalized_image)

    # Step 4: Sobel edge detection
    sobelx = cv2.Sobel(opencv_image, cv2.CV_64F, 1, 0, ksize=5)  # Horizontal gradients
    sobely = cv2.Sobel(opencv_image, cv2.CV_64F, 0, 1, ksize=5)  # Vertical gradients
    edges = np.hypot(sobelx, sobely)  # Combine gradients

    # Normalize the result to fit into the 0-255 grayscale range
    edges = np.uint8(255 * edges / np.max(edges))

    # Step 5: Sharpen the edges
    edges_image = Image.fromarray(edges)
    edges_image.show(title="Sharpened Edges")
    enhancer = ImageEnhance.Contrast(edges_image)
    enhanced_edges = enhancer.enhance(3.0)  # Increase contrast by a factor (2.0 is an example)

    sharpened_edges = enhanced_edges.filter(ImageFilter.SHARPEN)

    # sharpened_edges = edges_image.filter(ImageFilter.SHARPEN)

    # Step 6: Show the sharpened edges image
    sharpened_edges.show(title="Sharpened Edges")

    sharpened_edges = sharpened_edges.resize((new_width, new_height))
    sharpened_edges.show(title="Sharpened Edges")
    return sharpened_edges, sharpened_edges

# Step 2: Convert image to ASCII art
def image_to_ascii(image):
    pixels = np.array(image)
    ascii_str = ""
    for row in pixels:
        for pixel in row:
            ascii_str += ASCII_CHARS[pixel // 10]  # Mapping pixel intensity to ASCII (256 levels / 25 characters)
        ascii_str += "\n"
    return ascii_str

# Step 3: Convert ASCII text back to image
def ascii_to_image(ascii_art, font_size=12, output_file='ascii_art.png'):
    font_path = "DejaVuSansMono.ttf"  # Update with correct path if needed
    font = ImageFont.truetype(font_path, font_size)
    
    lines = ascii_art.splitlines()
    max_width = max(font.getbbox(line)[2] for line in lines)  # Get max width
    img_height = len(lines) * font_size

    image = Image.new("RGB", (max_width, img_height), "white")
    draw = ImageDraw.Draw(image)

    for y, line in enumerate(lines):
        draw.text((0, y * font_size), line, fill="black", font=font)

    image.save(output_file)
    return image

# Step 4: Calculate Structural Similarity Index (SSIM)
def compare_ssim(image_path_1, image_path_2):
    image1 = cv2.imread(image_path_1, cv2.IMREAD_GRAYSCALE)
    image2 = cv2.imread(image_path_2, cv2.IMREAD_GRAYSCALE)

    # Resize images to the same size if needed
    image2 = cv2.resize(image2, (image1.shape[1], image1.shape[0]))

    # Compute SSIM between the two images
    score, _ = ssim(image1, image2, full=True)
    return score

# Usage Example
if __name__ == "__main__":
    # Path to input image
    input_image_path = "image8a.jpg"

    # Step 1: Preprocess and edge detection with Sobel filter
    resized_image, edges = preprocess_image(input_image_path)

    # Step 2: Convert the edge-detected image to ASCII
    ascii_art = image_to_ascii(edges)
    print("ASCII Art:\n", ascii_art)

    # Step 3: Convert ASCII back to image
    ascii_image_path = "ascii_image.jpg"
    ascii_img = ascii_to_image(ascii_art, 12, ascii_image_path)

    # Step 4: Compare SSIM
    ssim_score = compare_ssim(input_image_path, ascii_image_path)
    print(f"SSIM between original and ASCII image: {ssim_score}")

# def process_image(image):
#     # Step 1: Preprocess and convert to ASCII
#     edges, _ = preprocess_image(image)
#     ascii_art = image_to_ascii(edges)
    
#     # Step 2: Convert ASCII art back to an image for SSIM calculation
#     ascii_image = ascii_to_image(ascii_art)
    
#     # Step 3: Calculate SSIM
#     ssim_score = compare_ssim(image, ascii_image)
    
#     # Step 4: Return ASCII art and SSIM score
#     with tempfile.NamedTemporaryFile(delete=False, suffix=".txt") as f:
#         f.write(ascii_art.encode())
#         ascii_txt_path = f.name
    
#     return ascii_art, ssim_score, ascii_txt_path

# # Gradio Interface
# def gradio_interface(image):
#     print(type(image))
#     ascii_art, ssim_score, ascii_txt_path = process_image(image)
#     return ascii_art, ssim_score, ascii_txt_path

# # Setup Gradio interface
# interface = gr.Interface(
#     fn=gradio_interface,
#     inputs="image",
#     outputs=["text", "number", "file"],
#     title="Image to ASCII Art with SSIM",
#     description="Upload an image, see the ASCII art, the SSIM score, and download the ASCII art as a text file."
# )

interface.launch()