rekotvd commited on
Commit
250504d
·
verified ·
1 Parent(s): f9d8a61

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +77 -116
app.py CHANGED
@@ -663,183 +663,145 @@ elif input_method == "Upload Image":
663
  # Updated code to convert frames to video file and display
664
  elif input_method == "Upload Video":
665
  uploaded_file = st.sidebar.file_uploader("Choose a video...", type=["mp4", "avi", "mov"])
666
-
667
  if uploaded_file is not None:
668
- # Save to temporary file
669
  tfile = tempfile.NamedTemporaryFile(delete=False, suffix='.mp4')
670
  tfile.write(uploaded_file.read())
671
  tfile_path = tfile.name
672
  tfile.close()
673
-
674
  # Process button
675
  if st.sidebar.button("Process Video"):
676
  try:
677
  cap = cv2.VideoCapture(tfile_path)
678
-
679
  if not cap.isOpened():
680
  st.error("Cannot open video file")
681
  else:
682
- # Get video info
683
  fps = cap.get(cv2.CAP_PROP_FPS)
684
  frame_count = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))
685
  frame_width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
686
  frame_height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
687
-
688
- # Store processing results
689
  processed_frames = []
690
  crash_frames = []
691
-
692
- # Process all frames first
693
  progress_bar = st.progress(0)
694
  status_text = st.empty()
695
-
696
  status_text.text(f"Analyzing video... (0/{frame_count} frames)")
 
697
  frame_number = 0
698
-
699
  while True:
700
  ret, frame = cap.read()
701
  if not ret:
702
  break
703
-
704
- # Process frame for detection
705
  st.session_state.total_detections += 1
706
  detection_result = detect_crash(frame)
707
-
708
- # Store processed frame and result
709
  processed_frames.append({
710
  "frame": detection_result["annotated_image"],
711
  "result": detection_result
712
  })
713
-
714
- # Track crash frames
715
  if detection_result["crash_detected"]:
716
  crash_frames.append({
717
  "frame_number": frame_number,
718
- "frame": frame.copy(), # Store original frame for analysis
719
  "detection_result": detection_result,
720
  "timestamp": time.time(),
721
  "severity": detection_result["severity"]
722
  })
723
-
724
- # Update progress
725
  frame_number += 1
726
  if frame_number % 5 == 0 or frame_number == frame_count:
727
- # Update the progress bar and text
728
  progress_value = min(frame_number / frame_count, 1.0)
729
  progress_bar.progress(progress_value)
730
  status_text.text(f"Analyzing video... ({frame_number}/{frame_count} frames)")
731
-
732
- # Close original video
733
  cap.release()
734
-
 
735
  status_text.text("Creating processed video...")
736
-
737
- # Create a temporary file in the system's temp directory
738
- timestamp = int(time.time())
739
- filename = f"processed_video_{timestamp}.mp4"
740
- temp_output_path = os.path.join(tempfile.gettempdir(), filename)
741
-
742
- # Create video writer
743
- fourcc = cv2.VideoWriter_fourcc(*'mp4v') # Use mp4v codec which is widely compatible
744
- out = cv2.VideoWriter(
745
- temp_output_path,
746
- fourcc,
747
- fps,
748
- (frame_width, frame_height)
749
- )
750
-
751
- # Write frames to video
752
- for frame_data in processed_frames:
753
- out.write(frame_data["frame"])
754
-
755
- # Release the writer
756
- out.release()
757
-
758
- # Verify file exists before proceeding
759
- if os.path.exists(temp_output_path) and os.path.getsize(temp_output_path) > 0:
760
- # Read the processed video into memory
761
- with open(temp_output_path, 'rb') as video_file:
762
- video_bytes = video_file.read()
763
-
764
- # Create a frame display interface
765
- display_option = st.radio(
766
- "Display Option",
767
- ["View Frames", "Download Video"],
768
- horizontal=True
769
- )
770
-
771
- if display_option == "View Frames":
772
- # Display frames with a slider
773
- st.write("Navigate through processed frames:")
774
- selected_frame = st.slider("Frame", 0, len(processed_frames)-1, 0)
775
- st.image(
776
- processed_frames[selected_frame]["frame"],
777
- channels="BGR",
778
- use_column_width=True,
779
- caption=f"Frame {selected_frame}"
780
- )
781
- else:
782
- # Provide a download button for the video
783
- st.download_button(
784
- label="Download Processed Video",
785
- data=video_bytes,
786
- file_name=filename,
787
- mime="video/mp4"
788
- )
789
-
790
- # Try to display the video directly as well
791
- try:
792
  st.video(video_bytes)
