nagasurendra commited on
Commit
c34a41a
·
verified ·
1 Parent(s): cc741a6

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +224 -123
app.py CHANGED
@@ -163,144 +163,244 @@ def generate_report(
163
  io_times: List[float]
164
  ) -> str:
165
  log_entries.append("Generating report...")
166
- report_path = os.path.join(OUTPUT_DIR, f"drone_analysis_report_{datetime.now().strftime('%Y%m%d_%H%M%S')}.md")
167
  timestamp = datetime.now().strftime('%Y%m%d_%H%M%S')
168
- report_content = [
169
- "# NHAI Drone Survey Analysis Report",
170
- "",
171
- "## Project Details",
172
- "- Project Name: NH-44 Delhi-Hyderabad Section (Package XYZ)",
173
- "- Highway Section: Km 100 to Km 150",
174
- "- State: Telangana",
175
- "- Region: South",
176
- f"- Survey Date: {datetime.now().strftime('%Y-%m-%d')}",
177
- "- Drone Service Provider: ABC Drone Services Pvt. Ltd.",
178
- "- Technology Service Provider: XYZ AI Analytics Ltd.",
179
- f"- Work Order Reference: Data Lake WO-{datetime.now().strftime('%Y-%m-%d')}-XYZ",
180
- "- Report Prepared By: Nagasurendra, Data Analyst",
181
- f"- Report Date: {datetime.now().strftime('%Y-%m-%d')}",
182
- "",
183
- "## 1. Introduction",
184
- "This report consolidates drone survey results for NH-44 (Km 100–150) under Operations & Maintenance, per NHAI Policy Circular No. 18.98/2024, detecting potholes and cracks using YOLOv8 for Monthly Progress Report integration.",
185
- "",
186
- "## 2. Drone Survey Metadata",
187
- "- Drone Speed: 5 m/s",
188
- "- Drone Height: 60 m",
189
- "- Camera Sensor: RGB, 12 MP",
190
- "- Recording Type: JPEG, 90° nadir",
191
- "- Image Overlap: 85%",
192
- "- Flight Pattern: Single lap, ROW centered",
193
- "- Geotagging: Enabled",
194
- "- Satellite Lock: 12 satellites",
195
- "- Terrain Follow Mode: Enabled",
196
- "",
197
- "## 3. Quality Check Results",
198
- f"- Resolution: 4000x3000 (12 MP)",
199
- "- Overlap: 85%",
200
- "- Camera Angle: 90° nadir",
201
- "- Drone Speed: ≤ 5 m/s",
202
- "- Geotagging: 100% compliant",
203
- "- QC Status: Passed",
204
- "",
205
- "## 4. AI/ML Analytics",
206
- f"- Total Frames Processed: {frame_count}",
207
- f"- Detection Frames: {detection_frame_count} ({detection_frame_count/frame_count*100:.2f}%)",
208
- f"- Total Detections: {metrics['total_detections']}",
209
- " - Breakdown:"
210
- ]
211
 
 
 
212
  for item in metrics.get("items", []):
213
  percentage = (item["count"] / metrics["total_detections"] * 100) if metrics["total_detections"] > 0 else 0
214
- report_content.append(f" - {item['type']}: {item['count']} ({percentage:.2f}%)")
215
- report_content.extend([
216
- f"- Processing Time: {total_time:.2f} seconds",
217
- f"- Average Frame Time: {sum(frame_times)/len(frame_times):.2f} ms" if frame_times else "- Average Frame Time: N/A",
218
- f"- Average Resize Time: {sum(resize_times)/len(resize_times):.2f} ms" if resize_times else "- Average Resize Time: N/A",
219
- f"- Average Inference Time: {sum(inference_times)/len(inference_times):.2f} ms" if inference_times else "- Average Inference Time: N/A",
220
- f"- Average I/O Time: {sum(io_times)/len(io_times):.2f} ms" if io_times else "- Average I/O Time: N/A",
221
- f"- Timestamp: {metrics.get('timestamp', 'N/A')}",
222
- "- Summary: Potholes and cracks detected in high-traffic segments.",
223
- "",
224
- "## 5. Output File Structure",
225
- "- ZIP file contains:",
226
- " - `drone_analysis_report_<timestamp>.md`: This report",
227
- " - `outputs/processed_output.mp4`: Processed video with annotations",
228
- " - `outputs/chart_<timestamp>.png`: Detection trend chart",
229
- " - `outputs/map_<timestamp>.png`: Issue locations map",
230
- " - `captured_frames/detected_<frame>.jpg`: Geotagged images for detected issues",
231
- " - `flight_logs/flight_log_<frame>.csv`: Flight logs matching image frames",
232
- "- Note: Images and logs share frame numbers (e.g., `detected_000001.jpg` corresponds to `flight_log_000001.csv`).",
233
- "",
234
- "## 6. Geotagged Images",
235
- f"- Total Images: {len(detected_issues)}",
236
- f"- Storage: Data Lake `/project_xyz/images/{datetime.now().strftime('%Y-%m-%d')}`",
237
- "",
238
- "| Frame | Issue Type | GPS (Lat, Lon) | Timestamp | Confidence | Image Path |",
239
- "|-------|------------|----------------|-----------|------------|------------|"
240
- ])
241
 
 
 
