Spaces:
Build error
Build error
| import cv2 | |
| import numpy as np | |
| import gradio as gr | |
| from skimage.metrics import structural_similarity as compare_ssim | |
| def ascii_art_generator(input_image, contrast, threshold1, threshold2, ascii_chars): | |
| # Resize the image | |
| new_width = 100 | |
| height, width = input_image.shape[:2] | |
| aspect_ratio = height / width | |
| new_height = int(aspect_ratio * new_width * 0.55) | |
| resized_image = cv2.resize(input_image, (new_width, int(new_height))) | |
| # Convert to grayscale | |
| gray_image = cv2.cvtColor(resized_image, cv2.COLOR_BGR2GRAY) | |
| # Apply transformation algorithm with user parameters | |
| adjusted_image = cv2.convertScaleAbs(gray_image, alpha=contrast, beta=0) | |
| edges = cv2.Canny( | |
| adjusted_image, threshold1=int(threshold1), threshold2=int(threshold2) | |
| ) | |
| processed_image = cv2.bitwise_not(edges) | |
| # Map intensities to ASCII characters | |
| def pixel_to_ascii(pixel_value): | |
| num_chars = len(ascii_chars) | |
| index = int(pixel_value / 255 * (num_chars - 1)) | |
| return ascii_chars[index] | |
| # Generate the ASCII art string | |
| ascii_art_lines = [] | |
| for row in processed_image: | |
| line = "".join([pixel_to_ascii(pixel) for pixel in row]) | |
| ascii_art_lines.append(line) | |
| ascii_art = "\n".join(ascii_art_lines) | |
| # Save the ASCII art to a text file | |
| with open("ascii_art.txt", "w") as f: | |
| f.write(ascii_art) | |
| # Convert processed_image to RGB format for display | |
| processed_image_rgb = cv2.cvtColor(processed_image, cv2.COLOR_GRAY2RGB) | |
| # Convert ASCII art back to image | |
| def ascii_to_image(ascii_art, ascii_chars): | |
| # Create a mapping from characters to grayscale values | |
| char_to_intensity = { | |
| char: int(i / (len(ascii_chars) - 1) * 255) | |
| for i, char in enumerate(ascii_chars) | |
| } | |
| ascii_lines = ascii_art.split("\n") | |
| height = len(ascii_lines) | |
| width = len(ascii_lines[0]) if height > 0 else 0 | |
| ascii_image = np.zeros((height, width), dtype=np.uint8) | |
| for y, line in enumerate(ascii_lines): | |
| for x, char in enumerate(line): | |
| ascii_image[y, x] = char_to_intensity.get(char, 0) | |
| return ascii_image | |
| ascii_image = ascii_to_image(ascii_art, ascii_chars) | |
| # Normalize the original image | |
| def normalize_images(original_image, ascii_image_shape): | |
| resized_original = cv2.resize( | |
| original_image, (ascii_image_shape[1], ascii_image_shape[0]) | |
| ) | |
| if len(resized_original.shape) == 3: | |
| resized_original = cv2.cvtColor(resized_original, cv2.COLOR_BGR2GRAY) | |
| return resized_original | |
| normalized_original = normalize_images(gray_image, ascii_image.shape) | |
| # Calculate similarity metrics | |
| def calculate_mse(image1, image2): | |
| mse = np.mean((image1.astype("float") - image2.astype("float")) ** 2) | |
| return mse | |
| def calculate_ssim(image1, image2): | |
| ssim, _ = compare_ssim(image1, image2, full=True) | |
| return ssim | |
| def calculate_psnr(image1, image2): | |
| mse = calculate_mse(image1, image2) | |
| if mse == 0: | |
| return float("inf") | |
| PIXEL_MAX = 255.0 | |
| psnr = 20 * np.log10(PIXEL_MAX / np.sqrt(mse)) | |
| return psnr | |
| mse = calculate_mse(normalized_original, ascii_image) | |
| ssim = calculate_ssim(normalized_original, ascii_image) | |
| psnr = calculate_psnr(normalized_original, ascii_image) | |
| # Prepare metrics output | |
| metrics_text = f"MSE: {mse:.2f}\nSSIM: {ssim:.4f}\nPSNR: {psnr:.2f} dB" | |
| return ascii_art, "ascii_art.txt", processed_image_rgb, metrics_text | |
| # Define the Gradio interface using the updated components | |
| iface = gr.Interface( | |
| fn=ascii_art_generator, | |
| inputs=[ | |
| gr.Image(type="numpy", label="Upload Image"), | |
| gr.Slider(0.5, 3.0, step=0.1, value=1.5, label="Contrast"), | |
| gr.Slider(0, 255, step=1, value=50, label="Edge Detection Threshold1"), | |
| gr.Slider(0, 255, step=1, value=150, label="Edge Detection Threshold2"), | |
| gr.Textbox(value="@%#*+=-:. ", label="ASCII Characters (Dark to Light)"), | |
| ], | |
| outputs=[ | |
| gr.Textbox(label="ASCII Art"), | |
| gr.File(label="Download ASCII Art as Text File"), | |
| gr.Image(type="numpy", label="Processed Image"), | |
| gr.Textbox(label="Performance Metrics"), | |
| ], | |
| title="Interactive ASCII Art Generator with Performance Metric", | |
| 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.", | |
| allow_flagging="never", | |
| ) | |
| iface.launch(debug=True, share=True) | |