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):
|