user2749297
user2749297

Reputation: 23

DeepFace for extracting vector information of an image

for doing face recognition with Deepface I am trying to extract vector information of an image to store in db. So that next time in order to match, I will extract the new image's vector information and look into the db . If the search has results then its a match. I used verify method of the DeepFace but its comparing between 2 images and returning with this:

from deepface import DeepFace
import os

detected_face = DeepFace.detectFace("sly.jpg")
print (detected_face)

this is the output for above:

enter image description here

result  = DeepFace.verify("sly1.jpg","sly2.jpg");

for this I get:

Using VGG-Face model backend and cosine distance.
{'verified': True, 'distance': 1.1920928955078125e-07, 'max_threshold_to_verify': 0.4, 'model': 'VGG-Face', 'similarity_metric': 'cosine'}

This is the comparison result, but I need information of only one image without comparison because I will have lots of records to search(for vector info) when a new face will be tested. Any help will be appreciated.

Upvotes: 1

Views: 6594

Answers (2)

sefiks
sefiks

Reputation: 1630

It becomes easier in DeepFace 0.0.41.

from deepface import DeepFace
from deepface.commons import functions

models = ['VGG-Face', 'Facenet', 'OpenFace', 'DeepFace', 'DeepID', 'Dlib']
model = DeepFace.build_model(models[0])
target_size = model.layers[0].input_shape

img1_path = "img1.jpg"
img2_path = "img2.jpg"

#detect and align 
img1 = functions.preprocess_face(img1_path, target_size = target_size)
img2 = functions.preprocess_face(img2_path, target_size = target_size)

#find vector embeddings
img1_embedding = model.predict(img1)
img2_embedding = model.predict(img2)

Upvotes: 0

B200011011
B200011011

Reputation: 4258

I am assuming it is this repo among others with same name and installed with setup.py or pip install deepface.

I tested this on google colab. For using locally use cv2.imshow(...) instead of cv2_imshow(...).

Downloading test images

!wget "http://*.jpg" -O "1.jpg"
!wget "https://*.jpg" -O "2.jpg"

Check image

import cv2
from google.colab.patches import cv2_imshow
im1 = cv2.imread("1.jpg")
#cv2.imshow("img", im1)
cv2_imshow(im1)

Face Detection

The output from DeepFace.detectFace returns normalized cropped face. For mtcnn I got image of shape (224, 224, 3). You can verify and view the image with,

from deepface import DeepFace
import cv2
from google.colab.patches import cv2_imshow

#backends = ['opencv', 'ssd', 'dlib', 'mtcnn']
backends = ['mtcnn']
for backend in backends:
  #face detection and alignment
  detected_face = DeepFace.detectFace("1.jpg", detector_backend = backend)
  
  print(detected_face)
  print(detected_face.shape)

  im = cv2.cvtColor(detected_face * 255, cv2.COLOR_BGR2RGB)
  #cv2.imshow("image", im)
  cv2_imshow(im)

Output

[[[0.12156863 0.05882353 0.02352941]
  [0.2901961  0.18039216 0.1254902 ]
  [0.3137255  0.20392157 0.14901961]
  ...
  [0.06666667 0.01176471 0.01176471]
  [0.05882353 0.01176471 0.00784314]
  [0.03921569 0.00784314 0.00392157]]

 [[0.26666668 0.2        0.16470589]
  [0.19215687 0.08235294 0.02745098]
  [0.33333334 0.22352941 0.16862746]
  ...
  [0.03921569 0.00392157 0.00392157]
  [0.04313726 0.00784314 0.00784314]
  [0.04313726 0.         0.00392157]]

 [[0.11764706 0.05098039 0.01568628]
  [0.21176471 0.10588235 0.05882353]
  [0.44313726 0.3372549  0.27058825]
  ...
  [0.02352941 0.00392157 0.        ]
  [0.02352941 0.00392157 0.        ]
  [0.02745098 0.         0.        ]]

 ...

 [[0.24313726 0.1882353  0.13725491]
  [0.24313726 0.18431373 0.13725491]
  [0.22745098 0.16470589 0.11372549]
  ...
  [0.654902   0.69803923 0.78431374]
  [0.62352943 0.67058825 0.7529412 ]
  [0.38431373 0.4117647  0.45882353]]

 [[0.23529412 0.18039216 0.12941177]
  [0.22352941 0.16862746 0.11764706]
  [0.22745098 0.16470589 0.11764706]
  ...
  [0.6392157  0.69803923 0.78039217]
  [0.6156863  0.6745098  0.75686276]
  [0.36862746 0.40392157 0.4627451 ]]

 [[0.21568628 0.16862746 0.10980392]
  [0.2        0.15294118 0.09803922]
  [0.20784314 0.14901961 0.10196079]
  ...
  [0.6313726  0.6901961  0.77254903]
  [0.6039216  0.6627451  0.74509805]
  [0.36078432 0.39607844 0.4509804 ]]]
