Spaces:
Sleeping
Sleeping
import numpy as np | |
import matplotlib.pyplot as plt | |
from skimage.io import imread | |
from skimage.color import rgb2gray | |
from skimage.metrics import structural_similarity as ssim | |
import streamlit as st | |
from io import BytesIO | |
def load_image(path, gray=False): | |
img = imread(path) | |
if gray: | |
img = rgb2gray(img) | |
return img / 255.0 # Normalize to [0, 1] | |
def svd_compression(image, num_singular_values): | |
U, S, V = np.linalg.svd(image, full_matrices=False) | |
U_reduced = U[:, :num_singular_values] | |
S_reduced = np.diag(S[:num_singular_values]) | |
V_reduced = V[:num_singular_values, :] | |
compressed_image = np.dot(U_reduced, np.dot(S_reduced, V_reduced)) | |
return compressed_image, U, S, V | |
def svd_compression_rgb(image, num_singular_values): | |
channels = [] | |
for i in range(image.shape[2]): # R, G, B channels | |
compressed_channel, _, _, _ = svd_compression(image[:, :, i], num_singular_values) | |
channels.append(compressed_channel) | |
return np.clip(np.stack(channels, axis=2), 0, 1) | |
def compute_metrics(original, compressed): | |
mse = np.mean((original - compressed) ** 2) | |
ssim_value = sum(ssim(original[:, :, i], compressed[:, :, i], data_range=compressed[:, :, i].max() - compressed[:, :, i].min()) for i in range(3)) / 3 | |
return mse, ssim_value | |
def visualize_results(original, compressed, num_singular_values, mse, ssim_value): | |
fig, ax = plt.subplots(1, 2, figsize=(12, 6)) | |
ax[0].imshow(original) | |
ax[0].set_title("Original Image") | |
ax[0].axis("off") | |
ax[1].imshow(compressed) | |
ax[1].set_title(f"Compressed (k={num_singular_values})\nMSE: {mse:.2f}, SSIM: {ssim_value:.2f}") | |
ax[1].axis("off") | |
plt.tight_layout() | |
plt.show() | |
# Main script | |
# image = load_image('cow.jpg', gray=False) | |
# num_singular_values = 50 | |
# compressed_image = svd_compression_rgb(image, num_singular_values) | |
# mse, ssim_value = compute_metrics(image, compressed_image) | |
# print(f"MSE: {mse:.2f}, SSIM: {ssim_value:.2f}") | |
# visualize_results(image, compressed_image, num_singular_values, mse, ssim_value) | |
def save_image_as_bytes(image): | |
buf = BytesIO() | |
plt.imsave(buf, image, format="jpg", cmap='gray') | |
buf.seek(0) | |
return buf | |
# Streamlit app code | |
st.title("Image Compression using SVD") | |
# Upload Image | |
uploaded_file = st.file_uploader("Choose an image...", type=["jpg", "png", "jpeg"]) | |
if uploaded_file is not None: | |
# Load the image | |
image = load_image(uploaded_file, gray=False) | |
# Show original image | |
st.image(image, caption="Original Image", use_container_width=True) | |
# User input for the number of singular values | |
num_singular_values = st.slider("Select number of singular values (k)", min_value=1, max_value=100, value=50) | |
# Perform SVD compression | |
compressed_image = svd_compression_rgb(image, num_singular_values) | |
# Compute metrics | |
mse, ssim_value = compute_metrics(image, compressed_image) | |
# Show compressed image | |
st.image(compressed_image, caption=f"Compressed Image (k={num_singular_values})", use_container_width=True) | |
# Display metrics | |
st.write(f"MSE: {mse:.2f}") | |
st.write(f"SSIM: {ssim_value:.2f}") | |
# Save compressed image as bytes for download | |
compressed_image_bytes = save_image_as_bytes(compressed_image) | |
# Download button for the compressed image | |
st.download_button( | |
label="Download Compressed Image", | |
data=compressed_image_bytes, | |
file_name="compressed_image.png", | |
mime="image/png" | |
) |