Haiss123 commited on
Commit
25e97a3
·
verified ·
1 Parent(s): fe17941

Update detection_api.py

Browse files
Files changed (1) hide show
  1. detection_api.py +33 -81
detection_api.py CHANGED
@@ -501,17 +501,17 @@ async def detect_video(
501
  file: UploadFile = File(..., description="Video file to analyze"),
502
  frame_skip: int = Form(5, ge=1, le=30, description="Process every Nth frame"),
503
  max_frames: int = Form(1000, ge=10, le=5000, description="Maximum frames to process"),
504
- enable_fight_detection: bool = Form(True, description="Enable fight detection"),
505
- save_processed: bool = Form(False, description="Save processed video with annotations")
506
  ):
507
  """
508
  Detect weapons (knife/dao/gun), fights, and NSFW content in videos
509
-
510
  Supports: MP4, AVI, MOV, MKV, WEBM, FLV, WMV
511
  Max size: 500MB
 
512
  """
513
  request_id = generate_request_id()
514
  start_time = datetime.now()
 
515
 
516
  try:
517
  # Validate file extension
@@ -528,7 +528,6 @@ async def detect_video(
528
  # Get file size
529
  file_size = upload_path.stat().st_size
530
  if not validate_file_size(file_size, config.MAX_VIDEO_SIZE):
531
- upload_path.unlink() # Delete the file
532
  raise HTTPException(
533
  status_code=400,
534
  detail=f"File too large. Maximum size: {config.MAX_VIDEO_SIZE / (1024 * 1024):.1f}MB"
@@ -557,19 +556,6 @@ async def detect_video(
557
  "size_mb": round(file_size / (1024 * 1024), 2)
558
  }
559
 
560
- # Prepare output video if requested
561
- out_writer = None
562
- processed_video_path = None
563
- if save_processed:
564
- processed_video_path = config.PROCESSED_DIR / "videos" / f"{request_id}_processed.mp4"
565
- fourcc = cv2.VideoWriter_fourcc(*'mp4v')
566
- out_writer = cv2.VideoWriter(
567
- str(processed_video_path),
568
- fourcc,
569
- fps,
570
- (width, height)
571
- )
572
-
573
  # Process video frames
574
  logger.info(f"Processing video {request_id}: {total_frames} frames, skip={frame_skip}")
575
 
@@ -636,21 +622,12 @@ async def detect_video(
636
  all_nsfw.extend(processed['nsfw'])
637
  all_fights.extend(processed['fights'])
638
 
639
- # Write annotated frame if saving video
640
- if out_writer and 'annotated_image' in result:
641
- out_writer.write(result['annotated_image'])
642
- elif out_writer:
643
- # Write original frame if no detections
644
- out_writer.write(frame)
645
-
646
  # Log progress every 100 frames
647
  if processed_count % 100 == 0:
648
  logger.info(f"Processed {processed_count} frames...")
649
 
650
  # Release resources
651
  cap.release()
652
- if out_writer:
653
- out_writer.release()
654
 
655
  # Calculate summary
656
  knife_count = sum(1 for w in all_weapons if 'knife' in w.class_name.lower() or 'dao' in w.class_name.lower())
@@ -689,11 +666,6 @@ async def detect_video(
689
  # Calculate processing time
690
  processing_time = (datetime.now() - start_time).total_seconds() * 1000
691
 
692
- # Prepare processed video URL if saved
693
- processed_video_url = None
694
- if save_processed and processed_video_path and processed_video_path.exists():
695
- processed_video_url = f"/results/videos/{request_id}_processed.mp4"
696
-
697
  return VideoDetectionResponse(
698
  success=True,
699
  request_id=request_id,
@@ -704,7 +676,7 @@ async def detect_video(
704
  summary=summary,
705
  risk_level=risk_level,
706
  action_required=(summary["total_detections"] > 0),
707
- processed_video_url=processed_video_url,
708
  processing_time_ms=processing_time
709
  )
710
 
@@ -718,67 +690,47 @@ async def detect_video(
718
  detail=f"Internal server error: {str(e)}"
719
  )
720
  finally:
721
- # Cleanup uploaded file if needed
722
- if upload_path.exists() and not save_processed:
723
  try:
724
  upload_path.unlink()
725
- except:
726
- pass
727
-
728
-
729
- @app.get("/results/images/{filename}")
730
- async def get_processed_image(filename: str):
731
- """Get processed/annotated image"""
732
- file_path = config.PROCESSED_DIR / "images" / filename
733
- if not file_path.exists():
734
- raise HTTPException(status_code=404, detail="File not found")
735
- return FileResponse(file_path)
736
-
737
-
738
- @app.get("/results/videos/{filename}")
739
- async def get_processed_video(filename: str):
740
- """Get processed/annotated video"""
741
- file_path = config.PROCESSED_DIR / "videos" / filename
742
- if not file_path.exists():
743
- raise HTTPException(status_code=404, detail="File not found")
744
- return FileResponse(file_path)
745
-
746
-
747
- @app.get("/health")
748
- async def health_check():
749
- """Health check endpoint"""
750
- if moderator:
751
- status = moderator.get_model_status()
752
- return {
753
- "status": "healthy",
754
- "models_loaded": True,
755
- "model_details": status
756
- }
757
- else:
758
- return {
759
- "status": "initializing",
760
- "models_loaded": False
761
- }
762
 
763
 
764
  @app.delete("/cleanup")
765
  async def cleanup_old_files(hours: int = 24):
766
- """Clean up old files from upload and results directories"""
767
  try:
768
  from datetime import timedelta
769
  cutoff_time = datetime.now() - timedelta(hours=hours)
770
 
771
  deleted_count = 0
 
 
772
  for directory in [config.UPLOAD_DIR, config.RESULTS_DIR, config.PROCESSED_DIR]:
773
- for subdir in ["images", "videos"]:
774
- path = directory / subdir
775
- if path.exists():
776
- for file in path.iterdir():
777
- if file.is_file():
778
- file_time = datetime.fromtimestamp(file.stat().st_mtime)
779
- if file_time < cutoff_time:
780
- file.unlink()
781
- deleted_count += 1
 
 
 
 
 
 
 
 
 
 
 
 
782
 
783
  return {
784
  "success": True,
 
501
  file: UploadFile = File(..., description="Video file to analyze"),
502
  frame_skip: int = Form(5, ge=1, le=30, description="Process every Nth frame"),
503
  max_frames: int = Form(1000, ge=10, le=5000, description="Maximum frames to process"),
504
+ enable_fight_detection: bool = Form(True, description="Enable fight detection")
 
505
  ):
506
  """
507
  Detect weapons (knife/dao/gun), fights, and NSFW content in videos
 
508
  Supports: MP4, AVI, MOV, MKV, WEBM, FLV, WMV
509
  Max size: 500MB
510
+ Note: Videos are automatically deleted after processing to save disk space
511
  """
512
  request_id = generate_request_id()
513
  start_time = datetime.now()
514
+ upload_path = None
515
 
516
  try:
517
  # Validate file extension
 
528
  # Get file size
529
  file_size = upload_path.stat().st_size
530
  if not validate_file_size(file_size, config.MAX_VIDEO_SIZE):
 
531
  raise HTTPException(
532
  status_code=400,
533
  detail=f"File too large. Maximum size: {config.MAX_VIDEO_SIZE / (1024 * 1024):.1f}MB"
 
556
  "size_mb": round(file_size / (1024 * 1024), 2)
557
  }
558
 
 
 
 
 
 
 
 
 
 
 
 
 
 
559
  # Process video frames
560
  logger.info(f"Processing video {request_id}: {total_frames} frames, skip={frame_skip}")
561
 
 
622
  all_nsfw.extend(processed['nsfw'])
623
  all_fights.extend(processed['fights'])
624
 
 
 
 
 
 
 
 
625
  # Log progress every 100 frames
626
  if processed_count % 100 == 0:
627
  logger.info(f"Processed {processed_count} frames...")
628
 
629
  # Release resources
630
  cap.release()
 
 
631
 
632
  # Calculate summary
633
  knife_count = sum(1 for w in all_weapons if 'knife' in w.class_name.lower() or 'dao' in w.class_name.lower())
 
666
  # Calculate processing time
667
  processing_time = (datetime.now() - start_time).total_seconds() * 1000
668
 
 
 
 
 
 
669
  return VideoDetectionResponse(
670
  success=True,
671
  request_id=request_id,
 
676
  summary=summary,
677
  risk_level=risk_level,
678
  action_required=(summary["total_detections"] > 0),
679
+ processed_video_url=None, # Always None since we don't save processed videos
680
  processing_time_ms=processing_time
681
  )
682
 
 
690
  detail=f"Internal server error: {str(e)}"
691
  )
692
  finally:
693
+ # Always cleanup uploaded video file after processing
694
+ if upload_path and upload_path.exists():
695
  try:
696
  upload_path.unlink()
697
+ logger.info(f"Cleaned up uploaded video: {upload_path}")
698
+ except Exception as cleanup_error:
699
+ logger.warning(f"Failed to cleanup uploaded video {upload_path}: {cleanup_error}")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
700
 
701
 
702
  @app.delete("/cleanup")
703
  async def cleanup_old_files(hours: int = 24):
704
+ """Clean up old files from upload and results directories (excluding videos from uploads as they are auto-deleted)"""
705
  try:
706
  from datetime import timedelta
707
  cutoff_time = datetime.now() - timedelta(hours=hours)
708
 
709
  deleted_count = 0
710
+
711
+ # Clean up images from all directories
712
  for directory in [config.UPLOAD_DIR, config.RESULTS_DIR, config.PROCESSED_DIR]:
713
+ images_path = directory / "images"
714
+ if images_path.exists():
715
+ for file in images_path.iterdir():
716
+ if file.is_file():
717
+ file_time = datetime.fromtimestamp(file.stat().st_mtime)
718
+ if file_time < cutoff_time:
719
+ file.unlink()
720
+ deleted_count += 1
721
+
722
+ # Clean up any remaining uploaded videos (should be rare since they're auto-deleted)
723
+ upload_videos_path = config.UPLOAD_DIR / "videos"
724
+ if upload_videos_path.exists():
725
+ for file in upload_videos_path.iterdir():
726
+ if file.is_file():
727
+ file_time = datetime.fromtimestamp(file.stat().st_mtime)
728
+ if file_time < cutoff_time:
729
+ file.unlink()
730
+ deleted_count += 1
731
+ logger.info(f"Cleaned up old uploaded video: {file}")
732
+
733
+ # Note: No need to clean processed videos since we don't save them anymore
734
 
735
  return {
736
  "success": True,