├── images1 ├── Face_recog.png ├── data_gen.jpeg └── face_detection2.png ├── Face_Detection_Recognition ├── data │ └── Harsh Sagar Garg.npy ├── face_detection.py ├── realtime_data_generation.py └── face_recognition_knn.py └── README.md /images1/Face_recog.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hsgarg/Face-Detection-and-Recognition/HEAD/images1/Face_recog.png -------------------------------------------------------------------------------- /images1/data_gen.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hsgarg/Face-Detection-and-Recognition/HEAD/images1/data_gen.jpeg -------------------------------------------------------------------------------- /images1/face_detection2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hsgarg/Face-Detection-and-Recognition/HEAD/images1/face_detection2.png -------------------------------------------------------------------------------- /Face_Detection_Recognition/data/Harsh Sagar Garg.npy: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hsgarg/Face-Detection-and-Recognition/HEAD/Face_Detection_Recognition/data/Harsh Sagar Garg.npy -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Face-Detection-and-Recognition:mag::performing_arts: 2 | [![forthebadge made-with-python](http://ForTheBadge.com/images/badges/made-with-python.svg)](https://www.python.org/) 3 | [![forthebadge](https://forthebadge.com/images/badges/built-with-love.svg)](https://forthebadge.com) 4 | 5 | [![star this repo](http://githubbadges.com/star.svg?user=harshgarg27&repo=Face-Detection-and-Recognition&style=default)](https://github.com/harshgarg27/Face-Detection-and-Recognition) 6 | 7 | 8 | This Project serves 3 major functionalities: 9 | * Face Detection : By using **OpenCV** and **Haar Cascades** 10 | 11 | 12 | * Generating Real Time Training Data by Taking Selfies from Webcam . 13 | 14 | 15 | * RECOGNISE Face Using **KNN Classification Algorithm** . 16 | 17 | 18 | ## Getting Started 19 | 20 | Clone the Repository, Open the terminal in the Project Folder and then 21 | * For Face Detection 22 | 23 | ``` 24 | python face_detection.py 25 | ``` 26 | * For Real Time Data Generation 27 | 28 | ``` 29 | python realtime_data_generation.py 30 | ``` 31 | * For Face Recognition 32 | 33 | ``` 34 | python face_recognition_knn.py 35 | ``` 36 | 37 | ### Press 'q' to stop the loop 38 | 39 | 40 | ## Project Implementation Video on Youtube 41 | Youtube [Video Link](https://www.youtube.com/watch?v=8Gasjferv2M) 42 | 43 | 44 | -------------------------------------------------------------------------------- /Face_Detection_Recognition/face_detection.py: -------------------------------------------------------------------------------- 1 | ## Face Detection using OpenCV and HaarCascades 2 | ## Haarcascade Classifier is already trained on a lot of facial data 3 | 4 | ############# Once done detecting -> PRESS 'q' to BREAK THE LOOP ################# 5 | 6 | import cv2 7 | 8 | 9 | ##1 Capturing the device from which we want to read our video stream, 0 is for default webcam 10 | cap = cv2.VideoCapture(0) 11 | 12 | ##2 Creating a clssifier object 13 | face_cascade = cv2.CascadeClassifier("haarcascade_frontalface_alt.xml") 14 | 15 | 16 | while True: 17 | ## cap.read() is a method which returns 2 a boolean value and the frame that is captured 18 | ## if the boolean value is false, it means the frame is not captured properly 19 | 20 | ret,frame = cap.read() 21 | gray_frame = cv2.cvtColor(frame,cv2.COLOR_BGR2GRAY) 22 | 23 | if ret == False: 24 | continue 25 | 26 | ##3 detectMultiScale : this method will return starting coordinates(x,y), width and height 27 | ## If there are multiple faces present, it will return a list of tuples like [(x,y,w,h),(x1,y1,w1,h1),(),....] 28 | ## Here 1.3 is the Scale Factor and 5 is the number of Neighbours 29 | ## Reason for Scaling : The Kernals should operate on similar size images on whih they are trained on 30 | ## 3~6 is a good value for Number of Neighbours, hence we have given 5 31 | faces = face_cascade.detectMultiScale(gray_frame,1.3,5) 32 | 33 | 34 | ##4 Iterate over the list and we are going to draw a bounding box around each face 35 | for (x,y,w,h) in faces: 36 | 37 | ## 2 end pts of the rectangle : (x,y) and (x+w,y+h) 38 | cv2.rectangle(frame,(x,y),(x+w,y+h),(0,250,0),2) 39 | cv2.rectangle(gray_frame,(x,y),(x+w,y+h),(255,0,0),2) 40 | 41 | ## Displaying Color Frame and Gray Frame 42 | cv2.imshow("BGR Frame",frame) 43 | cv2.imshow("Gray Frame", gray_frame) 44 | 45 | 46 | key_pressed = cv2.waitKey(1) & 0xFF 47 | if key_pressed == ord('q'): 48 | break 49 | 50 | cap.release() 51 | cv2.destroyAllWindows() 52 | 53 | 54 | ### scaleFactor – It Specifies how much the image size is reduced at each image scale. 55 | 56 | ''' 57 | minNeighbors – It specifies how many neighbors each candidate rectangle should have to retain it. 58 | This parameter will affect the quality of the detected faces. 59 | ''' 60 | -------------------------------------------------------------------------------- /Face_Detection_Recognition/realtime_data_generation.py: -------------------------------------------------------------------------------- 1 | # This is a Python Script that 2 | # 1. Captures images from the webcam video stream 3 | # 2. Extracts all Faces from the image frame (using haarcascades) 4 | # 3. Stores the Face information into numpy arrays 5 | # -> Take the LARGEST Face (in case of multiple faces) 6 | # -> Crop this face and create a 2-D matrix(this is the image itself) 7 | # -> Flatten it in the form of a Linear Array and save it as a .np file 8 | 9 | ################## STEPS FOLLOWED ################### 10 | 11 | # 1. Read and show video stream, capture images 12 | # 2. Detect Faces and show bounding box (haarcascade) 13 | # 3. Flatten the largest face image(gray scale) and save in a numpy array 14 | # 4. Repeat the above for multiple people to generate training data 15 | 16 | ######### WE are generating Real Time Training Data by Taking Selfies from Webcam ######### 17 | 18 | ######## Evertime this script is run, One File will be created in the Data Folder ######### 19 | 20 | 21 | import cv2 22 | import numpy as np 23 | 24 | ## Initialize the camera 25 | cap = cv2.VideoCapture(0) 26 | 27 | ## Detcting Face 28 | face_cascade = cv2.CascadeClassifier("haarcascade_frontalface_alt.xml") 29 | 30 | skip = 0 31 | ##Storing the data. hence creating an array 32 | face_data = [] 33 | dataset_path = './data/' ##data is a folder inside the project folder 34 | 35 | ## Taking File Name as Input From the User 36 | file_name = input("Enter the name of the person : ") 37 | 38 | while True: 39 | ret,frame = cap.read() 40 | 41 | if ret==False: 42 | continue 43 | 44 | gray_frame = cv2.cvtColor(frame,cv2.COLOR_BGR2GRAY) 45 | 46 | ## faces will be a list of Tuples [(x,y,widthh,height),(x1,y1,w1,h1),....] 47 | faces = face_cascade.detectMultiScale(frame,1.3,5) 48 | if len(faces)==0: 49 | continue 50 | 51 | ## Sorting on the basis of area, f[2] = w and f[3] = h hence area = w*h = f[2]*f[3] 52 | ## If we do reverse = True, largest will come to start 53 | faces = sorted(faces,key=lambda f:f[2]*f[3]) 54 | 55 | ##Draw bounding box 56 | ##Pick the last face, because its the largest in the area 57 | for face in faces[-1:]: 58 | x,y,w,h = face 59 | cv2.rectangle(frame,(x,y),(x+w,y+h),(0,255,255),2) 60 | 61 | ##Crop out required part : Region of interest 62 | ## Add offset of 10px on each side of face 63 | offset = 10 64 | ## SLICING 65 | face_section = frame[y-offset:y+h+offset,x-offset:x+w+offset] 66 | ## Resizing the face_section array into 100x100 67 | face_section = cv2.resize(face_section,(100,100)) 68 | 69 | skip += 1 70 | 71 | ## Store every 10th frame 72 | if skip%10==0: 73 | face_data.append(face_section) 74 | ## how many faces we have captured so far 75 | print(len(face_data)) 76 | 77 | ## Show Frame 78 | cv2.imshow("Frame",frame) 79 | 80 | ##Show the face 81 | cv2.imshow("Face Section",face_section) 82 | 83 | key_pressed = cv2.waitKey(1) & 0xFF 84 | if key_pressed == ord('q'): 85 | break 86 | 87 | # Convert the face list array into a numpy array 88 | face_data = np.asarray(face_data) 89 | ## Number of rows should be same as number of faces ace_data.shape[0] 90 | ## Number of cols should be decided automatically hence we have given -1 91 | 92 | face_data = face_data.reshape((face_data.shape[0],-1)) 93 | print(face_data.shape) 94 | 95 | ## SAVE THIS DATA INTO FILE SYSTEM 96 | ## file_name is the user input 97 | ## face_data is the numpy array that is to be saved 98 | np.save(dataset_path+file_name+'.npy',face_data) 99 | print("Data Successfully save at "+dataset_path+file_name+'.npy') 100 | 101 | cap.release() 102 | cv2.destroyAllWindows() 103 | 104 | ### You will see 2 windows, one is the frame and one is only the face 105 | -------------------------------------------------------------------------------- /Face_Detection_Recognition/face_recognition_knn.py: -------------------------------------------------------------------------------- 1 | ## RECOGNISE FACE USING KNN CLASSIFICATION ALGORITHM 2 | # 1. load the training data (numpy arrays of all the persons) 3 | # x- values are stored in the numpy arrays 4 | # y-values needed to be assigned for each person 5 | # 2. Read a video stream using opencv 6 | # 3. Extract faces out of it, these faces will now be for testing purposes for which we want to predict the label 7 | # 4. Use knn to find the prediction of face (int) 8 | # 5. Map the predicted id to name of the user 9 | # 6. Display the predictions on the screen - bounding box and name 10 | 11 | ##### GOAL OF ALGORITHM : Given a new image, we want to see with whose face it resembles the most ######## 12 | 13 | ##### FACE RECOGNITION ##### 14 | 15 | import cv2 16 | import numpy as np 17 | import os 18 | 19 | ############## KNN ALGORITHM ################## 20 | def distance(v1, v2): 21 | # Eucledian 22 | return np.sqrt(((v1-v2)**2).sum()) 23 | 24 | def knn(train, test, k=5): 25 | dist = [] 26 | 27 | for i in range(train.shape[0]): 28 | # Get the vector and label 29 | ix = train[i, :-1] ## We have used rest of the columns except last column for features 30 | iy = train[i, -1] ## We have used last column for labels 31 | # Compute the distance from test point 32 | d = distance(test, ix) 33 | dist.append([d, iy]) 34 | # Sort based on distance and get top k 35 | dk = sorted(dist, key=lambda x: x[0])[:k] 36 | # Retrieve only the labels 37 | labels = np.array(dk)[:, -1] 38 | 39 | # Get frequencies of each label 40 | output = np.unique(labels, return_counts=True) 41 | # Find max frequency and corresponding label 42 | index = np.argmax(output[1]) 43 | return output[0][index] 44 | 45 | ################################################# 46 | 47 | 48 | ## Initialize Camera 49 | cap = cv2.VideoCapture(0) 50 | 51 | ## Face Detection 52 | face_cascade = cv2.CascadeClassifier("haarcascade_frontalface_alt.xml") 53 | 54 | skip = 0 55 | dataset_path = './data/' 56 | 57 | face_data = [] ## x values of data 58 | labels = [] ## y values of data 59 | 60 | class_id = 0 # Labels for the given file, 1st File that is loaded will have id=0, next will have id=1 and so on.... 61 | names = {} # Mapping between id and name 62 | 63 | 64 | # Data Preparation 65 | for fx in os.listdir(dataset_path): ## iterating over directory 66 | if fx.endswith('.npy'): 67 | #Create a mapping btw class_id and name 68 | names[class_id] = fx[:-4] ## taking all characters before .npy 69 | print("Loaded "+fx) 70 | data_item = np.load(dataset_path+fx) 71 | face_data.append(data_item) 72 | 73 | ## Create Labels for the class 74 | ## for each training point, in each file, we are omputing one label using this -> 75 | target = class_id*np.ones((data_item.shape[0],)) 76 | class_id += 1 77 | labels.append(target) 78 | 79 | ## Concatenating all the items of the list into a single list 80 | face_dataset = np.concatenate(face_data,axis=0) 81 | face_labels = np.concatenate(labels,axis=0).reshape((-1,1)) 82 | 83 | print(face_dataset.shape) 84 | print(face_labels.shape) 85 | 86 | ## KNN Accepts accepts one training matrix in which we should have the x-data and y-data combined in a single matrix 87 | trainset = np.concatenate((face_dataset,face_labels),axis=1) 88 | print('Last Column for Labels and rest of the columns for Features : ') 89 | print(trainset.shape) 90 | 91 | ############### TESTING ##################### 92 | 93 | while True: 94 | ret,frame = cap.read() 95 | if ret == False: 96 | continue 97 | 98 | faces = face_cascade.detectMultiScale(frame,1.3,5) 99 | if(len(faces)==0): 100 | continue 101 | 102 | for face in faces: 103 | x,y,w,h = face 104 | 105 | ## Extracting Face Region of Interest 106 | offset = 10 107 | face_section = frame[y-offset:y+h+offset,x-offset:x+w+offset] 108 | face_section = cv2.resize(face_section,(100,100)) 109 | 110 | #Predicted Label (out) 111 | out = knn(trainset,face_section.flatten()) 112 | 113 | ## Display the name and rectangle around it on the Screen 114 | pred_name = names[int(out)] 115 | cv2.putText(frame,pred_name,(x,y-10),cv2.FONT_HERSHEY_COMPLEX,1,(0,127,255),2,cv2.LINE_AA) 116 | cv2.rectangle(frame,(x,y),(x+w,y+h),(0,0,204),2) 117 | 118 | cv2.imshow("Faces",frame) 119 | 120 | key = cv2.waitKey(1) & 0xFF 121 | if key==ord('q'): 122 | break 123 | 124 | cap.release() 125 | cv2.destroyAllWindows() 126 | 127 | 128 | 129 | 130 | --------------------------------------------------------------------------------