(224, 224, 3)

Face Embedding

Since, you are looking for embedding vector you can get it with below. It is a modified version of verify function. I kept option for two images, distance calculation, verification, but you can modify it generate face embedding for a single face only. I did not remove any unused imports.

"""
Modified verify function for face embedding generation
backends = ['opencv', 'ssd', 'dlib', 'mtcnn']
"""

from keras.preprocessing import image
import warnings
warnings.filterwarnings("ignore")
import time
import os
from os import path
from pathlib import Path
import gdown
import numpy as np
import pandas as pd
from tqdm import tqdm
import json
import cv2
from keras import backend as K
import keras
import tensorflow as tf
import pickle

from deepface import DeepFace
from deepface.basemodels import VGGFace, OpenFace, Facenet, FbDeepFace, DeepID
from deepface.extendedmodels import Age, Gender, Race, Emotion
from deepface.commons import functions, realtime, distance as dst


def FaceEmbeddingAndDistance(img1_path, img2_path = '', model_name ='Facenet', distance_metric = 'cosine', model = None, enforce_detection = True, detector_backend = 'mtcnn'):

  #--------------------------------
  #ensemble learning disabled.
  
  if model == None:
    if model_name == 'VGG-Face':
      print("Using VGG-Face model backend and", distance_metric,"distance.")
      model = VGGFace.loadModel()

    elif model_name == 'OpenFace':
      print("Using OpenFace model backend", distance_metric,"distance.")
      model = OpenFace.loadModel()

    elif model_name == 'Facenet':
      print("Using Facenet model backend", distance_metric,"distance.")
      model = Facenet.loadModel()

    elif model_name == 'DeepFace':
      print("Using FB DeepFace model backend", distance_metric,"distance.")
      model = FbDeepFace.loadModel()
    
    elif model_name == 'DeepID':
      print("Using DeepID2 model backend", distance_metric,"distance.")
      model = DeepID.loadModel()
    
    elif model_name == 'Dlib':
      print("Using Dlib ResNet model backend", distance_metric,"distance.")
      from deepface.basemodels.DlibResNet import DlibResNet #this is not a must because it is very huge.
      model = DlibResNet()

    else:
      raise ValueError("Invalid model_name passed - ", model_name)
  else: #model != None
    print("Already built model is passed")

  #------------------------------
  #face recognition models have different size of inputs
  #my environment returns (None, 224, 224, 3) but some people mentioned that they got [(None, 224, 224, 3)]. I think this is because of version issue.
    
  if model_name == 'Dlib': #this is not a regular keras model
    input_shape = (150, 150, 3)
  
  else: #keras based models
    input_shape = model.layers[0].input_shape
    
    if type(input_shape) == list:
      input_shape = input_shape[0][1:3]
    else:
      input_shape = input_shape[1:3]
    
  input_shape_x = input_shape[0]
  input_shape_y = input_shape[1]

  #------------------------------

  #tuned thresholds for model and metric pair
  threshold = functions.findThreshold(model_name, distance_metric)

  #------------------------------
  

  #----------------------
  #crop and align faces

  img1 = functions.preprocess_face(img=img1_path, target_size=(input_shape_y, input_shape_x), enforce_detection = enforce_detection, detector_backend = detector_backend)
  img2 = functions.preprocess_face(img=img2_path, target_size=(input_shape_y, input_shape_x), enforce_detection = enforce_detection, detector_backend = detector_backend)

  #----------------------
  #find embeddings

  img1_representation = model.predict(img1)[0,:]
  img2_representation = model.predict(img2)[0,:]

  print("FACE 1 Embedding:")
  print(img1_representation)

  print("FACE 2 Embedding:")
  print(img2_representation)

  #----------------------
  #find distances between embeddings

  if distance_metric == 'cosine':
    distance = dst.findCosineDistance(img1_representation, img2_representation)
  elif distance_metric == 'euclidean':
    distance = dst.findEuclideanDistance(img1_representation, img2_representation)
  elif distance_metric == 'euclidean_l2':
    distance = dst.findEuclideanDistance(dst.l2_normalize(img1_representation), dst.l2_normalize(img2_representation))
  else:
    raise ValueError("Invalid distance_metric passed - ", distance_metric)

  print("DISTANCE")
  print(distance)

  #----------------------
  #decision

  if distance <= threshold:
    identified =  "true"
  else:
    identified =  "false"

  print("IDENTIFIED")
  print(identified)

