{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.6.6","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"none","dataSources":[{"sourceId":16880,"databundleVersionId":858837,"sourceType":"competition"}],"dockerImageVersionId":29844,"isInternetEnabled":false,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"import json\nimport os\nimport cv2\nimport numpy as np\nimport matplotlib.pyplot as plt\n\n# Set paths\nmetadata_file = \"/kaggle/input/deepfake-detection-challenge/train_sample_videos/metadata.json\"\ninput_path = \"/kaggle/input/deepfake-detection-challenge/train_sample_videos/\"\nface_save_path = \"/kaggle/working/\"  # Change save path to \"faces\"\n\n# Constants\nSTRIDE = 1.0\nFACE_SIZE = (128, 128)  # Resize cropped face to consistent dimensions\nMAX_IMAGE_SIZE = 1024\n\n# Load OpenCV face detector\nface_cascade = cv2.CascadeClassifier(cv2.data.haarcascades + \"haarcascade_frontalface_default.xml\")\n\ndef get_frames_from_video(video_file, stride=1.0):\n    \"\"\"Extract frames from video based on stride interval.\"\"\"\n    video = cv2.VideoCapture(video_file)\n    fps = video.get(cv2.CAP_PROP_FPS)\n    i = 0.\n    frames = []\n    frame_times = []\n\n    while video.isOpened():\n        ret, frame = video.read()\n        if ret:\n            frames.append(frame)\n            frame_times.append(i)\n            i += stride\n            video.set(1, round(i * fps))  # Move to next frame position\n        else:\n            video.release()\n            break\n    return frames, frame_times\n\ndef detect_and_crop_face(image):\n    \"\"\"Detect and crop the largest face in the image.\"\"\"\n    gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)\n    faces = face_cascade.detectMultiScale(gray, scaleFactor=1.2, minNeighbors=5, minSize=(30, 30))\n\n    if len(faces) == 0:\n        return None  # No face detected\n\n    # Select the largest detected face\n    x, y, w, h = sorted(faces, key=lambda f: f[2] * f[3], reverse=True)[0]\n    face_crop = image[y:y+h, x:x+w]  # Crop face region\n\n    # Resize face to maintain uniform size\n    face_crop = cv2.resize(face_crop, FACE_SIZE, interpolation=cv2.INTER_CUBIC)\n    return face_crop\n\ndef process_video(input_path, save_path, key, stride, max_image_size):\n    \"\"\"Extract frames, detect faces, crop, and save cropped faces.\"\"\"\n    video_file = os.path.join(input_path, key)\n    frames, frame_times = get_frames_from_video(video_file, stride)\n\n    file_name, _ = key.split(\".\")\n    face_folder = os.path.join(save_path, file_name)\n\n    if not os.path.isdir(face_folder):\n        os.makedirs(face_folder)\n\n    for frame, frame_time in zip(frames, frame_times):\n        face = detect_and_crop_face(frame)\n\n        if face is not None:\n            image_name = str(round(frame_time, 3)).replace(\".\", \"_\")\n            cv2.imwrite(os.path.join(face_folder, f\"{image_name}.jpg\"), face)  # Save cropped face\n\n# Load metadata\nwith open(metadata_file) as json_file:\n    metadata = json.load(json_file)\n\n# Process first video\nkey = list(metadata.keys())[0]\nprocess_video(input_path, face_save_path, key, STRIDE, MAX_IMAGE_SIZE)\n\n# Compute storage efficiency\ndef get_folder_size(path):\n    total_size = sum(os.path.getsize(os.path.join(dirpath, f)) for dirpath, _, filenames in os.walk(path) for f in filenames if not os.path.islink(os.path.join(dirpath, f)))\n    return total_size\n\nvideo_size = os.path.getsize(os.path.join(input_path, key))\nfaces_folder = os.path.join(face_save_path, key.split(\".\")[0])\ntotal_faces_size = get_folder_size(faces_folder)\n\n# Print storage comparison\nprint(f\"Video file size: {video_size}\")\nprint(f\"Total extracted face images size: {total_faces_size}\")\nprint(f\"Compression Ratio: {video_size / total_faces_size:.4f}\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-04-30T09:18:03.024213Z","iopub.execute_input":"2025-04-30T09:18:03.024523Z","iopub.status.idle":"2025-04-30T09:18:13.907289Z","shell.execute_reply.started":"2025-04-30T09:18:03.024470Z","shell.execute_reply":"2025-04-30T09:18:13.906467Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import matplotlib.pyplot as plt\nimport cv2\nimport os\n\ndef print_cropped_faces(faces_folder, max_faces=10):\n    \"\"\"Displays cropped face images in a grid layout, similar to original frames.\"\"\"\n    face_images = sorted(os.listdir(faces_folder))[:max_faces]  # Limit number of displayed faces\n\n    plt.figure(figsize=(20, 10))\n    columns = 5  # Number of columns in the grid\n    for i, face_file in enumerate(face_images):\n        img = cv2.imread(os.path.join(faces_folder, face_file))  # Load face image\n        img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)  # Convert color format\n\n        plt.subplot(len(face_images) // columns + 1, columns, i + 1)\n        plt.imshow(img)\n        plt.axis('off')\n        plt.title(f\"Frame {face_file.split('.')[0].replace('_', '.')}s\")  # Show frame time\n\n    plt.tight_layout()\n    plt.show()\n\n# Example usage\nfaces_folder = \"/kaggle/working/aagfhgtpmv\"  # Replace with actual folder path\nprint_cropped_faces(faces_folder)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-04-30T09:18:21.016347Z","iopub.execute_input":"2025-04-30T09:18:21.016704Z","iopub.status.idle":"2025-04-30T09:18:22.042520Z","shell.execute_reply.started":"2025-04-30T09:18:21.016655Z","shell.execute_reply":"2025-04-30T09:18:22.041643Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import matplotlib.pyplot as plt\nimport cv2\nimport os\n\ndef print_cropped_faces(faces_folder, max_faces=10):\n    \"\"\"Displays cropped face images in a grid and prints X/Y axis values.\"\"\"\n    face_images = sorted(os.listdir(faces_folder))[:max_faces]  # Limit number of displayed faces\n\n    plt.figure(figsize=(20, 10))\n    columns = 5  # Number of columns in the grid\n    axes_list = []  # Store axis references\n\n    for i, face_file in enumerate(face_images):\n        img = cv2.imread(os.path.join(faces_folder, face_file))  # Load face image\n        img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)  # Convert color format\n\n        ax = plt.subplot(len(face_images) // columns + 1, columns, i + 1)\n        plt.imshow(img)\n        plt.axis('on')  # Keep axis visible for values\n        plt.title(f\"Frame {face_file.split('.')[0].replace('_', '.')}s\")\n\n        axes_list.append(ax)\n\n    plt.tight_layout()\n    plt.show()\n\n    # 🔹 Print X and Y axis limits for each subplot\n    for i, ax in enumerate(axes_list):\n        x_lim = ax.get_xlim()  # Get X-axis range\n        y_lim = ax.get_ylim()  # Get Y-axis range\n        print(f\"Grid {i+1}: X-axis range {x_lim}, Y-axis range {y_lim}\")\n\n# Example usage\nfaces_folder = \"/kaggle/working/aagfhgtpmv\"  # Replace with your folder path\nprint_cropped_faces(faces_folder)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-04-30T09:19:38.853450Z","iopub.execute_input":"2025-04-30T09:19:38.853838Z","iopub.status.idle":"2025-04-30T09:19:41.185941Z","shell.execute_reply.started":"2025-04-30T09:19:38.853773Z","shell.execute_reply":"2025-04-30T09:19:41.185137Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import shutil\n\n# Define the path of the directory you want to delete\ndir_path = \"/kaggle/working/aagfhgtpmv\"  # Replace with your actual folder path\n\n# Delete the entire directory\nshutil.rmtree(dir_path)\n\nprint(f\"Deleted directory: {dir_path}\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-04-30T09:17:21.925913Z","iopub.execute_input":"2025-04-30T09:17:21.926230Z","iopub.status.idle":"2025-04-30T09:17:21.941119Z","shell.execute_reply.started":"2025-04-30T09:17:21.926185Z","shell.execute_reply":"2025-04-30T09:17:21.939719Z"}},"outputs":[],"execution_count":null}]}