{"cells":[{"metadata":{"_uuid":"8b2f3d81-b117-409d-9613-a5fd3f7d2a41","_cell_guid":"eb2b9116-297f-4d7d-af2a-8f50b1979ef0","trusted":true},"cell_type":"code","source":"!pip install ../input/package/pretrainedmodels-0.7.4/ -f ./ --no-index\n#!pip install dlib\nimport os\nfrom os.path import join\n\n#import dlib\nimport cv2\nimport torch\nimport torch.nn as nn\nimport argparse\nimport sys\nimport time\nsys.path.append(\"/kaggle/input\")\nsys.path.append(\"/kaggle/input/faceforensics\")\nfrom tqdm import tqdm\nfrom PIL import Image as pil_image\nfrom torchvision import transforms\nimport pretrainedmodels\n\n\nxception_default_data_transforms = {\n    'train': transforms.Compose([\n        transforms.Resize((299, 299)),\n        transforms.ToTensor(),\n        transforms.Normalize([0.5]*3, [0.5]*3)\n    ]),\n    'val': transforms.Compose([\n        transforms.Resize((299, 299)),\n        transforms.ToTensor(),\n        transforms.Normalize([0.5] * 3, [0.5] * 3)\n    ]),\n    'test': transforms.Compose([\n        transforms.Resize((299, 299)),\n        transforms.ToTensor(),\n        transforms.Normalize([0.5] * 3, [0.5] * 3)\n    ]),\n}\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import numpy as np\ndirname = '/kaggle/input/deepfake-detection-challenge/test_videos'\nmax_confidence = 0.99\nmin_confidence = 0.01","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def get_boundingbox(face, width, height, scale=1.3, minsize=None):\n    \"\"\"\n    Expects a dlib face to generate a quadratic bounding box.\n    :param face: dlib face class\n    :param width: frame width\n    :param height: frame height\n    :param scale: bounding box size multiplier to get a bigger face region\n    :param minsize: set minimum bounding box size\n    :return: x, y, bounding_box_size in opencv form\n    \"\"\"\n    x1 = face.left()\n    y1 = face.top()\n    x2 = face.right()\n    y2 = face.bottom()\n    size_bb = int(max(x2 - x1, y2 - y1) * scale)\n    if minsize:\n        if size_bb < minsize:\n            size_bb = minsize\n    center_x, center_y = (x1 + x2) // 2, (y1 + y2) // 2\n\n    # Check for out of bounds, x-y top left corner\n    x1 = max(int(center_x - size_bb // 2), 0)\n    y1 = max(int(center_y - size_bb // 2), 0)\n    # Check for too big bb size for given x, y\n    size_bb = min(width - x1, size_bb)\n    size_bb = min(height - y1, size_bb)\n\n    return x1, y1, size_bb\n\n\ndef preprocess_image(image, cuda=True):\n    \"\"\"\n    Preprocesses the image such that it can be fed into our network.\n    During this process we envoke PIL to cast it into a PIL image.\n\n    :param image: numpy image in opencv form (i.e., BGR and of shape\n    :return: pytorch tensor of shape [1, 3, image_size, image_size], not\n    necessarily casted to cuda\n    \"\"\"\n    # Revert from BGR\n    image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)\n    # Preprocess using the preprocessing function used during training and\n    # casting it to PIL image\n    preprocess = xception_default_data_transforms['test']\n    preprocessed_image = preprocess(pil_image.fromarray(image))\n    # Add first dimension as the network expects a batch\n    preprocessed_image = preprocessed_image.unsqueeze(0)\n    if cuda:\n        preprocessed_image = preprocessed_image.cuda()\n    return preprocessed_image\n\n\ndef predict_with_model(image, model, post_function=nn.Softmax(dim=1),\n                       cuda=True):\n    \"\"\"\n    Predicts the label of an input image. Preprocesses the input image and\n    casts it to cuda if required\n\n    :param image: numpy image\n    :param model: torch model with linear layer at the end\n    :param post_function: e.g., softmax\n    :param cuda: enables cuda, must be the same parameter as the model\n    :return: prediction (1 = fake, 0 = real)\n    \"\"\"\n    # Preprocess\n    preprocessed_image = preprocess_image(image, cuda)\n\n    # Model prediction\n    output = model(preprocessed_image)\n    output = post_function(output)\n\n    return output","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def test_full_image_network_(video_path, model, face_detector,\n                            start_frame=0, end_frame=None, cuda=True):\n    # Read and write\n    reader = cv2.VideoCapture(video_path)\n\n    fps = reader.get(cv2.CAP_PROP_FPS)\n    num_frames = int(reader.get(cv2.CAP_PROP_FRAME_COUNT))\n\n    # Frame numbers and length of output video\n    frame_num = 0\n    assert start_frame < num_frames - 1\n    end_frame = end_frame if end_frame else num_frames\n    frame_logits = []\n    \n    while reader.isOpened():\n        frame_num += 1\n        print('{}/{}'.format(frame_num, num_frames), end=\"\\r\")\n        _ = reader.grab()\n        if image is None:\n            break\n        if frame_num < start_frame or frame_num % 3 == 0:\n            continue\n        \n        _, image = reader.retrieve()\n        # Image size\n        height, width = image.shape[:2]\n\n        # 2. Detect with dlib\n        gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)\n        faces = face_detector(gray, 1)\n\n        if len(faces):\n            # For now only take biggest face\n            face = faces[0]\n\n            # --- Prediction ---------------------------------------------------\n            # Face crop with dlib and bounding box scale enlargement\n            x, y, size = get_boundingbox(face, width, height)\n            cropped_face = image[y:y+size, x:x+size]\n\n            # Actual prediction using our model\n            logit = predict_with_model(cropped_face, model, cuda=cuda)[0, 1].detach().cpu().item()\n            frame_logits.append(logit*2)\n            # ------------------------------------------------------------------\n\n        if frame_num >= end_frame:\n            break\n            \n    num_detected_faces = len(frame_logits)\n    video_logit = sum(frame_logits)\n    if num_detected_faces > 0: \n        video_logit = video_logit/num_detected_faces\n    return np.clip(video_logit, min_confidence, max_confidence)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def get_boundingbox_v(face, width, height, mode='dlib', scale=1.3, minsize=None):\n    \"\"\"\n    Expects a dlib face to generate a quadratic bounding box.\n    :param face: dlib face class\n    :param width: frame width\n    :param height: frame height\n    :param scale: bounding box size multiplier to get a bigger face region\n    :param minsize: set minimum bounding box size\n    :return: x, y, bounding_box_size in opencv form\n    \"\"\"\n    if mode == 'dlib':\n        x1 = face.left()\n        y1 = face.top()\n        x2 = face.right()\n        y2 = face.bottom()\n        size_bb = int(max(x2 - x1, y2 - y1) * scale)\n        center_x, center_y = (x1 + x2) // 2, (y1 + y2) // 2\n    elif mode == 'opencv':\n        x1, y1, w, h = face\n        size_bb = int(max(w, h) * scale)\n        center_x = x1 + w//2\n        center_y = y1 + h//2\n    else:\n        raise Exception(\"Invalid mode!!\", mode)\n        \n    if minsize:\n        if size_bb < minsize:\n            size_bb = minsize\n\n    # Check for out of bounds, x-y top left corner\n    x1 = max(int(center_x - size_bb // 2), 0)\n    y1 = max(int(center_y - size_bb // 2), 0)\n    # Check for too big bb size for given x, y\n    size_bb = min(width - x1, size_bb)\n    size_bb = min(height - y1, size_bb)\n\n    return x1, y1, size_bb\n\ndef test_image_opencv(video_path, model, face_detector, mode='dlib',\n                            start_frame=0, end_frame=None, cuda=True):\n    # Read and write\n    reader = cv2.VideoCapture(video_path)\n\n    fps = reader.get(cv2.CAP_PROP_FPS)\n    num_frames = int(reader.get(cv2.CAP_PROP_FRAME_COUNT))\n\n    # Frame numbers and length of output video\n    frame_num = 0\n    assert start_frame < num_frames - 1\n    end_frame = end_frame if end_frame else num_frames\n    frame_logits = []\n    \n    while reader.isOpened():\n        frame_num += 1\n        if frame_num < start_frame or frame_num % 3 != 1:\n            continue\n        print('{}/{}'.format(frame_num, num_frames), end=\"\\r\")\n        \n        _ = reader.grab()\n        _, image = reader.retrieve()\n        \n        if image is None:\n            break\n        # Image size\n        height, width = image.shape[:2]\n        \n        #start = time.time()\n        # 2. Detect with dlib or opencv\n        gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)\n        if mode == 'dlib':\n            faces = face_detector(gray, 1)\n        elif mode == 'opencv':\n            faces = face_detector.detectMultiScale(gray, 1.8, 3, minSize=(50,50), maxSize=(500,500))\n        else:\n            raise Exception(\"Invalid mode!!\", mode)\n        #end = time.time()\n        #print(\"Detect Face: \", end-start, \" || Len Faces: \", len(faces))\n        \n        if len(faces):\n            # For now only take biggest face\n            face = faces[0]\n\n            # --- Prediction ---------------------------------------------------\n            # Face crop with dlib and bounding box scale enlargement\n            x, y, size = get_boundingbox_v(face, width, height, mode='opencv')\n            cropped_face = image[y:y+size, x:x+size]\n\n            # Actual prediction using our model\n            logit = predict_with_model(cropped_face, model, cuda=cuda)[0, 1].detach().cpu().item()\n            frame_logits.append(logit*2)\n            # ------------------------------------------------------------------\n        \n        if frame_num >= end_frame:\n            break\n            \n    num_detected_faces = len(frame_logits)\n    if (num_detected_faces < 10): \n        return 0.5\n    video_logit = sum(frame_logits)\n    if num_detected_faces > 0: \n        video_logit = video_logit/num_detected_faces\n    return np.clip(video_logit, min_confidence, max_confidence)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"cuda = True\nprint(\"Open Cuda: \", cuda)\n\n#face_detector = dlib.get_frontal_face_detector()\n\nface_cascade = cv2.CascadeClassifier()\nif not face_cascade.load(\"/kaggle/input/haarcascade/haarcascade_frontalface_alt.xml\"):\n    raise Exception(\"Cannot load face_cascade\")\n\nmodel = torch.load(\"/kaggle/input/faceforensics/all_c40.p\", map_location=\"cpu\")\n\nif cuda: \n    model = model.cuda()\n\nwith open(\"submission.csv\", \"w\") as f:\n    f.write(\"filename,label\\n\")\n    for i, filename in enumerate(os.listdir(dirname)):\n        video_path = os.path.join(dirname, filename)\n        # print('progress: {}, video path: {}'.format(i+1, video_path))\n        start = time.time()\n        logit = test_image_opencv(video_path, model, face_cascade, mode='opencv', cuda=cuda)\n        end = time.time()\n        # print()\n        print(video_path.split('/')[-1], \": \", logit, \" || Using Time: \", end-start)\n        f.write(\"{},{}\\n\".format(filename, logit))\n\n# Any results you write to the current directory are saved as output.","execution_count":null,"outputs":[]}],"metadata":{"kernelspec":{"display_name":"Python 3","language":"python","name":"python3"},"language_info":{"name":"python","version":"3.6.4","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"}},"nbformat":4,"nbformat_minor":1}