Yaswanth56 commited on
Commit
7be3c23
·
verified ·
1 Parent(s): 1b0039c

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +54 -104
app.py CHANGED
@@ -15,6 +15,7 @@ import ultralytics
15
  import time
16
  import piexif
17
  import zipfile
 
18
 
19
  # Set YOLO config directory
20
  os.environ["YOLO_CONFIG_DIR"] = "/tmp/Ultralytics"
@@ -56,13 +57,58 @@ print(f"Ultralytics version: {ultralytics.__version__}")
56
  print(f"CUDA available: {torch.cuda.is_available()}")
57
 
58
  # Load custom YOLO model
59
- device = "cuda" if torch.cuda.is_available() else "cpu"
60
  print(f"Using device: {device}")
61
- model = YOLO('./data/best.pt').to(device)
62
- if device == "cuda":
63
- model.half()
64
  print(f"Model classes: {model.names}")
65
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
66
  def zip_directory(folder_path: str, zip_path: str) -> str:
67
  """Zip all files in a directory."""
68
  try:
@@ -90,57 +136,6 @@ def generate_map(gps_coords: List[List[float]], items: List[Dict[str, Any]]) ->
90
  plt.close()
91
  return map_path
92
 
93
- def write_geotag(image_path: str, gps_coord: List[float]) -> bool:
94
- try:
95
- lat = abs(gps_coord[0])
96
- lon = abs(gps_coord[1])
97
- lat_ref = "N" if gps_coord[0] >= 0 else "S"
98
- lon_ref = "E" if gps_coord[1] >= 0 else "W"
99
- exif_dict = piexif.load(image_path) if os.path.exists(image_path) else {"GPS": {}}
100
- exif_dict["GPS"] = {
101
- piexif.GPSIFD.GPSLatitudeRef: lat_ref,
102
- piexif.GPSIFD.GPSLatitude: ((int(lat), 1), (0, 1), (0, 1)),
103
- piexif.GPSIFD.GPSLongitudeRef: lon_ref,
104
- piexif.GPSIFD.GPSLongitude: ((int(lon), 1), (0, 1), (0, 1))
105
- }
106
- piexif.insert(piexif.dump(exif_dict), image_path)
107
- return True
108
- except Exception as e:
109
- logging.error(f"Failed to geotag {image_path}: {str(e)}")
110
- log_entries.append(f"Error: Failed to geotag {image_path}: {str(e)}")
111
- return False
112
-
113
- def write_flight_log(frame_count: int, gps_coord: List[float], timestamp: str) -> str:
114
- log_path = os.path.join(FLIGHT_LOG_DIR, f"flight_log_{frame_count:06d}.csv")
115
- try:
116
- with open(log_path, 'w', newline='') as csvfile:
117
- writer = csv.writer(csvfile)
118
- writer.writerow(["Frame", "Timestamp", "Latitude", "Longitude", "Speed_ms", "Satellites", "Altitude_m"])
119
- writer.writerow([frame_count, timestamp, gps_coord[0], gps_coord[1], 5.0, 12, 60])
120
- return log_path
121
- except Exception as e:
122
- logging.error(f"Failed to write flight log {log_path}: {str(e)}")
123
- log_entries.append(f"Error: Failed to write flight log {log_path}: {str(e)}")
124
- return ""
125
-
126
- def check_image_quality(frame: np.ndarray, input_resolution: int) -> bool:
127
- height, width, _ = frame.shape
128
- frame_resolution = width * height
129
- if frame_resolution < 12_000_000:
130
- log_entries.append(f"Frame {frame_count}: Resolution {width}x{height} ({frame_resolution/1e6:.2f}MP) below 12MP, non-compliant")
131
- if frame_resolution < input_resolution:
132
- log_entries.append(f"Frame {frame_count}: Output resolution {width}x{height} below input resolution")
133
- return False
134
- return True
135
-
136
- def update_metrics(detections: List[Dict[str, Any]]) -> Dict[str, Any]:
137
- counts = Counter([det["label"] for det in detections])
138
- return {
139
- "items": [{"type": k, "count": v} for k, v in counts.items()],
140
- "total_detections": len(detections),
141
- "timestamp": datetime.now().strftime("%Y-%m-%d %H:%M:%S")
142
- }
143
-
144
  def generate_line_chart() -> Optional[str]:
145
  if not detected_counts:
146
  return None
@@ -361,6 +356,9 @@ def process_video(video, resize_width=4000, resize_height=3000, frame_skip=5):
361
  images_zip = zip_directory(CAPTURED_FRAMES_DIR, os.path.join(OUTPUT_DIR, "captured_frames.zip"))
362
  logs_zip = zip_directory(FLIGHT_LOG_DIR, os.path.join(OUTPUT_DIR, "flight_logs.zip"))
363
 
 
 
 
364
  return (
365
  output_path,
366
  json.dumps(last_metrics, indent=2),
@@ -368,56 +366,8 @@ def process_video(video, resize_width=4000, resize_height=3000, frame_skip=5):
368
  detected_issues,
369
  chart_path,
370
  map_path,
371
- submission_json_path,
372
  images_zip,
373
  logs_zip,
374
  output_path # For video download
375
  )
