Srikanthgoud7's picture
Upload app.py
abe3536 verified
Raw
History Blame Contribute Delete
2.57 kB
import streamlit as st
import cv2
import numpy as np
import matplotlib.pyplot as plt
from sklearn.cluster import KMeans
import matplotlib.ticker as ticker
from io import BytesIO
from PIL import Image
# -----------------------------
# Streamlit App
# -----------------------------
st.title("๐Ÿ–ผ๏ธ Image Segmentation using K-Means Clustering")
# Sidebar options
st.sidebar.header("Controls")
uploaded_file = st.sidebar.file_uploader("Upload an image", type=["jpg", "jpeg", "png"])
max_k = st.sidebar.slider("Max K for Elbow Curve", 5, 15, 10)
chosen_k = st.sidebar.slider("Choose K (Clusters)", 2, 10, 4)
if uploaded_file is not None:
# -----------------------------
# Step 1: Load Image
# -----------------------------
image = Image.open(uploaded_file)
image = np.array(image)
st.subheader("Original Image")
st.image(image, use_container_width=True)
# -----------------------------
# Step 2: Preprocess Image
# -----------------------------
pixels = image.reshape((-1, 3))
pixels = np.float32(pixels)
# -----------------------------
# Step 3: Elbow Curve
# -----------------------------
wcss = []
K = range(1, max_k+1)
for k in K:
kmeans = KMeans(n_clusters=k, random_state=42)
kmeans.fit(pixels)
wcss.append(kmeans.inertia_)
# Plot elbow curve
fig, ax = plt.subplots(figsize=(6, 4))
ax.plot(K, wcss, 'bo-')
ax.set_xlabel("Number of clusters (k)")
ax.set_ylabel("WCSS (Inertia)")
ax.set_title("Elbow Curve")
# Format y-axis in millions
ax.yaxis.set_major_formatter(ticker.FuncFormatter(lambda x, _: f'{int(x/1e6)}M'))
# Add vertical dotted line for chosen k
ax.axvline(x=chosen_k, color='r', linestyle='--', label=f'k={chosen_k}')
ax.legend()
st.subheader("Elbow Curve")
st.pyplot(fig)
# -----------------------------
# Step 4: Apply KMeans with chosen k
# -----------------------------
kmeans = KMeans(n_clusters=chosen_k, random_state=42)
labels = kmeans.fit_predict(pixels)
segmented_img = kmeans.cluster_centers_[labels]
segmented_img = segmented_img.reshape(image.shape)
segmented_img = np.uint8(segmented_img)
# -----------------------------
# Step 5: Show Results
# -----------------------------
st.subheader(f"Segmented Image (k={chosen_k})")
st.image(segmented_img, use_container_width=True)
else:
st.info("๐Ÿ‘ˆ Upload an image from the sidebar to start.")