793
- except:
794
- st.info("Video preview not available. Please use the download button.")
795
-
796
- # Analysis complete, display results
797
- st.success(f"Video analysis complete. {len(processed_frames)} frames processed, {len(crash_frames)} crashes detected.")
798
- else:
799
- st.error(f"Failed to create video file at {temp_output_path}")
800
 
801
- # After video display, process the last detected crash (if any)
 
802
  if crash_frames:
803
- # Sort crash frames by frame number to find the latest
804
  crash_frames.sort(key=lambda x: x["frame_number"])
805
-
806
- # Get the last crash frame
807
  last_crash = crash_frames[-1]
808
-
809
- # Display the last crash frame
810
- frame_placeholder.image(last_crash["detection_result"]["annotated_image"], channels="BGR",
811
- caption=f"Last Detected Crash (Frame {last_crash['frame_number']})",
812
- use_column_width=True)
813
-
814
- # Now do the LLM analysis
 
815
  with st.spinner("Analyzing crash severity..."):
816
  crash_analysis = assess_crash_severity(last_crash["frame"], last_crash["detection_result"])
817
-
818
- # Set global variables
819
  crash_detected = True
820
  crash_severity = last_crash["severity"]
821
  last_crash_time = last_crash["timestamp"]
822
-
823
- # Update crash statistics
824
  st.session_state.total_crashes += len(crash_frames)
825
  severe_count = sum(1 for crash in crash_frames if crash["severity"].lower() == "severe")
826
  st.session_state.severe_crashes += severe_count
827
-
828
- # Update display with the last crash information
829
  update_info_display(custom_analysis=crash_analysis)
830
-
831
- # Get current location
832
  location = get_current_location()
833
-
834
- # Prepare crash data for alert
835
  crash_data = {
836
  "timestamp": datetime.fromtimestamp(last_crash_time).strftime('%Y-%m-%d %H:%M:%S'),
837
  "severity": crash_severity,
 
838
  "location": location,
 
839
  }
840
-
841
  success, message = send_crash_alert_twilio(crash_data)
842
-
843
  if success:
844
  st.session_state.alerts_sent += 1
845
  alert_status_placeholder.success(f"Alert sent: {message}")
@@ -847,23 +809,22 @@ elif input_method == "Upload Video":
847
  alert_status_placeholder.error(f"Alert failed: {message}")
848
  else:
849
  st.info("No crashes detected in this video.")
850
-
851
- # Clean up temporary file
852
  try:
853
- if os.path.exists(temp_output_path):
854
- os.remove(temp_output_path)
855
  except:
856
  pass
 
857
  except Exception as e:
858
  st.error(f"Error processing video: {e}")
859
- st.exception(e) # Show the full traceback for debugging
860
  finally:
861
- # Clean up input file
862
  try:
863
  if os.path.exists(tfile_path):
864
  os.remove(tfile_path)
865
  except:
866
  pass
 
867
  st.markdown("---")
868
  col1, col2, col3, col4 = st.columns(4)
869
 
 
663
  # Updated code to convert frames to video file and display
664
  elif input_method == "Upload Video":
665
  uploaded_file = st.sidebar.file_uploader("Choose a video...", type=["mp4", "avi", "mov"])
666
+
667
  if uploaded_file is not None:
668
+ # Save uploaded file temporarily
669
  tfile = tempfile.NamedTemporaryFile(delete=False, suffix='.mp4')
670
  tfile.write(uploaded_file.read())
671
  tfile_path = tfile.name
672
  tfile.close()
673
+
674
  # Process button
675
  if st.sidebar.button("Process Video"):
676
  try:
677
  cap = cv2.VideoCapture(tfile_path)
678
+
679
  if not cap.isOpened():
680
  st.error("Cannot open video file")
681
  else:
 
682
  fps = cap.get(cv2.CAP_PROP_FPS)
683
  frame_count = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))
684
  frame_width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
685
  frame_height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
686
+
 
687
  processed_frames = []
688
  crash_frames = []
689
+
 
690
  progress_bar = st.progress(0)
691
  status_text = st.empty()
 
692
  status_text.text(f"Analyzing video... (0/{frame_count} frames)")
693
+
694
  frame_number = 0
 
695
  while True:
696
  ret, frame = cap.read()
697
  if not ret:
698
  break
699
+
 
700
  st.session_state.total_detections += 1
701
  detection_result = detect_crash(frame)
702
+
 
703
  processed_frames.append({
704
  "frame": detection_result["annotated_image"],
705
  "result": detection_result
706
  })
707
+
 
708
  if detection_result["crash_detected"]:
