Celpha2svxx/solvix_linear_algebra
0
1import streamlit as st2import numpy as np3from PIL import Image4import io5 6# 1. Page Configuration7st.set_page_config(page_title="Linear Algebra Image Compressor", layout="wide")8 9st.title(" Matrix Decomposition: Image Compression")10st.markdown("""11This tool uses **Singular Value Decomposition (SVD)** to reduce an image matrix to its most important components. 12It’s the bridge between pure Linear Algebra and real-world data storage.13""")14 15# 2. Sidebar 16st.sidebar.header(" Settings")17uploaded_file = st.sidebar.file_uploader("Upload an image", type=["jpg", "png", "jpeg"])18 19if uploaded_file:20 # Load and Prepare Data21 original_img = Image.open(uploaded_file).convert('L')22 A = np.array(original_img)23 24 # Mathematical Engine (SVD)25 U, s, Vh = np.linalg.svd(A, full_matrices=False)26 max_k = len(s)27 28 # Dynamic Slider for K29 k = st.sidebar.select_slider(30 "Select Number of Singular Values (k)",31 options=list(range(1, max_k + 1)),32 value=min(50, max_k),33 help="Higher k = better quality but less compression."34 )35 36 # 3. Calculations37 # Reconstruct the matrix using the top k components38 A_compressed = np.dot(U[:, :k], np.dot(np.diag(s[:k]), Vh[:k, :]))39 A_compressed = np.clip(A_compressed, 0, 255).astype(np.uint8)40 41 # Information Metric (The 'Energy' of the image)42 variance_explained = np.sum(s[:k]**2) / np.sum(s**2) * 10043 44 # 4. Display Layout45 col1, col2 = st.columns(2)46 47 with col1:48 st.subheader("Original Matrix")49 st.image(A, caption=f"Full Rank: {max_k}", use_container_width=True)50 st.write(f"Size: {A.shape[0]} x {A.shape[1]} pixels")51 52 with col2:53 st.subheader(f"Compressed Matrix (k={k})")54 st.image(A_compressed, caption=f"Approximated Rank: {k}", use_container_width=True)55 st.metric("Information Retained", f"{variance_explained:.2f}%")56 57 # 5. Download Functionality58 result_img = Image.fromarray(A_compressed)59 buf = io.BytesIO()60 result_img.save(buf, format="PNG")61 byte_im = buf.getvalue()62 63 st.sidebar.download_button(64 label="Download Compressed Image",65 data=byte_im,66 file_name=f"compressed_k{k}.png",67 mime="image/png"68 )69 70 st.info(f"Theory in Action: You are representing this {A.size} pixel image using only {((U.shape[0]*k) + k + (k*Vh.shape[1]))} data points.")71 72else:73 st.warning(" Please upload an image in the sidebar to begin the transformation.")74 