nkeerthi/H4_ComputerVision
0
1import numpy as np2import cv23from matplotlib import pyplot as plt4import torch5# In the below line,remove '.' while working on your local system. However Make sure that '.' is present before face_recognition_model while uploading to the server, Do not remove it.6from .face_recognition_model import *7from PIL import Image8import base649import io10import os11import joblib12import pickle13# Add more imports if required14 15from torch.autograd import Variable16import torch.nn.functional as F17 18 19 20###########################################################################################################################################21# Caution: Don't change any of the filenames, function names and definitions #22# Always use the current_path + file_name for refering any files, without it we cannot access files on the server # 23###########################################################################################################################################24 25# Current_path stores absolute path of the file from where it runs. 26current_path = os.path.dirname(os.path.abspath(__file__))27 28#1) The below function is used to detect faces in the given image.29#2) It returns only one image which has maximum area out of all the detected faces in the photo.30#3) If no face is detected,then it returns zero(0).31 32def detected_face(image):33 eye_haar = current_path + '/haarcascade_eye.xml'34 face_haar = current_path + '/haarcascade_frontalface_default.xml'35 face_cascade = cv2.CascadeClassifier(face_haar)36 eye_cascade = cv2.CascadeClassifier(eye_haar)37 gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)38 faces = face_cascade.detectMultiScale(gray, 1.3, 5)39 face_areas=[]40 images = []41 required_image=042 for i, (x,y,w,h) in enumerate(faces):43 face_cropped = gray[y:y+h, x:x+w]44 face_areas.append(w*h)45 images.append(face_cropped)46 required_image = images[np.argmax(face_areas)]47 required_image = Image.fromarray(required_image)48 return required_image49 50 51#1) Images captured from mobile is passed as parameter to the below function in the API call. It returns the similarity measure between given images.52#2) The image is passed to the function in base64 encoding, Code for decoding the image is provided within the function.53#3) Define an object to your siamese network here in the function and load the weight from the trained network, set it in evaluation mode.54#4) Get the features for both the faces from the network and return the similarity measure, Euclidean,cosine etc can be it. But choose the Relevant measure.55#5) For loading your model use the current_path+'your model file name', anyhow detailed example is given in comments to the function 56#Caution: Don't change the definition or function name; for loading the model use the current_path for path example is given in comments to the function57def get_similarity(img1, img2):58 device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")59 60 det_img1 = detected_face(img1)61 det_img2 = detected_face(img2)62 if(det_img1 == 0 or det_img2 == 0):63 det_img1 = Image.fromarray(cv2.cvtColor(img1, cv2.COLOR_BGR2GRAY))64 det_img2 = Image.fromarray(cv2.cvtColor(img2, cv2.COLOR_BGR2GRAY))65 face1 = trnscm(det_img1).unsqueeze(0)66 face2 = trnscm(det_img2).unsqueeze(0)67 ##########################################################################################68 ##Example for loading a model using weight state dictionary: ##69 ## feature_net = light_cnn() #Example Network ##70 ## model = torch.load(current_path + '/siamese_model.t7', map_location=device) ##71 ## feature_net.load_state_dict(model['net_dict']) ##72 ## ##73 ##current_path + '/<network_definition>' is path of the saved model if present in ##74 ##the same path as this file, we recommend to put in the same directory ##75 ##########################################################################################76 ##########################################################################################77 78 # YOUR CODE HERE, load the model79 feature_net = Siamese() #Example Network ##80 model = torch.load(current_path + '/siamese_model.t7', map_location=device) ##81 feature_net.load_state_dict(model['net_dict']) 82 83 # YOUR CODE HERE, return similarity measure using your model84 output1,output2 = feature_net(face1.to(device),face2.to(device)) 85 86 euclidean_distance = F.pairwise_distance(output1, output2) 87 return euclidean_distance.item()88 89#1) Image captured from mobile is passed as parameter to this function in the API call, It returns the face class in the string form ex: "Person1"90#2) The image is passed to the function in base64 encoding, Code to decode the image provided within the function91#3) Define an object to your network here in the function and load the weight from the trained network, set it in evaluation mode92#4) Perform necessary transformations to the input(detected face using the above function).93#5) Along with the siamese, you need the classifier as well, which is to be finetuned with the faces that you are training94##Caution: Don't change the definition or function name; for loading the model use the current_path for path example is given in comments to the function95def get_face_class(img1):96 device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")97 98 det_img1 = detected_face(img1)99 if(det_img1 == 0):100 det_img1 = Image.fromarray(cv2.cvtColor(img1, cv2.COLOR_BGR2GRAY))101 ##YOUR CODE HERE, return face class here102 ##Hint: you need a classifier finetuned for your classes, it takes o/p of siamese as i/p to it103 ##Better Hint: Siamese experiment is covered in one of the labs104 face = trnscm(det_img1).unsqueeze(0).to(device)105 106 feature_net = Siamese().to(device) #Example Network ##107 siemese_model_dict = torch.load(current_path + '/siamese_model.t7', map_location=device) ##108 feature_net.load_state_dict(siemese_model_dict['net_dict']) 109 110 srepr_img = feature_net.forward_once(face)111 X = srepr_img.detach().numpy()112 113 loaded_model_clf = joblib.load(current_path + '/clf.joblib')114 y = loaded_model_clf.predict(X)115 print(y[0])116 return y