{"cells":[{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"cell_type":"code","source":"import numpy as np\nimport pandas as pd\nimport os","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"!ls -GFlash ../input/deepfake-detection-challenge","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import cv2\nimport seaborn as sns\nimport matplotlib.pyplot as plt","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"from PIL import Image, ImageDraw","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"os.listdir('/kaggle/input/deepfake-detection-challenge')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"INPUT_FOLDER = '../input/deepfake-detection-challenge'\nTRAIN_SAMPLE_FOLDER = 'train_sample_videos'\nTEST_FOLDER = 'test_videos'","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","trusted":true},"cell_type":"code","source":"print(f'No of training sample videos : {len(os.listdir(os.path.join(INPUT_FOLDER, TRAIN_SAMPLE_FOLDER)))}')\nprint(f'No of test videos : {len(os.listdir(os.path.join(INPUT_FOLDER, TEST_FOLDER)))}')","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"**Let's check the extensions**"},{"metadata":{"trusted":true},"cell_type":"code","source":"train_files = os.listdir(os.path.join(INPUT_FOLDER, TRAIN_SAMPLE_FOLDER))\nall_extensions = []\nfor file in train_files:\n    ext = file.split('.')[1]\n    if ext not in all_extensions:\n        all_extensions.append(ext)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"print(f'All extensions in Train folder are - {all_extensions}')","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"**JSON file contains metadata. Let's explore it**"},{"metadata":{"trusted":true},"cell_type":"code","source":"json_file = [file for file in train_files if file.endswith('.json')][0]\nprint(f'Metadata filename is {json_file}')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"df_metadata = pd.read_json(os.path.join(INPUT_FOLDER, TRAIN_SAMPLE_FOLDER, json_file)).T","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"df_metadata","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"plt.figure(figsize = (13,8))\nax = sns.countplot(df_metadata['label'])\nfor p in ax.patches:\n    ax.annotate(f'{p.get_height():.0f}\\n({p.get_height()/df_metadata.shape[0] * 100:.1f}%)', xy = (p.get_x() + p.get_width()/2., p.get_height()), ha = 'center', xytext = (-10, 5), textcoords = 'offset points')\nax.set_ylim(0, .9 * df_metadata.shape[0])\nplt.xlabel('Video Type', fontsize = 14)\nplt.ylabel('Count', fontsize = 14)\nplt.title('Distribution of Video type', fontsize = 14)\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"**Check Missing Data**"},{"metadata":{"trusted":true},"cell_type":"code","source":"total = df_metadata.isnull().sum()\ncount = df_metadata.isnull().count()\npercent_missing = (total/count * 100)\nprint(f'Original videos which are missing are {total.original} which is {percent_missing.original}% of the total')","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"**This number is exactly same as number of REAL videos. Does it mean that all Real label videos do not have original videos?\nLet us confirm our suspicion**"},{"metadata":{"trusted":true},"cell_type":"code","source":"len(df_metadata[df_metadata['label'] == 'REAL'])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"df_metadata.original.nunique()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"**Out of total 323 original videos (which are all FAKE) only 209 are unique**"},{"metadata":{"trusted":true},"cell_type":"code","source":"df_metadata.original.value_counts()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def grab_image_from_video(filename):\n    cap = cv2.VideoCapture(filename)\n    ret, frame = cap.read()\n    frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)\n    cap.release()\n    cv2.destroyAllWindows()\n    return frame","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def plot_frame(filename, type):\n    frame = grab_image_from_video(filename)\n    fig = plt.figure(figsize = (13,8))\n    ax = fig.add_subplot(111)\n    ax.imshow(frame)\n    ax.axis('off')\n    ax.set_title(f'Screen grab of {type} Video - {filename.split(\"/\")[-1]}')","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"**Let's plot some Fake samples**"},{"metadata":{"trusted":true},"cell_type":"code","source":"fake_videos = list(df_metadata[df_metadata['label'] == 'FAKE'].sample(3).index)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"for fake_video in fake_videos:\n    plot_frame(os.path.join(INPUT_FOLDER, TRAIN_SAMPLE_FOLDER, fake_video), 'FAKE')","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"**Some Real videos too**"},{"metadata":{"trusted":true},"cell_type":"code","source":"real_videos = list(df_metadata[df_metadata['label'] == 'REAL'].sample(3).index)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"for real_video in real_videos:\n    plot_frame(os.path.join(INPUT_FOLDER, TRAIN_SAMPLE_FOLDER, real_video), 'REAL')","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"**Detect faces using Haar Cascade classifier**"},{"metadata":{"trusted":true},"cell_type":"code","source":"def detect_faces(image):\n    face_cascade = cv2.CascadeClassifier('../input/haarcascades/haarcascade_frontalface_default.xml')\n    faces = face_cascade.detectMultiScale(image, 1.2, 3)\n    return faces","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"sample_videos = list(df_metadata.sample(3).index)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"for video in sample_videos:\n    screen_grab = grab_image_from_video(os.path.join(INPUT_FOLDER, TRAIN_SAMPLE_FOLDER, video))\n    faces = detect_faces(screen_grab)\n    for x, y, w, h in faces:\n        cv2.rectangle(screen_grab, (x,y), (x+w, y+h), (255, 0, 0), 3)\n    fig = plt.figure(figsize = (11, 11))\n    ax = fig.add_subplot(111)\n    image = cv2.cvtColor(screen_grab, cv2.COLOR_BGR2RGB)\n    ax.axis('off')\n    ax.imshow(image)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"**Thus for sideways looking subjects cascade classifier is not able to detect faces. Lets try another method of face detection using facial_recognition library and see if perfomance improves**"},{"metadata":{"trusted":true},"cell_type":"code","source":"!pip install face_recognition","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"**Detect face using face_recognition library and zoom on it**"},{"metadata":{"trusted":true},"cell_type":"code","source":"import face_recognition\ndef detect_faces_using_face_recognition(image):\n    face_locations = face_recognition.face_locations(image)\n    print(f'Found {len(face_locations)} faces in image')\n    fig, axs = plt.subplots(1, 2, figsize = (21, 5))\n    axs[0].imshow(image)\n    axs[0].axis('off')\n    axs[0].set_title('Original Image')\n    for face_location in face_locations:\n        top, right, bottom, left = face_location\n        face_image = image[top:bottom, left:right]\n        axs[1].imshow(face_image)\n        axs[1].axis('off')\n        axs[1].set_title('Detected Face')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"sample_videos = list(df_metadata.sample(3).index)\nfor file in sample_videos:\n    screen_grab = grab_image_from_video(os.path.join(INPUT_FOLDER, TRAIN_SAMPLE_FOLDER, file))\n    detect_faces_using_face_recognition(screen_grab)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def draw_face_landmarks(image):\n    img = Image.fromarray(image)\n    d = ImageDraw.Draw(img)\n    face_landmarks_list = face_recognition.face_landmarks(image)\n    for face_landmarks in face_landmarks_list:\n        for facial_feature in face_landmarks.keys():\n            #print(f'{facial_feature} has points: {face_landmarks[facial_feature]}')\n            d.line(face_landmarks[facial_feature], width = 3)\n            \n    display(img)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"sample_videos = list(df_metadata.sample(3).index)\nfor file in sample_videos:\n    screen_grab = grab_image_from_video(os.path.join(INPUT_FOLDER, TRAIN_SAMPLE_FOLDER, file))\n    draw_face_landmarks(screen_grab)","execution_count":null,"outputs":[]}],"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"pygments_lexer":"ipython3","nbconvert_exporter":"python","version":"3.6.4","file_extension":".py","codemirror_mode":{"name":"ipython","version":3},"name":"python","mimetype":"text/x-python"}},"nbformat":4,"nbformat_minor":4}