376
-
377
- # Gradio interface
378
- with gr.Blocks(theme=gr.themes.Soft(primary_hue="orange")) as iface:
379
- gr.Markdown("# NHAI Road Defect Detection Dashboard")
380
- with gr.Row():
381
- with gr.Column(scale=3):
382
- video_input = gr.Video(label="Upload Video (12MP recommended for NHAI compliance)")
383
- width_slider = gr.Slider(320, 4000, value=4000, label="Output Width", step=1)
384
- height_slider = gr.Slider(240, 3000, value=3000, label="Output Height", step=1)
385
- skip_slider = gr.Slider(1, 10, value=5, label="Frame Skip", step=1)
386
- process_btn = gr.Button("Process Video", variant="primary")
387
- with gr.Column(scale=1):
388
- metrics_output = gr.Textbox(label="Detection Metrics", lines=5, interactive=False)
389
- with gr.Row():
390
- video_output = gr.Video(label="Processed Video")
391
- issue_gallery = gr.Gallery(label="Detected Issues", columns=4, height="auto", object_fit="contain")
392
- with gr.Row():
393
- chart_output = gr.Image(label="Detection Trend")
394
- map_output = gr.Image(label="Issue Locations Map")
395
- with gr.Row():
396
- logs_output = gr.Textbox(label="Logs", lines=5, interactive=False)
397
- with gr.Row():
398
- gr.Markdown("## Download Results")
399
- with gr.Row():
400
- json_download = gr.File(label="Download Data Lake JSON")
401
- images_zip_download = gr.File(label="Download Geotagged Images (ZIP)")
402
- logs_zip_download = gr.File(label="Download Flight Logs (ZIP)")
403
- video_download = gr.File(label="Download Processed Video")
404
-
405
- process_btn.click(
406
- fn=process_video,
407
- inputs=[video_input, width_slider, height_slider, skip_slider],
408
- outputs=[
409
- video_output,
410
- metrics_output,
411
- logs_output,
412
- issue_gallery,
413
- chart_output,
414
- map_output,
415
- json_download,
416
- images_zip_download,
417
- logs_zip_download,
418
- video_download
419
- ]
420
- )
421
-
422
- if __name__ == "__main__":
423
- iface.launch()
 
15
  import time
16
  import piexif
17
  import zipfile
18
+ from fpdf import FPDF # PDF generation
19
 
20
  # Set YOLO config directory
21
  os.environ["YOLO_CONFIG_DIR"] = "/tmp/Ultralytics"
 
57
  print(f"CUDA available: {torch.cuda.is_available()}")
58
 
59
  # Load custom YOLO model
60
+ device = "cpu" # Force the use of CPU
61
  print(f"Using device: {device}")
62
+ model = YOLO('./data/best.pt').to(device) # Model is now moved to the CPU
63
+ if device == "cpu": # Optional check, not strictly needed but can help to ensure
64
+ model.float() # Ensure model is running on the CPU
65
  print(f"Model classes: {model.names}")
66
 
67
+ # Generate PDF report
68
+ def generate_pdf_report(log_entries, detected_issues, chart_path, map_path, metrics):
69
+ pdf = FPDF()
70
+ pdf.set_auto_page_break(auto=True, margin=15)
71
+ pdf.add_page()
72
+
73
+ # Add Title
74
+ pdf.set_font("Arial", "B", 16)
75
+ pdf.cell(200, 10, txt="Road Defect Detection Report", ln=True, align="C")
76
+ pdf.ln(10)
77
+
78
+ # Add Log Entries
79
+ pdf.set_font("Arial", size=12)
80
+ pdf.cell(200, 10, txt="Log Entries:", ln=True)
81
+ pdf.multi_cell(0, 10, txt="\n".join(log_entries))
82
+ pdf.ln(5)
83
+
84
+ # Add Detected Issues
85
+ pdf.cell(200, 10, txt="Detected Issues:", ln=True)
86
+ for issue in detected_issues:
87
+ pdf.cell(200, 10, txt=issue, ln=True)
88
+ pdf.ln(5)
89
+
90
+ # Add Metrics
91
+ pdf.cell(200, 10, txt="Detection Metrics:", ln=True)
92
+ pdf.multi_cell(0, 10, txt=json.dumps(metrics, indent=2))
93
+ pdf.ln(5)
94
+
95
+ # Add Chart Image
96
+ if chart_path:
97
+ pdf.cell(200, 10, txt="Detection Trend Chart:", ln=True)
98
+ pdf.image(chart_path, x=10, y=pdf.get_y(), w=180)
99
+ pdf.ln(80)
100
+
101
+ # Add Map Image
102
+ if map_path:
103
+ pdf.cell(200, 10, txt="Issue Locations Map:", ln=True)
104
+ pdf.image(map_path, x=10, y=pdf.get_y(), w=180)
105
+ pdf.ln(80)
106
+
107
+ # Save PDF
108
+ pdf_output_path = os.path.join(OUTPUT_DIR, "detection_report.pdf")
109
+ pdf.output(pdf_output_path)
110
+ return pdf_output_path
111
+
112
  def zip_directory(folder_path: str, zip_path: str) -> str:
113
  """Zip all files in a directory."""
114
  try:
 
136
  plt.close()
137
  return map_path
138
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
139
  def generate_line_chart() -> Optional[str]:
140
  if not detected_counts:
141
  return None
 
356
  images_zip = zip_directory(CAPTURED_FRAMES_DIR, os.path.join(OUTPUT_DIR, "captured_frames.zip"))
357
  logs_zip = zip_directory(FLIGHT_LOG_DIR, os.path.join(OUTPUT_DIR, "flight_logs.zip"))
358
 
359
+ # Generate PDF report
360
+ pdf_path = generate_pdf_report(log_entries, detected_issues, chart_path, map_path, last_metrics)
361
+
362
  return (
363
  output_path,
364
  json.dumps(last_metrics, indent=2),
 
366
  detected_issues,
367
  chart_path,
368
  map_path,
369
+ pdf_path, # PDF report path
370
  images_zip,
371
  logs_zip,
372
  output_path # For video download
373
  )