242
  for detection in all_detections[:100]:
243
- report_content.append(
244
- f"| {detection['frame']:06d} | {detection['label']} | ({detection['gps'][0]:.6f}, {detection['gps'][1]:.6f}) | {detection['timestamp']} | {detection['conf']:.2f} | captured_frames/{os.path.basename(detection['path'])} |"
 
 
 
 
245
  )
246
 
247
- report_content.extend([
248
- "",
249
- "## 7. Flight Logs",
250
- f"- Total Logs: {len(detected_issues)}",
251
- f"- Storage: Data Lake `/project_xyz/flight_logs/{datetime.now().strftime('%Y-%m-%d')}`",
252
- "",
253
- "| Frame | Timestamp | Latitude | Longitude | Speed (m/s) | Satellites | Altitude (m) | Log Path |",
254
- "|-------|-----------|----------|-----------|-------------|------------|--------------|----------|"
255
- ])
256
-
257
  for detection in all_detections[:100]:
258
  log_path = f"flight_logs/flight_log_{detection['frame']:06d}.csv"
259
- report_content.append(
260
- f"| {detection['frame']:06d} | {detection['timestamp']} | {detection['gps'][0]:.6f} | {detection['gps'][1]:.6f} | 5.0 | 12 | 60 | {log_path} |"
 
 
261
  )
262
 
263
- report_content.extend([
264
- "",
265
- "## 8. Processed Video",
266
- f"- Path: outputs/processed_output.mp4",
267
- f"- Frames: {output_frames}",
268
- f"- FPS: {output_fps:.2f}",
269
- f"- Duration: {output_duration:.2f} seconds",
270
- "",
271
- "## 9. Visualizations",
272
- f"- Detection Trend Chart: outputs/chart_{timestamp}.png",
273
- f"- Issue Locations Map: outputs/map_{timestamp}.png",
274
- "",
275
- "## 10. Processing Timestamps",
276
- f"- Total Processing Time: {total_time:.2f} seconds",
277
- "- Log Entries (Last 10):"
278
- ])
279
-
280
  for entry in log_entries[-10:]:
281
- report_content.append(f" - {entry}")
282
-
283
- report_content.extend([
284
- "",
285
- "## 11. Stakeholder Validation",
286
- "- AE/IE Comments: [Pending]",
287
- "- PD/RO Comments: [Pending]",
288
- "",
289
- "## 12. Recommendations",
290
- "- Repair potholes in high-traffic segments.",
291
- "- Seal cracks to prevent degradation.",
292
- "- Schedule follow-up survey.",
293
- "",
294
- "## 13. Data Lake References",
295
- f"- Images: `/project_xyz/images/{datetime.now().strftime('%Y-%m-%d')}`",
296
- f"- Flight Logs: `/project_xyz/flight_logs/{datetime.now().strftime('%Y-%m-%d')}`",
297
- f"- Video: `/project_xyz/videos/processed_output_{datetime.now().strftime('%Y%m%d')}.mp4`",
298
- f"- DAMS Dashboard: `/project_xyz/dams/{datetime.now().strftime('%Y-%m-%d')}`"
299
- ])
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
300
 
301
  try:
302
  with open(report_path, 'w') as f:
303
- f.write("\n".join(report_content))
304
  log_entries.append(f"Report saved: {report_path}")
305
  return report_path
306
  except Exception as e:
@@ -415,6 +515,7 @@ def process_video(video, resize_width=4000, resize_height=3000, frame_skip=5):
415
 
416
  io_times.append((time.time() - io_start) * 1000)
417
 
 
418
  out.write(annotated_frame)
419
  output_frame_count += 1
420
  last_annotated_frame = annotated_frame
@@ -504,7 +605,7 @@ with gr.Blocks(theme=gr.themes.Soft(primary_hue="orange")) as iface:
504
  video_output = gr.Video(label="Processed Video")
