File size: 3,526 Bytes
c70d2eb
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
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"
    )