from django.http import HttpResponse, HttpResponseBadRequest, HttpResponseForbidden import cv2 import numpy as np import base64 import os from django.views.decorators.csrf import csrf_exempt import json import datetime from django.conf import settings from django.core.files.base import ContentFile from proctoring.models.image import Image from proctoring.models.imageTypes import ImageTypes from collections import Counter @csrf_exempt def CheckImage(request): if request.method != "POST": return HttpResponseForbidden("Only POST requests are allowed") try: data = json.loads(request.body) base64image = data.get("base64_image", "") shareId = data.get("shareId", "") isIdentityCheck = data.get("isIdentityCheck", False) except json.JSONDecodeError: return HttpResponseBadRequest("Invalid JSON data") if base64image == "" or shareId == "": return HttpResponseBadRequest("Missing parameters") # Get the current directory of the script # current_dir = os.path.dirname(os.path.abspath(__file__)) # Construct the full path to the AIModel directory # ai_model_dir = os.path.join(current_dir, "AIModel") # Load the YOLOv11 model model = settings.model # Remove any header if present (e.g., "data:image/jpeg;base64,") if "," in base64image: base64image = base64image.split(",")[1] # Decode base64 string to bytes img_bytes = base64.b64decode(base64image) # Convert bytes data to a 1D numpy array nparr = np.frombuffer(img_bytes, np.uint8) # Decode the image to a cv2 (BGR) image img = cv2.imdecode(nparr, cv2.IMREAD_COLOR) if img is None: raise ValueError("Could not decode the image. Please check your base64 string.") # Predict with the model results = model(img) # predict on an image # Create a list to store the labels of detections detection_labels = [] # myLables = ["book", "laptop", "cell phone", "person"] # Loop through each result (each result corresponds to one image, or one batch element) for result in results: # result.names is a dictionary mapping class IDs to their names # result.boxes.data is a tensor where each row is [x1, y1, x2, y2, confidence, class] for detection in result.boxes.data: # Extract the class id (the last element of the detection tensor) class_id = int(detection[-1]) # Use the class id to get the label name label = result.names[class_id] detection_labels.append(label) counts=Counter(detection_labels) personCount = counts["person"] prohibitedObjectsCount = counts["book"] + counts["laptop"] + counts["cell phone"] # imgHeight=int(img.shape[0]*0.37) # imgWidth=int(img.shape[1]*0.37) imgWidth=240 imgHeight=135 img = cv2.resize(img,(imgWidth,imgHeight),interpolation=cv2.INTER_AREA) outputImage = cv2.imencode(".jpg", img)[1].tobytes() # Construct the base save folder and filename save_folder = os.path.join("proctoring_images", shareId) filename = datetime.datetime.now().strftime("%Y-%m-%d_%H.%M.%S.jpg") # Determine folder and image type based on conditions if not isIdentityCheck: if personCount == 1 and prohibitedObjectsCount == 0: folder = os.path.join(save_folder, "passed") imageType = ImageTypes.Acceptable else: folder = os.path.join(save_folder, "failed") imageType = ImageTypes.AttentionRequired else: # For identity check, only save if one person and no prohibited objects if personCount == 1 and prohibitedObjectsCount == 0: folder = os.path.join(save_folder, "identity-check", "face") imageType = ImageTypes.FaceCheck else: # Skip saving if the identity-check conditions aren't met. folder = None # If a valid folder was determined, save the image if folder: filepath = os.path.join(folder, filename) content_file = ContentFile(outputImage, name=filename) saved_path = settings.s3_storage.save(filepath, content_file) image = Image( path=f"{settings.AWS_S3_ACCESS_DOMAIN}/{saved_path}", personCount=personCount, prohibitedObjectsCount=prohibitedObjectsCount, type=imageType, shareId=shareId ) image.save() response = { "personCount": personCount, "prohibitedObjectsCount": prohibitedObjectsCount, } return HttpResponse(json.dumps(response))