File size: 3,886 Bytes
ad9abdd
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
import streamlit as st
import cv2
import numpy as np
from yolov5 import YOLOv5
from sort.sort import Sort
import tempfile
import shutil
from moviepy.editor import VideoFileClip, concatenate_videoclips, ImageSequenceClip
import os

# Load the pre-trained model and initialize the SORT tracker
model_path = 'yolov5s.pt'  # Ensure this path points to the model file
model = YOLOv5(model_path, device='cpu')
tracker = Sort()

def process_video(uploaded_file):
    # Save the uploaded file to a temporary location
    temp_file_path = "temp_video.mp4"
    with open(temp_file_path, "wb") as temp_file:
        temp_file.write(uploaded_file.getbuffer())

    # Use moviepy to read the video file
    video_clip = VideoFileClip(temp_file_path)
    total_frames = int(video_clip.fps * video_clip.duration)
    width, height = video_clip.size

    # Temporary directory to save processed video frames
    temp_dir = tempfile.mkdtemp()

    unique_cars = set()
    progress_bar = st.progress(0)

    for frame_idx, frame in enumerate(video_clip.iter_frames()):
        frame = cv2.cvtColor(frame, cv2.COLOR_RGB2BGR)

        progress_percentage = int((frame_idx + 1) / total_frames * 100)
        progress_bar.progress(progress_percentage)

        # Detection and tracking logic
        results = model.predict(frame)
        preds = results.pandas().xyxy[0]
        detections = []

        for index, row in preds.iterrows():
            if row['name'] == 'car':
                xmin, ymin, xmax, ymax, conf = row['xmin'], row['ymin'], row['xmax'], row['ymax'], row['confidence']
                detections.append([xmin, ymin, xmax, ymax, conf])

        if detections:
            detections_np = np.array(detections)
            trackers = tracker.update(detections_np)

            for d in trackers:
                unique_cars.add(int(d[4]))
                xmin, ymin, xmax, ymax = map(int, d[:4])
                cv2.rectangle(frame, (xmin, ymin), (xmax, ymax), (255, 0, 0), 2)
                cv2.putText(frame, f'ID: {int(d[4])}', (xmin, ymin - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.9, (255, 0, 0), 2)

        cv2.putText(frame, f'Unique Cars: {len(unique_cars)}', (10, 35), cv2.FONT_HERSHEY_SIMPLEX, 1.25, (0, 255, 0), 2)
        frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)  # Convert back to RGB for moviepy
        cv2.imwrite(f"{temp_dir}/{frame_idx:04d}.jpg", frame)

    frames_files = [os.path.join(temp_dir, f"{i:04d}.jpg") for i in range(total_frames)]
    clip = ImageSequenceClip(frames_files, fps=video_clip.fps)
    output_video_path = 'processed_video.mp4'
    clip.write_videofile(output_video_path, codec='libx264')  # Use libx264 codec for compatibility

    # Remove temporary directory and temporary files
    shutil.rmtree(temp_dir)

    return output_video_path


def main():
    # Initialize session state variables if they don't exist
    if 'output_video_path' not in st.session_state:
        st.session_state.output_video_path = None

    st.sidebar.image("logo.jpg", use_column_width=True)
    uploaded_file = st.sidebar.file_uploader("Upload a video", type=['mp4'])

    st.title("Car Detection and Tracking")

    if uploaded_file is not None:
        # Process the video only if it hasn't been processed yet or a new file is uploaded
        if st.session_state.output_video_path is None or st.session_state.uploaded_file_name != uploaded_file.name:
            st.session_state.uploaded_file_name = uploaded_file.name
            st.session_state.output_video_path = process_video(uploaded_file)

        # Display the processed video
        st.video(st.session_state.output_video_path)

        # Provide a download link for the processed video
        with open(st.session_state.output_video_path, "rb") as file:
            st.download_button("Download Processed Video", file, file_name="processed_video.mp4")


if __name__ == "__main__":
    main()