Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
@@ -44,8 +44,8 @@ last_metrics: Dict[str, Any] = {}
|
|
44 |
frame_count: int = 0
|
45 |
SAVE_IMAGE_INTERVAL = 1 # Save every frame with detections
|
46 |
|
47 |
-
# Detection classes (
|
48 |
-
DETECTION_CLASSES = ["Longitudinal", "Pothole", "Transverse"
|
49 |
|
50 |
# Debug: Check environment
|
51 |
print(f"Torch version: {torch.__version__}")
|
@@ -106,10 +106,13 @@ def write_flight_log(frame_count: int, gps_coord: List[float], timestamp: str) -
|
|
106 |
log_entries.append(f"Error: Failed to write flight log {log_path}: {str(e)}")
|
107 |
return ""
|
108 |
|
109 |
-
def check_image_quality(frame: np.ndarray) -> bool:
|
110 |
height, width, _ = frame.shape
|
111 |
-
|
112 |
-
|
|
|
|
|
|
|
113 |
return False
|
114 |
return True
|
115 |
|
@@ -136,7 +139,7 @@ def generate_line_chart() -> Optional[str]:
|
|
136 |
plt.close()
|
137 |
return chart_path
|
138 |
|
139 |
-
def process_video(video, resize_width=
|
140 |
global frame_count, last_metrics, detected_counts, detected_issues, gps_coordinates, log_entries
|
141 |
frame_count = 0
|
142 |
detected_counts.clear()
|
@@ -159,12 +162,13 @@ def process_video(video, resize_width=320, resize_height=240, frame_skip=5):
|
|
159 |
|
160 |
frame_width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
|
161 |
frame_height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
|
|
|
162 |
fps = cap.get(cv2.CAP_PROP_FPS)
|
163 |
total_frames = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))
|
164 |
expected_duration = total_frames / fps if fps > 0 else 0
|
165 |
-
log_entries.append(f"Input video: {frame_width}x{frame_height}, {fps} FPS, {total_frames} frames, {expected_duration:.2f} seconds")
|
166 |
-
logging.info(f"Input video: {frame_width}x{frame_height}, {fps} FPS, {total_frames} frames, {expected_duration:.2f} seconds")
|
167 |
-
print(f"Input video: {frame_width}x{frame_height}, {fps} FPS, {total_frames} frames, {expected_duration:.2f} seconds")
|
168 |
|
169 |
out_width, out_height = resize_width, resize_height
|
170 |
output_path = os.path.join(OUTPUT_DIR, "processed_output.mp4")
|
@@ -213,7 +217,7 @@ def process_video(video, resize_width=320, resize_height=240, frame_skip=5):
|
|
213 |
frame_start = time.time()
|
214 |
|
215 |
frame = cv2.resize(frame, (out_width, out_height))
|
216 |
-
if not check_image_quality(frame):
|
217 |
log_entries.append(f"Frame {frame_count}: Skipped due to low resolution")
|
218 |
continue
|
219 |
|
@@ -232,7 +236,7 @@ def process_video(video, resize_width=320, resize_height=240, frame_skip=5):
|
|
232 |
conf = float(detection.conf)
|
233 |
box = detection.xyxy[0].cpu().numpy().astype(int).tolist()
|
234 |
label = model.names[cls]
|
235 |
-
if label in DETECTION_CLASSES:
|
236 |
frame_detections.append({
|
237 |
"label": label,
|
238 |
"box": box,
|
@@ -327,8 +331,8 @@ def process_video(video, resize_width=320, resize_height=240, frame_skip=5):
|
|
327 |
total_time = time.time() - start_time
|
328 |
avg_frame_time = sum(frame_times) / len(frame_times) if frame_times else 0
|
329 |
log_entries.append(f"Output video: {output_frames} frames, {output_fps} FPS, {output_duration:.2f} seconds")
|
330 |
-
log_entries.append(f"Total processing time: {total_time:.2f} seconds, Avg frame time: {avg_frame_time:.2f} ms, Detection frames: {detection_frame_count}, Output frames: {output_frame_count}")
|
331 |
logging.info(f"Output video: {output_frames} frames, {output_fps} FPS, {output_duration:.2f} seconds")
|
|
|
332 |
logging.info(f"Total processing time: {total_time:.2f} seconds, Avg frame time: {avg_frame_time:.2f} ms, Detection frames: {detection_frame_count}, Output frames: {output_frame_count}")
|
333 |
print(f"Output video: {output_frames} frames, {output_fps} FPS, {output_duration:.2f} seconds")
|
334 |
print(f"Total processing time: {total_time:.2f} seconds, Avg frame time: {avg_frame_time:.2f} ms, Detection frames: {detection_frame_count}, Output frames: {output_frame_count}")
|
@@ -350,9 +354,9 @@ with gr.Blocks(theme=gr.themes.Soft(primary_hue="orange")) as iface:
|
|
350 |
gr.Markdown("# NHAI Road Defect Detection Dashboard")
|
351 |
with gr.Row():
|
352 |
with gr.Column(scale=3):
|
353 |
-
video_input = gr.Video(label="Upload Video")
|
354 |
-
width_slider = gr.Slider(320,
|
355 |
-
height_slider = gr.Slider(240,
|
356 |
skip_slider = gr.Slider(1, 10, value=5, label="Frame Skip", step=1)
|
357 |
process_btn = gr.Button("Process Video", variant="primary")
|
358 |
with gr.Column(scale=1):
|
|
|
44 |
frame_count: int = 0
|
45 |
SAVE_IMAGE_INTERVAL = 1 # Save every frame with detections
|
46 |
|
47 |
+
# Detection classes (aligned with model classes, excluding 'Crocodile' and 'Crack')
|
48 |
+
DETECTION_CLASSES = ["Longitudinal", "Pothole", "Transverse"]
|
49 |
|
50 |
# Debug: Check environment
|
51 |
print(f"Torch version: {torch.__version__}")
|
|
|
106 |
log_entries.append(f"Error: Failed to write flight log {log_path}: {str(e)}")
|
107 |
return ""
|
108 |
|
109 |
+
def check_image_quality(frame: np.ndarray, input_resolution: int) -> bool:
|
110 |
height, width, _ = frame.shape
|
111 |
+
frame_resolution = width * height
|
112 |
+
if frame_resolution < 12_000_000: # NHAI requires 12 MP
|
113 |
+
log_entries.append(f"Frame {frame_count}: Resolution {width}x{height} ({frame_resolution/1e6:.2f}MP) below 12MP, non-compliant")
|
114 |
+
if frame_resolution < input_resolution: # Ensure output is not below input
|
115 |
+
log_entries.append(f"Frame {frame_count}: Output resolution {width}x{height} below input resolution")
|
116 |
return False
|
117 |
return True
|
118 |
|
|
|
139 |
plt.close()
|
140 |
return chart_path
|
141 |
|
142 |
+
def process_video(video, resize_width=4000, resize_height=3000, frame_skip=5):
|
143 |
global frame_count, last_metrics, detected_counts, detected_issues, gps_coordinates, log_entries
|
144 |
frame_count = 0
|
145 |
detected_counts.clear()
|
|
|
162 |
|
163 |
frame_width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
|
164 |
frame_height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
|
165 |
+
input_resolution = frame_width * frame_height
|
166 |
fps = cap.get(cv2.CAP_PROP_FPS)
|
167 |
total_frames = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))
|
168 |
expected_duration = total_frames / fps if fps > 0 else 0
|
169 |
+
log_entries.append(f"Input video: {frame_width}x{frame_height} ({input_resolution/1e6:.2f}MP), {fps} FPS, {total_frames} frames, {expected_duration:.2f} seconds")
|
170 |
+
logging.info(f"Input video: {frame_width}x{frame_height} ({input_resolution/1e6:.2f}MP), {fps} FPS, {total_frames} frames, {expected_duration:.2f} seconds")
|
171 |
+
print(f"Input video: {frame_width}x{frame_height} ({input_resolution/1e6:.2f}MP), {fps} FPS, {total_frames} frames, {expected_duration:.2f} seconds")
|
172 |
|
173 |
out_width, out_height = resize_width, resize_height
|
174 |
output_path = os.path.join(OUTPUT_DIR, "processed_output.mp4")
|
|
|
217 |
frame_start = time.time()
|
218 |
|
219 |
frame = cv2.resize(frame, (out_width, out_height))
|
220 |
+
if not check_image_quality(frame, input_resolution):
|
221 |
log_entries.append(f"Frame {frame_count}: Skipped due to low resolution")
|
222 |
continue
|
223 |
|
|
|
236 |
conf = float(detection.conf)
|
237 |
box = detection.xyxy[0].cpu().numpy().astype(int).tolist()
|
238 |
label = model.names[cls]
|
239 |
+
if label in DETECTION_CLASSES:
|
240 |
frame_detections.append({
|
241 |
"label": label,
|
242 |
"box": box,
|
|
|
331 |
total_time = time.time() - start_time
|
332 |
avg_frame_time = sum(frame_times) / len(frame_times) if frame_times else 0
|
333 |
log_entries.append(f"Output video: {output_frames} frames, {output_fps} FPS, {output_duration:.2f} seconds")
|
|
|
334 |
logging.info(f"Output video: {output_frames} frames, {output_fps} FPS, {output_duration:.2f} seconds")
|
335 |
+
log_entries.append(f"Total processing time: {total_time:.2f} seconds, Avg frame time: {avg_frame_time:.2f} ms, Detection frames: {detection_frame_count}, Output frames: {output_frame_count}")
|
336 |
logging.info(f"Total processing time: {total_time:.2f} seconds, Avg frame time: {avg_frame_time:.2f} ms, Detection frames: {detection_frame_count}, Output frames: {output_frame_count}")
|
337 |
print(f"Output video: {output_frames} frames, {output_fps} FPS, {output_duration:.2f} seconds")
|
338 |
print(f"Total processing time: {total_time:.2f} seconds, Avg frame time: {avg_frame_time:.2f} ms, Detection frames: {detection_frame_count}, Output frames: {output_frame_count}")
|
|
|
354 |
gr.Markdown("# NHAI Road Defect Detection Dashboard")
|
355 |
with gr.Row():
|
356 |
with gr.Column(scale=3):
|
357 |
+
video_input = gr.Video(label="Upload Video (12MP recommended for NHAI compliance)")
|
358 |
+
width_slider = gr.Slider(320, 4000, value=4000, label="Output Width", step=1)
|
359 |
+
height_slider = gr.Slider(240, 3000, value=3000, label="Output Height", step=1)
|
360 |
skip_slider = gr.Slider(1, 10, value=5, label="Frame Skip", step=1)
|
361 |
process_btn = gr.Button("Process Video", variant="primary")
|
362 |
with gr.Column(scale=1):
|