File size: 3,648 Bytes
2b706a3 3e76461 1aada28 2b706a3 1aada28 2b706a3 21ff79c 3e76461 2b706a3 a38d262 52a6170 2b706a3 3e76461 2b706a3 3e76461 2b706a3 3e76461 1aada28 2b706a3 3e76461 21ff79c 3e76461 1aada28 aac9498 2b706a3 aac9498 2b706a3 3e76461 2b706a3 1aada28 3e76461 1aada28 21ff79c 3e76461 1aada28 21ff79c 1aada28 3e76461 7cfc50e a38d262 2b706a3 7cfc50e 3e76461 21ff79c 339c61a aac9498 339c61a 21ff79c 3e76461 a38d262 3e76461 1aada28 21ff79c 7cfc50e a38d262 21ff79c a38d262 aac9498 1c98205 | 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 streamlit as st
from ultralytics import YOLO
from ultralytics.nn.tasks import SegmentationModel
import torch
import cv2
import numpy as np
import tempfile
import os
# Fix for PyTorch 2.6
torch.serialization.add_safe_globals([SegmentationModel])
# Load YOLOv8 segmentation model on CPU
model = YOLO("yolov8n-seg.pt").to("cpu")
st.title("🎥 Object Segmentation on Uploaded Video")
uploaded_video = st.file_uploader("Upload a video", type=["mp4", "avi", "mov"])
if uploaded_video:
# Save video temporarily
tfile = tempfile.NamedTemporaryFile(delete=False)
tfile.write(uploaded_video.read())
video_path = tfile.name
st.video(video_path)
st.markdown("### ⏳ Processing video... Please wait.")
cap = cv2.VideoCapture(video_path)
width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
fps = int(cap.get(cv2.CAP_PROP_FPS))
output_path = os.path.join(tempfile.gettempdir(), "output_segmentation.mp4")
fourcc = cv2.VideoWriter_fourcc(*'mp4v')
out = cv2.VideoWriter(output_path, fourcc, fps, (width, height))
frame_count = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))
progress_bar = st.progress(0)
# Generate class color map
np.random.seed(42)
colors = {i: tuple(np.random.randint(0, 256, 3).tolist()) for i in range(80)}
frame_index = 0
while cap.isOpened():
ret, frame = cap.read()
if not ret:
break
try:
results = model.predict(frame, conf=0.3, iou=0.5)
except Exception as e:
st.error(f"Prediction failed on frame {frame_index}: {e}")
break
if results[0].masks is not None:
masks = results[0].masks.data.cpu().numpy()
class_ids = results[0].boxes.cls.cpu().numpy().astype(int)
boxes = results[0].boxes.xyxy.cpu().numpy()
names = results[0].names
for mask, class_id, box in zip(masks, class_ids, boxes):
label = names[class_id]
color = colors.get(class_id, (0, 255, 0))
# Resize and apply mask
resized_mask = cv2.resize(mask, (frame.shape[1], frame.shape[0]))
mask_bool = resized_mask > 0.5
# Overlay
colored_mask = np.zeros_like(frame, dtype=np.uint8)
colored_mask[mask_bool] = color
frame = cv2.addWeighted(frame, 1.0, colored_mask, 0.5, 0)
# Label
x1, y1, x2, y2 = box.astype(int)
font = cv2.FONT_HERSHEY_SIMPLEX
font_scale = 0.6
thickness = 1
label_text = label
(text_width, text_height), _ = cv2.getTextSize(label_text, font, font_scale, thickness)
text_x = x1
text_y = y1 - 10 if y1 - 10 > 10 else y1 + text_height + 10
# Draw label background
cv2.rectangle(frame, (text_x - 2, text_y - text_height - 4),
(text_x + text_width + 2, text_y + 4), (0, 0, 0), -1)
cv2.putText(frame, label_text, (text_x, text_y),
font, font_scale, (255, 255, 255), thickness=1, lineType=cv2.LINE_AA)
out.write(frame)
frame_index += 1
progress_bar.progress(min(frame_index / frame_count, 1.0))
cap.release()
out.release()
progress_bar.empty()
st.success("✅ Video processing completed!")
with open(output_path, "rb") as f:
st.download_button("📥 Download Segmented Video", f, file_name="segmented_output.mp4", mime="video/mp4")
|