# This Python 3 environment comes with many helpful analytics libraries installed
# It is defined by the kaggle/python Docker image: https://github.com/kaggle/docker-python
# For example, here's several helpful packages to load

import numpy as np # linear algebra
import pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)

# Input data files are available in the read-only "../input/" directory
# For example, running this (by clicking run or pressing Shift+Enter) will list all files under the input directory

import os
for dirname, _, filenames in os.walk('/kaggle/input'):
    for filename in filenames:
        print(os.path.join(dirname, filename))

# You can write up to 20GB to the current directory (/kaggle/working/) that gets preserved as output when you create a version using "Save & Run All" 
# You can also write temporary files to /kaggle/temp/, but they won't be saved outside of the current session
#prerequisites
import tensorflow as tf
print(tf.__version__)

!pip install git+https://github.com/rcmalli/keras-vggface.git
#mtcnn-multi-tasking cnn
!pip install mtcnn
!pip install keras_vggface
#to read and store the image from external storage

import urllib.request

def store_image(url, local_file_name):
    with urllib.request.urlopen(url) as resource:
        with open(local_file_name, 'wb') as f:
            f.write(resource.read())
"""
**Images from external storage**
"""
store_image('https://i.guim.co.uk/img/media/cabcfbdafc3b7e0854e07c35c35b18c199aa19a2/0_0_5130_3078/master/5130.jpg?width=620&quality=45&auto=format&fit=max&dpr=2&s=ae80fd89ca23ac48d4bff44aadb7523a','hamilton1.jpg')
store_image('https://cdn-1.motorsport.com/images/mgl/0k7er3A0/s1200/lewis-hamilton-mercedes-1.webp','hamilton2.jpg')
from matplotlib import pyplot as plt
from mtcnn.mtcnn import MTCNN
#reading image pixels
image = plt.imread('hamilton1.jpg')

#detection of face in the image and its properties
detector = MTCNN()

faces = detector.detect_faces(image)
for face in faces:
    print(face)
#to highlight the face with a rectangle
from matplotlib.patches import Rectangle
def highlight_faces(image_path, faces):
  # display image
    image = plt.imread(image_path)
    plt.imshow(image)

    ax = plt.gca()

  # for each face, draw a rectangle based on coordinates
    for face in faces:
        x, y, width, height = face['box']
        face_border = Rectangle((x, y), width, height,
                          fill=False, color='red')
        ax.add_patch(face_border)
    plt.show()
highlight_faces('hamilton1.jpg', faces)
image = plt.imread('hamilton2.jpg')
faces = detector.detect_faces(image)

highlight_faces('hamilton2.jpg', faces)
from numpy import asarray
from PIL import Image

def extract_face_from_image(image_path, required_size=(224, 224)):
  # load image and detect faces
    image = plt.imread(image_path)
    detector = MTCNN()
    faces = detector.detect_faces(image)

    face_images = []

    for face in faces:
    # extract the bounding box from the requested face
        x1, y1, width, height = face['box']
        x2, y2 = x1 + width, y1 + height

    # extract the face
        face_boundary = image[y1:y2, x1:x2]
    # resize pixels to the model size
        face_image = Image.fromarray(face_boundary)
        face_image = face_image.resize(required_size)
        face_array = asarray(face_image)
        face_images.append(face_array)

    return face_images

extracted_face = extract_face_from_image('hamilton2.jpg')


# Display the first face from the extracted faces

plt.imshow(extracted_face[0])
print(extracted_face[0].shape)
plt.show()
 !pip install Keras-Applications
from keras_applications.imagenet_utils import _obtain_input_shape
from keras_vggface.utils import preprocess_input
from keras_vggface.vggface import VGGFace
from scipy.spatial.distance import cosine
def get_model_scores(faces):
    samples = asarray(faces, 'float32')
    print(samples.shape)
  
    print(samples.shape)
  # prepare the data for the model
    samples = preprocess_input(samples, version=2)
  

  # create a vggface model object
    model = VGGFace(model='resnet50',
      include_top=False,
      input_shape=(224, 224, 3),
      pooling='avg')
#each feature is down grades to avg value

  # perform prediction
    return model.predict(samples)

faces = [extract_face_from_image(image_path)
         for image_path in ['hamilton1.jpg', 'hamilton2.jpg']]
model_scores1 = get_model_scores(faces[0])
model_scores2 = get_model_scores(faces[1])
#to check if the given faces in both images match or not
if cosine(model_scores1, model_scores2) <= 0.4:
    print("Faces Matched")
"""
**With Multiple faces in a picture**
"""
store_image('https://www.formula1.com/content/dam/fom-website/sutton/2019/AbuDhabi/Sunday/DXI14281_20191201120510963.jpg.transform/9col-retina/image.jpg','team1.jpg')
image = plt.imread('team1.jpg')
faces = detector.detect_faces(image)

highlight_faces('team1.jpg', faces)
store_image('https://cdn.asiatatler.com/asiatatler/i/ph/2019/03/15162238-1_cover_1920x1280.jpg','team2.jpg')
image = plt.imread('team2.jpg')
faces1 = detector.detect_faces(image)

highlight_faces('team2.jpg', faces1)
team1 = extract_face_from_image('team1.jpg')
team2 = extract_face_from_image('team2.jpg')

model_scores_team1 = get_model_scores(team1)
model_scores_team2= get_model_scores(team2)
#to display the matching faces
for idx, face_score_1 in enumerate(model_scores_team1):
    for idy, face_score_2 in enumerate(model_scores_team2):
        score = cosine(face_score_1, face_score_2)
        if score <= 0.4:
      # Printing the IDs of faces and score
            print(idx, idy, score)
      # Displaying each matched pair of faces
            plt.imshow(team1[idx])
            plt.show()
            plt.imshow(team2[idy])
            plt.show()