505
  issue_gallery = gr.Gallery(label="Detected Issues", columns=4, height="auto", object_fit="contain")
506
  with gr.Row():
507
- chart_output = gr.Image(label="Detection Trend")
508
  map_output = gr.Image(label="Issue Locations Map")
509
  with gr.Row():
510
  logs_output = gr.Textbox(label="Logs", lines=5, interactive=False)
 
163
  io_times: List[float]
164
  ) -> str:
165
  log_entries.append("Generating report...")
166
+ report_path = os.path.join(OUTPUT_DIR, f"drone_analysis_report_{datetime.now().strftime('%Y%m%d_%H%M%S')}.tex")
167
  timestamp = datetime.now().strftime('%Y%m%d_%H%M%S')
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
168
 
169
+ # Prepare items for the breakdown
170
+ items = []
171
  for item in metrics.get("items", []):
172
  percentage = (item["count"] / metrics["total_detections"] * 100) if metrics["total_detections"] > 0 else 0
173
+ items.append(f"\\item {item['type']}: {item['count']} ({percentage:.2f}\\%)")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
174
 
175
+ # Prepare image rows with embedded images
176
+ image_rows = []
177
  for detection in all_detections[:100]:
178
+ image_basename = os.path.basename(detection['path'])
179
+ image_rows.append(
180
+ f"{detection['frame']:06d} & {detection['label']} & "
181
+ f"({detection['gps'][0]:.6f}, {detection['gps'][1]:.6f}) & "
182
+ f"{detection['timestamp']} & {detection['conf']:.2f} & "
183
+ f"\\includegraphics[width=4cm, height=3cm, keepaspectratio]{{{image_basename}}} \\\\"
184
  )
185
 
186
+ # Prepare flight log rows
187
+ log_rows = []
 
 
 
 
 
 
 
 
188
  for detection in all_detections[:100]:
189
  log_path = f"flight_logs/flight_log_{detection['frame']:06d}.csv"
190
+ log_rows.append(
191
+ f"{detection['frame']:06d} & {detection['timestamp']} & "
192
+ f"{detection['gps'][0]:.6f} & {detection['gps'][1]:.6f} & "
193
+ f"5.0 & 12 & 60 & \\texttt{{{log_path}}} \\\\"
194
  )
195
 
196
+ # Prepare log entries
197
+ log_entries_str = []
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
198
  for entry in log_entries[-10:]:
