File size: 4,213 Bytes
6cb50ff
a03d512
fc635eb
177b569
7a25fd2
d552a3c
99d616d
 
 
 
7a25fd2
99d616d
b739bed
d552a3c
c0cf5bc
99d616d
 
d552a3c
6cb50ff
d552a3c
99d616d
 
 
d552a3c
 
 
 
99d616d
 
 
 
7a25fd2
 
 
99d616d
7a25fd2
d552a3c
 
99d616d
d552a3c
 
 
7a25fd2
 
99d616d
d552a3c
 
99d616d
7a25fd2
d552a3c
99d616d
a03d512
99d616d
7a25fd2
99d616d
 
 
d552a3c
 
 
 
 
 
7a25fd2
99d616d
d552a3c
 
7a25fd2
d552a3c
 
99d616d
7a25fd2
d552a3c
 
 
 
 
 
 
99d616d
d552a3c
 
 
 
 
 
 
a952223
7a25fd2
99d616d
 
d552a3c
 
 
 
 
 
 
 
 
 
 
99d616d
 
 
 
 
d552a3c
 
 
 
 
 
99d616d
d552a3c
 
99d616d
 
 
 
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
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
import cv2
import torch
import gradio as gr
import numpy as np
from ultralytics import YOLO, __version__ as ultralytics_version
import time

# Debug: Check environment
print(f"Torch version: {torch.__version__}")
print(f"Gradio version: {gr.__version__}")
print(f"Ultralytics version: {ultralytics_version}")
print(f"CUDA available: {torch.cuda.is_available()}")

# Load custom YOLO model
device = "cuda" if torch.cuda.is_available() else "cpu"
print(f"Using device: {device}")
model = YOLO('./data/best.pt').to(device)
print(f"Model classes: {model.names}")  # Print classes (should include cracks, potholes)

def process_video(video, resize_width=640, resize_height=480, frame_skip=1):
    if video is None:
        return "Error: No video uploaded"
    
    # Start timer
    start_time = time.time()
    
    # Open input video
    cap = cv2.VideoCapture(video)
    if not cap.isOpened():
        return "Error: Could not open video file"
    
    # Get input video properties
    frame_width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
    frame_height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
    fps = cap.get(cv2.CAP_PROP_FPS)
    total_frames = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))
    expected_duration = total_frames / fps
    print(f"Input video: {frame_width}x{frame_height}, {fps} FPS, {total_frames} frames, {expected_duration:.2f} seconds")
    
    # Set output resolution
    out_width, out_height = resize_width, resize_height
    print(f"Output resolution: {out_width}x{out_height}")
    
    # Set up video writer
    output_path = "processed_output.mp4"
    fourcc = cv2.VideoWriter_fourcc(*'mp4v')  # Use 'H264' if mp4v fails
    out = cv2.VideoWriter(output_path, fourcc, fps, (out_width, out_height))
    
    frame_count = 0
    processed_frames = 0
    
    while True:
        ret, frame = cap.read()
        if not ret:
            break
            
        frame_count += 1
        
        # Skip frames if frame_skip > 1
        if frame_count % frame_skip != 0:
            continue
            
        processed_frames += 1
        print(f"Processing frame {frame_count}/{total_frames}")
        
        # Resize frame for faster inference
        frame = cv2.resize(frame, (out_width, out_height))
        
        # Run YOLO inference (detect cracks and potholes)
        results = model(frame, verbose=False, conf=0.5)  # Confidence threshold 0.5
        annotated_frame = results[0].plot()
        
        # Log detections
        for detection in results[0].boxes:
            cls = int(detection.cls)
            conf = float(detection.conf)
            print(f"Frame {frame_count}: Detected {model.names[cls]} with confidence {conf:.2f}")
        
        # Write annotated frame
        out.write(annotated_frame)
        
        # Duplicate frames if skipping to maintain duration
        if frame_skip > 1:
            for _ in range(frame_skip - 1):
                if frame_count + 1 <= total_frames:
                    out.write(annotated_frame)
                    frame_count += 1
    
    # Release resources
    cap.release()
    out.release()
    
    # Verify output duration
    cap = cv2.VideoCapture(output_path)
    output_frames = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))
    output_fps = cap.get(cv2.CAP_PROP_FPS)
    output_duration = output_frames / output_fps
    cap.release()
    
    print(f"Output video: {output_frames} frames, {output_fps} FPS, {output_duration:.2f} seconds")
    print(f"Processing time: {time.time() - start_time:.2f} seconds")
    
    return output_path

# Gradio interface
iface = gr.Interface(
    fn=process_video,
    inputs=[
        gr.Video(label="Upload Video"),
        gr.Slider(minimum=320, maximum=1280, value=640, label="Output Width", step=1),
        gr.Slider(minimum=240, maximum=720, value=480, label="Output Height", step=1),
        gr.Slider(minimum=1, maximum=5, value=1, label="Frame Skip (1 = process all frames)", step=1)
    ],
    outputs=gr.Video(label="Processed Video"),
    title="Crack and Pothole Detection with YOLO",
    description="Upload a video to detect cracks and potholes. Adjust resolution and frame skip for faster processing."
)

if __name__ == "__main__":
    iface.launch()