Above function is called via,

FaceEmbeddingAndDistance("1.jpg", "2.jpg", model_name='Facenet', detector_backend = 'mtcnn')

Output

FACE 1 Embedding:
[-0.7229302  -1.766835   -1.5399052   0.59634393  1.203212   -1.693247
 -0.90845925  0.5264039   2.148173   -0.9786542  -0.00369854 -1.2710322
 -1.5515596  -0.4111185  -0.36896533 -0.30051672  0.35091963  0.5073533
 -1.7270111  -0.5230838   0.3376239  -1.0811361   1.5242224  -0.6137103
 -1.3100258   0.80050004 -0.7087368  -0.64483845  1.0830203   2.6056807
 -0.76527536 -0.83047277 -0.7335422  -0.01964059 -0.86749244  2.9645889
 -2.426583   -0.11157394 -2.3535717  -0.65058017  0.30864614 -0.77746457
 -0.6233895   0.44898677  2.5578005  -0.583796    0.8406945   1.1105415
 -1.652044   -0.6351479   0.07651432 -1.0454555  -1.8752071   0.50948805
 -1.6050931  -1.1769634  -0.02965304  1.5107706   0.83292925 -0.5382068
 -1.5981512  -0.6405941   0.5521577   0.22957848  0.506649    0.24680384
 -0.91464925 -0.18441322 -0.6801975  -1.0448433   0.52288735 -0.79405725
  0.5974493  -0.40668172 -0.00640235 -0.742475    0.1928863   0.31236258
 -0.37383577 -1.5883486  -1.5336255  -0.74254227 -0.8524561  -1.4625055
 -2.718953   -0.7180952  -1.2140683  -0.5232462   1.2576898  -1.1097553
  2.3971314   0.8855096  -0.16556528 -0.07307663 -1.8778017   0.8690948
 -0.39043528 -0.5494097  -2.2382076   0.7101087   0.15859437  0.2959841
  0.8605075  -0.2040207   0.77952844  0.04542177  0.92514265 -1.988945
  0.9418363   1.6509243  -0.20324889  0.2974357   0.37681833  1.095943
  1.6308782  -1.2553837  -0.10246387 -1.4697052  -0.5832107  -0.34192032
 -1.1347024   1.5154309  -0.00527111 -1.165709   -0.7296148  -0.20767921
  1.2530949  -0.9487353 ]
FACE 2 Embedding:
[ 0.9399996   1.3996615  -1.2931366   0.6869738  -0.03219241  0.96111965
  0.7378809  -0.24804354 -0.8128112   0.19901593  0.48911542 -0.91603553
 -1.1671298   0.88576627  0.25427592  1.1395477   0.45400882 -1.4845027
 -0.90582514 -1.1371222   0.47669724  1.2933927   1.4533392  -0.46943524
  0.10245587 -1.4916894  -2.3223586  -0.10979578  1.7803721   1.0051152
 -0.09164213 -0.64848715 -1.4191641   1.811776    0.73174113  0.2582223
 -0.26430857  1.7021953  -1.0571098  -1.1215096   0.3606074   1.5136883
 -0.30045512  0.26225814 -0.19101554  1.269355    1.0674374  -0.2550623
 -1.0582973   1.7474637  -1.7739134  -0.67914337 -0.1877765   1.1581128
 -2.281225    1.3955555  -1.2690883  -0.16299461  1.337664   -0.8831901
 -0.6862674   2.0526903  -0.6325836   1.333468   -0.10851342 -0.64831966
 -1.0277263   1.4572504  -0.29905424 -0.33187118 -0.54727656  1.1528811
  0.12454037 -1.5835186  -0.2271783   1.3911225   1.0170195   0.5741334
 -1.3088373  -0.5950714  -0.6856393  -0.910367   -2.0136826  -0.73777384
  0.319223   -2.1968741   0.9673934  -0.604423   -0.08049382 -1.948634
  1.88159     0.20169139  0.7295723  -1.0224706   1.2995481  -0.3402595
  1.1711328  -0.64862376  0.42063504 -0.01502114 -0.7048841   1.4360497
 -1.2988033   0.31773448  1.534014    0.98858756  1.3450235  -0.9417385
  0.26414695 -0.01988658  0.7418235  -0.04945141 -0.44838902  1.5288658
 -1.1905407   0.13961646 -0.17101136 -0.18599203 -1.9648114   0.66071814
 -0.07431012  1.5870664   1.5989372  -0.21751085  0.78908855 -1.5576671
  0.02266342  0.20999858]
DISTANCE
0.807837575674057
IDENTIFIED
false

Upvotes: 2

Related Questions