199
+ log_entries_str.append(f"\\item {entry}")
200
+
201
+ # Calculate average times
202
+ avg_frame_time = sum(frame_times) / len(frame_times) if frame_times else 0
203
+ avg_resize_time = sum(resize_times) / len(resize_times) if resize_times else 0
204
+ avg_inference_time = sum(inference_times) / len(inference_times) if inference_times else 0
205
+ avg_io_time = sum(io_times) / len(io_times) if io_times else 0
206
+
207
+ # LaTeX template
208
+ latex_template = r"""
209
+ \documentclass[a4paper,12pt]{article}
210
+ \usepackage[utf8]{inputenc}
211
+ \usepackage[T1]{fontenc}
212
+ \usepackage{geometry}
213
+ \geometry{margin=1in}
214
+ \usepackage{graphicx}
215
+ \usepackage{booktabs}
216
+ \usepackage{longtable}
217
+ \usepackage{hyperref}
218
+ \usepackage{xcolor}
219
+ \usepackage{parskip}
220
+ \setlength{\parskip}{0.5em}
221
+ \usepackage{noto}
222
+ \graphicspath{{./captured_frames/}}
223
+
224
+ \begin{document}
225
+
226
+ % Title and project details
227
+ \section*{NHAI Drone Survey Analysis Report}
228
+
229
+ \subsection*{Project Details}
230
+ \begin{itemize}
231
+ \item \textbf{Project Name:} NH-44 Delhi-Hyderabad Section (Package XYZ)
232
+ \item \textbf{Highway Section:} Km 100 to Km 150
233
+ \item \textbf{State:} Telangana
234
+ \item \textbf{Region:} South
235
+ \item \textbf{Survey Date:} \today
236
+ \item \textbf{Drone Service Provider:} ABC Drone Services Pvt. Ltd.
237
+ \item \textbf{Technology Service Provider:} XYZ AI Analytics Ltd.
238
+ \item \textbf{Work Order Reference:} Data Lake WO-\today-XYZ
239
+ \item \textbf{Report Prepared By:} Nagasurendra, Data Analyst
240
+ \item \textbf{Report Date:} \today
241
+ \end{itemize}
242
+
243
+ \section{Introduction}
244
+ This report consolidates drone survey results for NH-44 (Km 100--150) under Operations \& Maintenance, per NHAI Policy Circular No. 18.98/2024, detecting potholes and cracks using YOLOv8 for Monthly Progress Report integration.
245
+
246
+ \section{Drone Survey Metadata}
247
+ \begin{itemize}
248
+ \item \textbf{Drone Speed:} 5 m/s
249
+ \item \textbf{Drone Height:} 60 m
250
+ \item \textbf{Camera Sensor:} RGB, 12 MP
251
+ \item \textbf{Recording Type:} JPEG, 90° nadir
252
+ \item \textbf{Image Overlap:} 85\%
253
+ \item \textbf{Flight Pattern:} Single lap, ROW centered
254
+ \item \textbf{Geotagging:} Enabled
255
+ \item \textbf{Satellite Lock:} 12 satellites
256
+ \item \textbf{Terrain Follow Mode:} Enabled
257
+ \end{itemize}
258
+
259
+ \section{Quality Check Results}
260
+ \begin{itemize}
261
+ \item \textbf{Resolution:} 4000x3000 (12 MP)
262
+ \item \textbf{Overlap:} 85\%
263
+ \item \textbf{Camera Angle:} 90° nadir
264
+ \item \textbf{Drone Speed:} $\leq$ 5 m/s
265
+ \item \textbf{Geotagging:} 100\% compliant
266
+ \item \textbf{QC Status:} Passed
267
+ \end{itemize}
268
+
269
+ \section{AI/ML Analytics}
270
+ \begin{itemize}
271
+ \item \textbf{Total Frames Processed:} {frame_count}
272
+ \item \textbf{Detection Frames:} {detection_frame_count} ({detection_percentage:.2f}\%)
273
+ \item \textbf{Total Detections:} {total_detections}
274
+ \item \textbf{Breakdown:}
275
+ \begin{itemize}
276
+ {items}
277
+ \end{itemize}
278
+ \item \textbf{Processing Time:} {total_time:.2f} seconds
279
+ \item \textbf{Average Frame Time:} {avg_frame_time:.2f} ms
280
+ \item \textbf{Average Resize Time:} {avg_resize_time:.2f} ms
281
+ \item \textbf{Average Inference Time:} {avg_inference_time:.2f} ms
282
+ \item \textbf{Average I/O Time:} {avg_io_time:.2f} ms
283
+ \item \textbf{Timestamp:} {timestamp_str}
284
+ \item \textbf{Summary:} Potholes and cracks detected in high-traffic segments.
285
+ \end{itemize}
286
+
287
+ \section{Output File Structure}
288
+ \begin{itemize}
289
+ \item ZIP file contains:
290
+ \begin{itemize}
291
+ \item \texttt{drone_analysis_report_{timestamp}.pdf}: This report
292
+ \item \texttt{outputs/processed_output.mp4}: Processed video with annotations
293
+ \item \texttt{outputs/chart_{timestamp}.png}: Detection trend chart
294
+ \item \texttt{outputs/map_{timestamp}.png}: Issue locations map
295
+ \item \texttt{captured_frames/detected_<frame>.jpg}: Geotagged images for detected issues
296
+ \item \texttt{flight_logs/flight_log_<frame>.csv}: Flight logs matching image frames
297
+ \end{itemize}
298
+ \item \textbf{Note:} Images and logs share frame numbers (e.g., \texttt{detected_000001.jpg} corresponds to \texttt{flight_log_000001.csv}).
299
+ \end{itemize}
300
+
301
+ \section{Geotagged Images}
302
+ \begin{itemize}
303
+ \item \textbf{Total Images:} {total_images}
304
+ \item \textbf{Storage:} Data Lake \texttt{{/project_xyz/images/{date_str}}}
305
+ \end{itemize}
306
+
307
+ \begin{longtable}{c l c c c p{4cm}}
308
+ \toprule
309
+ \textbf{Frame} & \textbf{Issue Type} & \textbf{GPS (Lat, Lon)} & \textbf{Timestamp} & \textbf{Confidence} & \textbf{Image} \\
310
+ \midrule
311
+ \endhead
312
+ {image_rows}
313
+ \bottomrule
314
+ \end{longtable}
315
+
316
+ \section{Flight Logs}
317
+ \begin{itemize}
318
+ \item \textbf{Total Logs:} {total_logs}
319
+ \item \textbf{Storage:} Data Lake \texttt{{/project_xyz/flight_logs/{date_str}}}
320
+ \end{itemize}
321
+
322
+ \begin{longtable}{c c c c c c c l}
323
+ \toprule
324
+ \textbf{Frame} & \textbf{Timestamp} & \textbf{Latitude} & \textbf{Longitude} & \textbf{Speed (m/s)} & \textbf{Satellites} & \textbf{Altitude (m)} & \textbf{Log Path} \\
325
+ \midrule
326
+ \endhead
327
+ {log_rows}
328
+ \bottomrule
329
+ \end{longtable}
330
+
331
+ \section{Processed Video}
332
+ \begin{itemize}
333
+ \item \textbf{Path:} \texttt{outputs/processed_output.mp4}
334
+ \item \textbf{Frames:} {output_frames}
335
+ \item \textbf{FPS:} {output_fps:.2f}
336
+ \item \textbf{Duration:} {output_duration:.2f} seconds
337
+ \end{itemize}
338
+
339
+ \section{Visualizations}
340
+ \begin{itemize}
341
+ \item \textbf{Detection Trend Chart:} \texttt{outputs/chart_{timestamp}.png}
342
+ \item \textbf{Issue Locations Map:} \texttt{outputs/map_{timestamp}.png}
343
+ \end{itemize}
344
+
345
+ \section{Processing Timestamps}
346
+ \begin{itemize}
347
+ \item \textbf{Total Processing Time:} {total_time:.2f} seconds
348
+ \item \textbf{Log Entries (Last 10):}
349
+ \begin{itemize}
350
+ {log_entries}
351
+ \end{itemize}
352
+ \end{itemize}
353
+
354
+ \section{Stakeholder Validation}
355
+ \begin{itemize}
356
+ \item \textbf{AE/IE Comments:} [Pending]
357
+ \item \textbf{PD/RO Comments:} [Pending]
358
+ \end{itemize}
359
+
360
+ \section{Recommendations}
361
+ \begin{itemize}
362
+ \item Repair potholes in high-traffic segments.
363
+ \item Seal cracks to prevent degradation.
364
+ \item Schedule follow-up survey.
365
+ \end{itemize}
366
+
367
+ \section{Data Lake References}
368
+ \begin{itemize}
369
+ \item \textbf{Images:} \texttt{{/project_xyz/images/{date_str}}}
370
+ \item \textbf{Flight Logs:} \texttt{{/project_xyz/flight_logs/{date_str}}}
371
+ \item \textbf{Video:} \texttt{{/project_xyz/videos/processed_output_{date_str_no_dash}.mp4}}
372
+ \item \textbf{DAMS Dashboard:} \texttt{{/project_xyz/dams/{date_str}}}
373
+ \end{itemize}
374
+
375
+ \end{document}
376
+ """
377
+
378
+ # Format the LaTeX template
379
+ report_content = latex_template.format(
380
+ frame_count=frame_count,
381
+ detection_frame_count=detection_frame_count,
382
+ detection_percentage=(detection_frame_count / frame_count * 100) if frame_count > 0 else 0,
383
+ total_detections=metrics['total_detections'],
384
+ items="\n ".join(items),
385
+ total_time=total_time,
386
+ avg_frame_time=avg_frame_time,
387
+ avg_resize_time=avg_resize_time,
388
+ avg_inference_time=avg_inference_time,
389
+ avg_io_time=avg_io_time,
390
+ timestamp_str=metrics.get('timestamp', 'N/A'),
391
+ timestamp=timestamp,
392
+ total_images=len(detected_issues),
393
+ total_logs=len(detected_issues),
394
+ date_str=datetime.now().strftime('%Y-%m-%d'),
395
+ date_str_no_dash=datetime.now().strftime('%Y%m%d'),
396
+ image_rows="\n ".join(image_rows),
397
+ log_rows="\n ".join(log_rows),
398
+ log_entries="\n ".join(log_entries_str)
399
+ )
400
 
401
  try:
402
  with open(report_path, 'w') as f:
403
+ f.write(report_content)
404
  log_entries.append(f"Report saved: {report_path}")
405
  return report_path
406
  except Exception as e:
 
515
 
516
  io_times.append((time.time() - io_start) * 1000)
517
 
518
+ torrents
519
  out.write(annotated_frame)
520
  output_frame_count += 1
521
  last_annotated_frame = annotated_frame
 
605
  video_output = gr.Video(label="Processed Video")
606
  issue_gallery = gr.Gallery(label="Detected Issues", columns=4, height="auto", object_fit="contain")
607
  with gr.Row():
608
+ chart_output = gr.Image(label-gate="Detection Trend")
609
  map_output = gr.Image(label="Issue Locations Map")
610
  with gr.Row():
611
  logs_output = gr.Textbox(label="Logs", lines=5, interactive=False)