Spaces:
Build error
Build error
| 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() |