{"cells":[{"metadata":{},"cell_type":"markdown","source":"# Introduction"},{"metadata":{},"cell_type":"markdown","source":"I am going to introduce Mobilenet SSD face extractor. **It is better than MTCNN/same with MTCNN in accuracy, but still have a competitive speed** I am aware of dual shot detector is better, but it takes too long.\n\nIt is recommended by @harshit_sheoran. FYI, it is used in our best score kernel(0.34LB)."},{"metadata":{},"cell_type":"markdown","source":"In this kernel, it will be a clean version of that extractor extracting faces from frames. I also included the helper function to go over video(with error catch)."},{"metadata":{},"cell_type":"markdown","source":"**Here is the comparison to other face extractors[link](https://www.kaggle.com/unkownhihi/mobilenet-face-extractor-helper-code)**"},{"metadata":{},"cell_type":"markdown","source":"# Imports"},{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"cell_type":"code","source":"import sys\nimport matplotlib.pyplot as plt\nimport cv2\nimport time\nimport tensorflow as tf\nimport numpy as np","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Initialize Mobilenet Face Extractor"},{"metadata":{"trusted":true},"cell_type":"code","source":"import tensorflow as tf\ndetection_graph = tf.Graph()\nwith detection_graph.as_default():\n    od_graph_def = tf.compat.v1.GraphDef()\n    with tf.io.gfile.GFile('../input/mobilenet-face/frozen_inference_graph_face.pb', 'rb') as fid:\n        serialized_graph = fid.read()\n        od_graph_def.ParseFromString(serialized_graph)\n        tf.import_graph_def(od_graph_def, name='')\n        config = tf.compat.v1.ConfigProto()\n    config.gpu_options.allow_growth = True\n    sess=tf.compat.v1.Session(graph=detection_graph, config=config)\n    image_tensor = detection_graph.get_tensor_by_name('image_tensor:0')\n    boxes_tensor = detection_graph.get_tensor_by_name('detection_boxes:0')    \n    scores_tensor = detection_graph.get_tensor_by_name('detection_scores:0')\n    num_detections = detection_graph.get_tensor_by_name('num_detections:0')","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Helper Fuction"},{"metadata":{"trusted":true},"cell_type":"code","source":"def get_mobilenet_face(image):\n    global boxes,scores,num_detections\n    (im_height,im_width)=image.shape[:-1]\n    imgs=np.array([image])\n    (boxes, scores) = sess.run(\n        [boxes_tensor, scores_tensor],\n        feed_dict={image_tensor: imgs})\n    max_=np.where(scores==scores.max())[0][0]\n    box=boxes[0][max_]\n    ymin, xmin, ymax, xmax = box\n    (left, right, top, bottom) = (xmin * im_width, xmax * im_width,\n                                ymin * im_height, ymax * im_height)\n    left, right, top, bottom = int(left), int(right), int(top), int(bottom)\n    return (left, right, top, bottom)\ndef crop_image(frame,bbox):\n    left, right, top, bottom=bbox\n    return frame[top:bottom,left:right]\ndef get_img(frame):\n    return cv2.resize(crop_image(frame,get_mobilenet_face(frame)),(160,160))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def detect_video(video):\n    capture = cv2.VideoCapture(video)\n    v_len = int(capture.get(cv2.CAP_PROP_FRAME_COUNT))\n    frame_idxs = np.linspace(0,v_len,frame_count, endpoint=False, dtype=np.int)\n    imgs=[]\n    i=0\n    for frame_idx in range(int(v_len)):\n        ret = capture.grab()\n        if not ret: \n            pass\n        if frame_idx >= frame_idxs[i]:\n            ret, frame = capture.retrieve()\n            if not ret or frame is None:\n                pass\n            else:\n                frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)\n                try:\n                    face=get_img(frame)\n                except Exception as err:\n                    print(err)\n                    continue\n                imgs.append(face)\n            i += 1\n            if i >= len(frame_idxs):\n                break\n    if len(imgs)<frame_count:\n        return None\n    return np.hstack(imgs)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Detection/Results"},{"metadata":{"trusted":true},"cell_type":"code","source":"video='../input/deepfake-detection-challenge/train_sample_videos/bdnaqemxmr.mp4'","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"frame_count=5\nplt.imshow(detect_video(video))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"frame_count=10\nplt.imshow(detect_video(video))","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Conclusion"},{"metadata":{},"cell_type":"markdown","source":"Thanks for reading. Hope this notebook helps! Please upvote this notebook and the associated dataset if you find it helpful."}],"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}