diff --git a/.gitignore b/.gitignore index 930d26950b4632e0728aa35b227445f7abe3484f..d541310bbac00b6161d56fa6b07298db446e764c 100644 --- a/.gitignore +++ b/.gitignore @@ -12,4 +12,7 @@ uploads/ /uploads/ -/node_modules/ \ No newline at end of file +/node_modules/ + +MisplaceAI/rules/migrations/0001_initial.py +MisplaceAI/rules/migrations/__pycache__/0001_initial.cpython-310.pyc diff --git a/MisplaceAI/process_misplaced_manager/models.py b/MisplaceAI/process_misplaced_manager/models.py index 0f074a108f8c177aa82c227e1e75a4fa28627123..e107bc62b1cc544fd61b61f764a5fec27a1cdf7d 100644 --- a/MisplaceAI/process_misplaced_manager/models.py +++ b/MisplaceAI/process_misplaced_manager/models.py @@ -9,15 +9,21 @@ class UploadedImage(models.Model): uploaded_at = models.DateTimeField(auto_now_add=True) user = models.ForeignKey(User, on_delete=models.CASCADE) + class UserVideoFramePreference(models.Model): user = models.OneToOneField(User, on_delete=models.CASCADE) - frame_interval = models.IntegerField(default=1) # interval in seconds + frame_interval = models.IntegerField(default=1) + frame_delay = models.IntegerField(default=1) + + def __str__(self): + return f'{self.user.username} - Frame Interval: {self.frame_interval}, Frame Delay: {self.frame_delay}' class UploadedVideo(models.Model): video = models.FileField(upload_to='videos/') uploaded_at = models.DateTimeField(auto_now_add=True) user = models.ForeignKey(User, on_delete=models.CASCADE) - user_video_frame_preference = models.ForeignKey(UserVideoFramePreference, on_delete=models.CASCADE, null=True, blank=True) + user_video_frame_preference = models.ForeignKey(UserVideoFramePreference, on_delete=models.SET_NULL, null=True) + class DailyDetectionLimit(models.Model): user = models.OneToOneField(User, on_delete=models.CASCADE) @@ -35,9 +41,12 @@ class DailyDetectionLimit(models.Model): def __str__(self): return f'{self.user.username} - Images: {self.image_detection_count}, Videos: {self.video_detection_count}' + class DetectionLimitSetting(models.Model): daily_image_limit = models.IntegerField(default=10) # Default limit for images daily_video_limit = models.IntegerField(default=5) # Default limit for videos def __str__(self): return f'Daily Limits - Images: {self.daily_image_limit}, Videos: {self.daily_video_limit}' + + diff --git a/MisplaceAI/process_misplaced_manager/serializers.py b/MisplaceAI/process_misplaced_manager/serializers.py index 393f30c4e48edf08130c71ecf208406ca9bc2985..7b7a8abaf00cc21db6e89c15250b0b21e59d9428 100644 --- a/MisplaceAI/process_misplaced_manager/serializers.py +++ b/MisplaceAI/process_misplaced_manager/serializers.py @@ -1,15 +1,19 @@ # MisplaceAI/process_misplaced_manager/serializers.py from rest_framework import serializers -from .models import UploadedImage, UploadedVideo +from .models import UploadedImage, UploadedVideo, UserVideoFramePreference + +class UserVideoFramePreferenceSerializer(serializers.ModelSerializer): + class Meta: + model = UserVideoFramePreference + fields = ['frame_interval', 'frame_delay'] class UploadedImageSerializer(serializers.ModelSerializer): class Meta: model = UploadedImage fields = ['id', 'image', 'uploaded_at', 'user'] - class UploadedVideoSerializer(serializers.ModelSerializer): class Meta: model = UploadedVideo - fields = ['id', 'video', 'uploaded_at', 'user', 'user_video_frame_preference'] \ No newline at end of file + fields = ['id', 'video', 'uploaded_at', 'user', 'user_video_frame_preference'] diff --git a/MisplaceAI/process_misplaced_manager/urls.py b/MisplaceAI/process_misplaced_manager/urls.py index 0b19a737837e0525c67d157d57d4220e7724640c..4b6d21ed4882fc5f6612268d299e1cc97d8e2d3a 100644 --- a/MisplaceAI/process_misplaced_manager/urls.py +++ b/MisplaceAI/process_misplaced_manager/urls.py @@ -5,7 +5,8 @@ from .views import ( UploadedImageViewSet, UploadedVideoViewSet, normal_detection, display_results, - display_video_results,upload_video, + display_video_results, + upload_video, download_image, delete_image, delete_video, @@ -32,11 +33,8 @@ urlpatterns = [ path('delete-image/<str:image_name>/', delete_image, name='delete_image_by_name'), path('delete-video/<str:video_name>/', delete_video, name='delete_video'), path('download_video/<str:file_path>/', download_media, name='download_media'), - path('daily-limits/', get_daily_limits, name='get_daily_limits'), path('set-daily-limits/', set_daily_limits, name='set_daily_limits'), path('check-daily-limit/', check_daily_limit, name='check_daily_limit'), - path('increment-detection/', increment_detection, name='increment_detection'), - ] diff --git a/MisplaceAI/process_misplaced_manager/views.py b/MisplaceAI/process_misplaced_manager/views.py index a3c7178a5c84757a91fb6d3bcddbd4d36ad4dc05..166bcf476bd0ae5ac51759763eb16d2dac06ef48 100644 --- a/MisplaceAI/process_misplaced_manager/views.py +++ b/MisplaceAI/process_misplaced_manager/views.py @@ -5,7 +5,7 @@ from rest_framework.decorators import api_view, permission_classes from rest_framework.permissions import IsAuthenticated, IsAdminUser from rest_framework.response import Response from django.shortcuts import get_object_or_404 -from .models import UploadedImage, UploadedVideo, UserVideoFramePreference,DetectionLimitSetting, DailyDetectionLimit +from .models import UploadedImage, UploadedVideo, UserVideoFramePreference, DetectionLimitSetting, DailyDetectionLimit from .serializers import UploadedImageSerializer, UploadedVideoSerializer from item_detector.utils import run_inference, load_model, create_category_index_from_labelmap from placement_rules.utils import PlacementRules @@ -17,7 +17,7 @@ from PIL import Image, ExifTags import logging import cv2 from django.conf import settings -from django.http import JsonResponse, HttpResponse, Http404 +from django.http import JsonResponse, HttpResponse, Http404 import numpy as np from moviepy.editor import VideoFileClip, ImageSequenceClip from .utils import increment_detection_count @@ -146,9 +146,11 @@ def upload_video(request): print("No video file provided in request") return Response({'error': 'No video file provided'}, status=status.HTTP_400_BAD_REQUEST) - frame_interval = int(request.data.get('frame_interval', 1)) + frame_interval = int(request.data.get('frames_jump', 1)) + frame_delay = int(request.data.get('frame_delay', 1)) user_video_frame_preference, created = UserVideoFramePreference.objects.get_or_create(user=request.user) user_video_frame_preference.frame_interval = frame_interval + user_video_frame_preference.frame_delay = frame_delay user_video_frame_preference.save() serializer = UploadedVideoSerializer(data={'video': request.FILES['video'], 'user': request.user.id, 'user_video_frame_preference': user_video_frame_preference.id}) @@ -168,11 +170,14 @@ def display_video_results(request, video_id): try: video = get_object_or_404(UploadedVideo, id=video_id) video_path = video.video.path + user_video_frame_preference = get_object_or_404(UserVideoFramePreference, user=video.user) + frame_interval = user_video_frame_preference.frame_interval + frame_delay = user_video_frame_preference.frame_delay print("Processing video at path:", video_path) - frame_interval = video.user_video_frame_preference.frame_interval if video.user_video_frame_preference else 1 - detected_objects, misplaced_objects, output_video_path = process_video_for_misplaced_objects(video_path, frame_interval) - + print(f"Frame interval: {frame_interval}, Frame delay: {frame_delay}") + detected_objects, misplaced_objects, output_video_path = process_video_for_misplaced_objects(video_path, frame_interval, frame_delay) + # Delete the original uploaded video if os.path.exists(video_path): os.remove(video_path) @@ -192,7 +197,7 @@ def display_video_results(request, video_id): return JsonResponse({'error': str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR) -def process_video_for_misplaced_objects(video_path, frame_interval): +def process_video_for_misplaced_objects(video_path, frame_interval, frame_delay): print("Starting object detection for video:", video_path) cap = cv2.VideoCapture(video_path) print("Video capture object created") @@ -246,9 +251,9 @@ def process_video_for_misplaced_objects(video_path, frame_interval): cap.release() - # Create a video with a 1-second delay between each frame + # Create a video with a specified delay between each frame output_video_path = os.path.join(settings.MEDIA_ROOT, 'videos', os.path.basename(video_path).replace('.mp4', '_annotated.mp4')) - annotated_clip = ImageSequenceClip([np.array(frame) for frame in annotated_frames], fps=1) + annotated_clip = ImageSequenceClip([np.array(frame) for frame in annotated_frames], fps=1/frame_delay) annotated_clip.write_videofile(output_video_path, codec='libx264', audio_codec='aac') print("Finished processing video:", output_video_path) @@ -370,8 +375,6 @@ def set_daily_limits(request): 'daily_video_limit': limit_setting.daily_video_limit }) - - @api_view(['GET']) @permission_classes([IsAuthenticated]) def check_daily_limit(request): diff --git a/MisplaceAI/rules/migrations/0001_initial.py b/MisplaceAI/rules/migrations/0001_initial.py index b569a06ea10df6e6f1f2301622ef44364a8e75c3..27aa9cf1c4ba8c44513b1906b336dad286e17065 100644 --- a/MisplaceAI/rules/migrations/0001_initial.py +++ b/MisplaceAI/rules/migrations/0001_initial.py @@ -1,4 +1,4 @@ -# Generated by Django 3.2 on 2024-06-25 20:00 +# Generated by Django 3.2 on 2024-07-05 11:15 from django.conf import settings from django.db import migrations, models diff --git a/MisplaceAI/rules/migrations/__pycache__/0001_initial.cpython-310.pyc b/MisplaceAI/rules/migrations/__pycache__/0001_initial.cpython-310.pyc index e717ee00d97b36956a3e9d972c6d89a8a5d84a4f..d7f18479c4fc837ff96dff18e6d87dad6e55cbe3 100644 Binary files a/MisplaceAI/rules/migrations/__pycache__/0001_initial.cpython-310.pyc and b/MisplaceAI/rules/migrations/__pycache__/0001_initial.cpython-310.pyc differ