709
  crash_frames.append({
710
  "frame_number": frame_number,
711
+ "frame": frame.copy(),
712
  "detection_result": detection_result,
713
  "timestamp": time.time(),
714
  "severity": detection_result["severity"]
715
  })
716
+
 
717
  frame_number += 1
718
  if frame_number % 5 == 0 or frame_number == frame_count:
 
719
  progress_value = min(frame_number / frame_count, 1.0)
720
  progress_bar.progress(progress_value)
721
  status_text.text(f"Analyzing video... ({frame_number}/{frame_count} frames)")
722
+
 
723
  cap.release()
724
+
725
+ # Write processed frames to a new video file
726
  status_text.text("Creating processed video...")
727
+ output_video_path = tempfile.NamedTemporaryFile(delete=False, suffix='.mp4').name
728
+
729
+ if processed_frames:
730
+ first_frame = processed_frames[0]["frame"]
731
+ h, w = first_frame.shape[:2]
732
+
733
+ fourcc = cv2.VideoWriter_fourcc(*'mp4v') # fallback codec
734
+ out = cv2.VideoWriter(output_video_path, fourcc, fps, (w, h))
735
+
736
+ for frame_data in processed_frames:
737
+ out.write(frame_data["frame"])
738
+
739
+ out.release()
740
+ time.sleep(0.5) # ensure video file is flushed
741
+
742
+ try:
743
+ with open(output_video_path, 'rb') as video_file:
744
+ video_bytes = video_file.read()
745
+
746
+ status_text.empty()
747
+ progress_bar.empty()
748
+
749
+ if "huggingface.co" in os.environ.get("HOST", "") or "SPACE_ID" in os.environ:
750
+ # Display video using HTML for Hugging Face Spaces
751
+ video_base64 = base64.b64encode(video_bytes).decode("utf-8")
752
+ st.markdown(
753
+ f"""
754
+ <video width="100%" controls autoplay>
755
+ <source src="data:video/mp4;base64,{video_base64}" type="video/mp4">
756
+ Your browser does not support the video tag.
757
+ </video>
758
+ """,
759
+ unsafe_allow_html=True
760
+ )
761
+ else:
762
+ # Local streamlit display
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
763
  st.video(video_bytes)
764
+
765
+ except Exception as e:
766
+ st.error(f"Error displaying video: {e}")
 
 
 
 
767
 
768
+ st.success(f"Video analysis complete. {len(processed_frames)} frames processed, {len(crash_frames)} crashes detected.")
769
+
770
  if crash_frames:
 
771
  crash_frames.sort(key=lambda x: x["frame_number"])
 
 
772
  last_crash = crash_frames[-1]
773
+
774
+ frame_placeholder.image(
775
+ last_crash["detection_result"]["annotated_image"],
776
+ channels="BGR",
777
+ caption=f"Last Detected Crash (Frame {last_crash['frame_number']})",
778
+ use_column_width=True
779
+ )
780
+
781
  with st.spinner("Analyzing crash severity..."):
782
  crash_analysis = assess_crash_severity(last_crash["frame"], last_crash["detection_result"])
783
+
 
784
  crash_detected = True
785
  crash_severity = last_crash["severity"]
786
  last_crash_time = last_crash["timestamp"]
787
+
 
788
  st.session_state.total_crashes += len(crash_frames)
789
  severe_count = sum(1 for crash in crash_frames if crash["severity"].lower() == "severe")
790
  st.session_state.severe_crashes += severe_count
791
+
 
792
  update_info_display(custom_analysis=crash_analysis)
793
+
 
794
  location = get_current_location()
795
+
 
796
  crash_data = {
797
  "timestamp": datetime.fromtimestamp(last_crash_time).strftime('%Y-%m-%d %H:%M:%S'),
798
  "severity": crash_severity,
799
+ "analysis": crash_analysis,
800
  "location": location,
801
+ "raw_detection": last_crash["detection_result"]["raw_result"]
802
  }
803
+
804
  success, message = send_crash_alert_twilio(crash_data)
 
805
  if success:
806
  st.session_state.alerts_sent += 1
807
  alert_status_placeholder.success(f"Alert sent: {message}")
 
809
  alert_status_placeholder.error(f"Alert failed: {message}")
810
  else:
811
  st.info("No crashes detected in this video.")
812
+
 
813
  try:
814
+ os.remove(output_video_path)
 
815
  except:
816
  pass
817
+
818
  except Exception as e:
819
  st.error(f"Error processing video: {e}")
820
+ st.exception(e)
821
  finally:
 
822
  try:
823
  if os.path.exists(tfile_path):
824
  os.remove(tfile_path)
825
  except:
826
  pass
827
+
828
  st.markdown("---")
829
  col1, col2, col3, col4 = st.columns(4)
830