|
import numpy as np |
|
import gradio as gr |
|
from skimage import io |
|
from PIL import Image |
|
|
|
def svd_compress(image_channel, k): |
|
"""Compress a single channel of the image using SVD by keeping only the top k singular values.""" |
|
U, S, Vt = np.linalg.svd(image_channel, full_matrices=False) |
|
compressed_channel = np.dot(U[:, :k], np.dot(np.diag(S[:k]), Vt[:k, :])) |
|
return compressed_channel |
|
|
|
def process_image(image, k): |
|
"""Process the uploaded image, compress it using SVD for each color channel, and return the result.""" |
|
|
|
image_np = np.array(image) |
|
|
|
|
|
if len(image_np.shape) == 3: |
|
r_channel, g_channel, b_channel = image_np[:, :, 0], image_np[:, :, 1], image_np[:, :, 2] |
|
|
|
|
|
r_compressed = svd_compress(r_channel, k) |
|
g_compressed = svd_compress(g_channel, k) |
|
b_compressed = svd_compress(b_channel, k) |
|
|
|
|
|
compressed_image = np.stack([r_compressed, g_compressed, b_compressed], axis=2) |
|
else: |
|
compressed_image = svd_compress(image_np, k) |
|
|
|
|
|
compressed_image = np.clip(compressed_image, 0, 255) |
|
compressed_image_pil = Image.fromarray(compressed_image.astype(np.uint8)) |
|
|
|
return compressed_image_pil |
|
|
|
|
|
gr.Interface(fn=process_image, |
|
inputs=[gr.Image(type="pil", label="Upload Image"), |
|
gr.Slider(1, 100, step=1, value=50, label="Compression Rank")], |
|
outputs=gr.Image(type="pil", label="Compressed Image"), |
|
title="Color Image Compression using SVD", |
|
description="Upload an image (color or grayscale) and adjust the compression rank to see the compressed version." |
|
).launch() |