Srikanth0804's picture
Update app.py
dcbec55 verified
Raw History Blame Contribute Delete
4.01 kB
# streamlit_yolo_seg_webcam_fixed.py
import streamlit as st
import cv2
import numpy as np
from ultralytics import YOLO
from PIL import Image
import matplotlib.pyplot as plt
st.title("YOLOv8 Image Segmentation with Webcam & Elbow Curve")
# -------------------------------
# Load YOLO Segmentation Model
# -------------------------------
@st.cache_resource
def load_model(model_name="yolov8n-seg.pt"):
return YOLO(model_name)
model = load_model()
# -------------------------------
# Input Method
# -------------------------------
input_option = st.radio("Input Method", ["Upload Image", "Webcam Capture"])
if input_option == "Upload Image":
uploaded_file = st.file_uploader("Upload an image", type=["jpg", "jpeg", "png"])
if uploaded_file is not None:
image = Image.open(uploaded_file).convert("RGB")
img_array = np.array(image)
elif input_option == "Webcam Capture":
webcam_image = st.camera_input("Capture an image")
if webcam_image is not None:
image = Image.open(webcam_image).convert("RGB")
img_array = np.array(image)
else:
st.stop()
# -------------------------------
# Run Segmentation
# -------------------------------
if 'img_array' in locals():
with st.spinner("Running YOLOv8 segmentation..."):
results = model(img_array)
annotated_img = results[0].plot()
# Display images
col1, col2 = st.columns(2)
with col1:
st.image(image, caption="Original Image", use_column_width=True)
with col2:
st.image(annotated_img, caption="Segmented Image", use_column_width=True)
# Download annotated image
annotated_bgr = cv2.cvtColor(annotated_img, cv2.COLOR_RGB2BGR)
cv2.imwrite("segmented_output.jpg", annotated_bgr)
with open("segmented_output.jpg", "rb") as f:
st.download_button("Download Segmented Image", f, "segmented_output.jpg")
# -------------------------------
# Elbow Curve (robust)
# -------------------------------
st.subheader("Elbow Curve")
try:
from sklearn.cluster import KMeans
# Extract centroids from masks
masks = getattr(results[0], "masks", None)
centroids = []
if masks is not None:
try:
mask_np = masks.data
except AttributeError:
mask_np = masks
# Convert to numpy
if hasattr(mask_np, "numpy"):
mask_np = mask_np.numpy()
elif isinstance(mask_np, list):
mask_np = np.array(mask_np)
if mask_np.ndim >= 3:
for m in mask_np:
y_idx, x_idx = np.where(m > 0.5)
if len(x_idx) > 0:
centroids.append([np.mean(x_idx), np.mean(y_idx)])
# Fallback if no masks found
if len(centroids) == 0:
st.info("No masks detected — using random points for elbow curve.")
centroids = np.random.rand(10, 2) * 100
centroids = np.array(centroids)
# Only compute elbow if >= 2 points
if len(centroids) < 2:
st.info("Too few points for elbow curve.")
else:
max_k = min(10, len(centroids))
wcss = []
for k in range(1, max_k + 1):
kmeans = KMeans(n_clusters=k, random_state=42).fit(centroids)
wcss.append(kmeans.inertia_)
# Slider to select k
selected_k = st.slider("Select k to highlight on Elbow Curve", 1, max_k, value=3)
# Plot elbow curve
fig, ax = plt.subplots()
ax.plot(range(1, max_k + 1), wcss, marker='o', label='WCSS')
ax.axvline(x=selected_k, color='r', linestyle='--', label=f'Selected k = {selected_k}')
ax.set_xlabel("Number of clusters (k)")
ax.set_ylabel("WCSS")
ax.set_title("Elbow Curve")
ax.legend()
st.pyplot(fig)
except Exception as e:
st.info(f"Elbow curve unavailable: {e}")