Lane-seg / src /streamlit_app.py
Nasim435's picture
Update src/streamlit_app.py
0428305 verified
import streamlit as st
import cv2
import numpy as np
import tensorflow as tf
from PIL import Image
import time
st.set_page_config(page_title="Lane Segmentation Dashboard", layout="wide")
# MODEL PATH
MODEL_PATH = "/app/model/1"
# LOAD MODEL
@st.cache_resource
def load_model():
model_layer = tf.keras.layers.TFSMLayer(
MODEL_PATH,
call_endpoint="serving_default"
)
inputs = tf.keras.Input(shape=(256, 832, 3))
outputs = model_layer(inputs)
model = tf.keras.Model(inputs=inputs, outputs=outputs)
return model
# PROCESSING
def preprocess_image(image):
image = cv2.resize(image, (832, 256))
return np.expand_dims(image.astype(np.float32) / 255.0, axis=0)
def process_image(image, model):
processed = preprocess_image(image)
prediction = model(processed, training=False)
if isinstance(prediction, dict):
prediction = list(prediction.values())[0]
prediction = prediction.numpy()
mask = (prediction[0] > 0.5).astype(np.uint8).squeeze()
mask = cv2.resize(mask, (image.shape[1], image.shape[0]))
return mask
# SIDEBAR CONTROLS
st.sidebar.header("Controls")
alpha = st.sidebar.slider("Overlay Intensity", 0.0, 1.0, 0.3)
threshold = st.sidebar.slider("Threshold", 0.1, 0.9, 0.5)
show_mask = st.sidebar.checkbox("Show Raw Mask")
show_metrics = st.sidebar.checkbox("Show Metrics", value=True)
# UI HEADER
st.title("Lane Segmentation Dashboard")
model = load_model()
st.success("Model loaded successfully")
# FILE UPLOAD
uploaded_file = st.file_uploader(
"Upload image",
type=["jpg", "jpeg", "png"],
accept_multiple_files=False
)
if uploaded_file is None:
st.info("Upload an image to begin")
st.stop()
# LOAD IMAGE
image = np.array(Image.open(uploaded_file).convert("RGB"))
if image.shape[0] > 1500 or image.shape[1] > 1500:
image = cv2.resize(image, (832, 256))
# RUN BUTTON
run = st.button("Run Lane Detection")
if not run:
st.image(image, caption="Uploaded Image", width="stretch")
st.stop()
# INFERENCE
start = time.time()
mask = process_image(image, model)
end = time.time()
inference_time = (end - start) * 1000 # ms
# APPLY THRESHOLD + COLOR
mask = (mask > threshold).astype(np.uint8)
colored_mask = np.zeros_like(image)
colored_mask[mask == 1] = [0, 255, 0]
result = cv2.addWeighted(image, 1 - alpha, colored_mask, alpha, 0)
# METRICS
lane_pixels = np.sum(mask)
total_pixels = mask.size
lane_coverage = (lane_pixels / total_pixels) * 100
fps = 1000 / inference_time if inference_time > 0 else 0
# DISPLAY
col1, col2 = st.columns(2)
with col1:
st.subheader("Original")
st.image(image, width="stretch")
with col2:
st.subheader("Segmentation")
st.image(result, width="stretch")
# OPTIONAL MASK
if show_mask:
st.subheader("Raw Mask")
st.image(mask * 255)
# METRICS DASHBOARD
if show_metrics:
st.subheader("Performance Metrics")
m1, m2, m3 = st.columns(3)
m1.metric("Inference Time (ms)", f"{inference_time:.2f}")
m2.metric("FPS", f"{fps:.2f}")
m3.metric("Lane Coverage (%)", f"{lane_coverage:.2f}")