diff --git a/Face_Recognition/README.md b/Face_Recognition/README.md new file mode 100644 index 0000000000..7566cdde42 --- /dev/null +++ b/Face_Recognition/README.md @@ -0,0 +1,46 @@ +# Face Recognition using OpenCV's Builtin Recognizer + +## About This Project + +Aim: This script recognizes the face in from video stream. + +## Implementation + +Captures images from your webcam video stream +Extracts all Faces from the image frame (using haarcascades) +Stores the Face information into numpy arrays + +1. Read and show video stream, capture images +2. Detect Faces and show bounding box (haarcascade) +3. Flatten the largest face image(gray scale) and save in a numpy array +4. Repeat the above for multiple people to generate training data + +Recognise faces using some classification algo - logistic, KNN, SVM etc. + +1. Read a video stream using opencv +2. extract faces out of it +3. load the training data(numpy array of all the persons) + a. x-values are stored in numpy arrays + b. y-values we need to assign for each person +4. use knn to find the prediction of face(int) +5. map the predicted id to name of the user +6. display the predictions on the screen - bounding box and name + +## Application + +Using this script we can recognize the faces in the running videos (frame by frame). Face recognition is also useful in human computer interaction, virtual reality, database recovery, multimedia, computer entertainment, information security. + +## How To Run + +To run the script use following commands + +1. Get the required modules + ```bash + pip install -r requirements.txt + ``` + +2. Get multiple images of multiple person from face_data_collect.py and save them in numpy array. + +3. Run the face_recognition.py + + diff --git a/Face_Recognition/cv_video_read.py b/Face_Recognition/cv_video_read.py new file mode 100644 index 0000000000..397dcb7978 --- /dev/null +++ b/Face_Recognition/cv_video_read.py @@ -0,0 +1,21 @@ +# Read a video Stream from Camera ( Frame by frame ) + +import cv2 +cap = cv2.VideoCapture(0) +while True: + ret, frame = cap.read() + gray_frame = cv2.cvtColor(frame,cv2.COLOR_BGR2GRAY) + if ret==False: + continue + + cv2.imshow("Video Frame", frame) + cv2.imshow("gray frame", gray_frame) + + # wait for user inqut -q, then u will stop the loop + + key_pressed = cv2.waitKey(1) & 0xFF + if key_pressed == ord('q'): + break + +cap.release() +cv2.destroyAllWindows() diff --git a/Face_Recognition/face_data_collect.py b/Face_Recognition/face_data_collect.py new file mode 100644 index 0000000000..61870dba71 --- /dev/null +++ b/Face_Recognition/face_data_collect.py @@ -0,0 +1,72 @@ +# Write a Python Script that captures images from your webcam video stream +# Extracts all Faces from the image frame (using haarcascades) +# Stores the Face information into numpy arrays + +# 1. Read and show video stream, capture images +# 2. Detect Faces and show bounding box (haarcascade) +# 3. Flatten the largest face image(gray scale) and save in a numpy array +# 4. Repeat the above for multiple people to generate training data + + +import cv2 +import numpy as np + +#Init Camera +cap = cv2.VideoCapture(0) + +# Face Detection +face_cascade = cv2.CascadeClassifier("haarcascade_frontalface_alt.xml") + +skip = 0 +face_data = [] +dataset_path = './data/' +file_name = input("Enter the name of the person : ") +while True: + ret,frame = cap.read() + + if ret==False: + continue + + gray_frame = cv2.cvtColor(frame,cv2.COLOR_BGR2GRAY) + + + faces = face_cascade.detectMultiScale(frame,1.3,5) + if len(faces)==0: + continue + + faces = sorted(faces,key=lambda f:f[2]*f[3]) + + # Pick the last face (because it is the largest face acc to area(f[2]*f[3])) + for face in faces[-1:]: + x,y,w,h = face + cv2.rectangle(frame,(x,y),(x+w,y+h),(0,255,255),2) + + #Extract (Crop out the required face) : Region of Interest + offset = 10 + face_section = frame[y-offset:y+h+offset,x-offset:x+w+offset] + face_section = cv2.resize(face_section,(100,100)) + + skip += 1 + if skip%10==0: + face_data.append(face_section) + print(len(face_data)) + + + cv2.imshow("Frame",frame) + cv2.imshow("Face Section",face_section) + + key_pressed = cv2.waitKey(1) & 0xFF + if key_pressed == ord('q'): + break + +# Convert our face list array into a numpy array +face_data = np.asarray(face_data) +face_data = face_data.reshape((face_data.shape[0],-1)) +print(face_data.shape) + +# Save this data into file system +np.save(dataset_path+file_name+'.npy',face_data) +print("Data Successfully save at "+dataset_path+file_name+'.npy') + +cap.release() +cv2.destroyAllWindows() diff --git a/Face_Recognition/face_detection.py b/Face_Recognition/face_detection.py new file mode 100644 index 0000000000..d4dc7f8b93 --- /dev/null +++ b/Face_Recognition/face_detection.py @@ -0,0 +1,35 @@ +# Read a video Stream from Camera ( Frame by frame ) + +import cv2 +cap = cv2.VideoCapture(0) +face_cascade = cv2.CascadeClassifier("haarcascade_frontalface_alt.xml") # classifier +while True: + ret, frame = cap.read() # we read 1 img + gray_frame = cv2.cvtColor(frame,cv2.COLOR_BGR2GRAY) + if ret==False: + continue +# now we read the img + # (gray_frame, scaling factor, no of neighbors) + faces = face_cascade.detectMultiscale(gray_frame,1.3,5) # 1.3 means img will shrink by 30% + cv2.imshow("Video Frame",frame) + for (x,y,w,h) in faces: + cv2.rectangle(frame,(x,y),(x+w,y+h),(255,0,0),2) + # (frame , coordinates , opposite coordinate of rect , color , boundries) + key_pressed = cv2.waitKey(1) & 0xFF # wait for user inqut -q, then u will stop the loop + if key_pressed == ord('q'): + break + +cap.release() +cv2.destroyAllWindows() + + + + +""" Scaling Factor -- parameter specifying how much the image size is reduced at each image scale. Basically the scale factor is used to create your scale pyaramid. +1.05 is a good possible value for this, which means you use a small step for resizing i.e. reduce size + +Min Neighh -- Parameter specifying how many neigh each candidate rectangle should have to retain it. +this parameter will affect the quality of the detected faces. Higher value results in less detection but with higher quality. 3~6 is a good value for it. """ + +''' detectMultiscale() - if the imag has 2 faces then this method going to returns the coordinates, the starting of the face (x1,y1), width, height +then there are multiple faces present then it will return tuple of [(x,y,w,h)] ''' \ No newline at end of file diff --git a/Face_Recognition/face_recognition.py b/Face_Recognition/face_recognition.py new file mode 100644 index 0000000000..1778964b25 --- /dev/null +++ b/Face_Recognition/face_recognition.py @@ -0,0 +1,204 @@ +''' +Recognise faces using some classification algo - logistic, KNN, SVM etc. + +1. Read a video stream using opencv +2. extract faces out of it +3. load the training data(numpy array of all the persons) + a. x-values are stored in numpy arrays + b. y-values we need to assign for each person +4. use knn to find the prediction of face(int) +5. map the predicted id to name of the user +6. display the predictions on the screen - bounding box and name +''' +import cv2 +import numpy as np +import os + +########## KNN CODE ############ +def distance(v1, v2): + # Eucledian + return np.sqrt(((v1-v2)**2).sum()) + +def knn(train, test, k=5): + dist = [] + + for i in range(train.shape[0]): + # Get the vector and label + ix = train[i, :-1] + iy = train[i, -1] + # Compute the distance from test point + d = distance(test, ix) + dist.append([d, iy]) + # Sort based on distance and get top k + dk = sorted(dist, key=lambda x: x[0])[:k] + # Retrieve only the labels + labels = np.array(dk)[:, -1] + + # Get frequencies of each label + output = np.unique(labels, return_counts=True) + # Find max frequency and corresponding label + index = np.argmax(output[1]) + return output[0][index] +################################ + + +#Init Camera +cap = cv2.VideoCapture(0) + +# Face Detection +face_cascade = cv2.CascadeClassifier("haarcascade_frontalface_alt.xml") + +skip = 0 +dataset_path = './data/' + +face_data = [] +labels = [] + +class_id = 0 # Labels for the given file +names = {} #Mapping btw id - name + + +# Data Preparation +for fx in os.listdir(dataset_path): + if fx.endswith('.npy'): + #Create a mapping btw class_id and name + names[class_id] = fx[:-4] + print("Loaded "+fx) + data_item = np.load(dataset_path+fx) + face_data.append(data_item) + + #Create Labels for the class + target = class_id*np.ones((data_item.shape[0],)) + class_id += 1 + labels.append(target) + +face_dataset = np.concatenate(face_data,axis=0) +face_labels = np.concatenate(labels,axis=0).reshape((-1,1)) + +print(face_dataset.shape) +print(face_labels.shape) + +trainset = np.concatenate((face_dataset,face_labels),axis=1) +print(trainset.shape) + +# Testing + +while True: + ret,frame = cap.read() + if ret == False: + continue + + faces = face_cascade.detectMultiScale(frame,1.3,5) + if(len(faces)==0): + continue + + for face in faces: + x,y,w,h = face + + #Get the face ROI + offset = 10 + face_section = frame[y-offset:y+h+offset,x-offset:x+w+offset] + face_section = cv2.resize(face_section,(100,100)) + + #Predicted Label (out) + out = knn(trainset,face_section.flatten()) + + #Display on the screen the name and rectangle around it + pred_name = names[int(out)] + cv2.putText(frame,pred_name,(x,y-10),cv2.FONT_HERSHEY_SIMPLEX,1,(255,0,0),2,cv2.LINE_AA) + cv2.rectangle(frame,(x,y),(x+w,y+h),(0,255,255),2) + + cv2.imshow("Faces",frame) + + key = cv2.waitKey(1) & 0xFF + if key==ord('q'): + break + +cap.release() +cv2.destroyAllWindows() + +import numpy as np +import cv2 +import os + +def distance(v1, v2): + return np.sqrt(((v1-v2)**2).sum()) + +def knn(train, test, k=5): + dist = [] + + for i in range(train.shape[0]): + ix = train[i, :-1] + iy = train[i, -1] + d = distance(test, ix) + dist.append([d, iy]) + dk = sorted(dist, key=lambda x: x[0])[:k] + labels = np.array(dk)[:, -1] + output = np.unique(labels, return_counts=True) + index = np.argmax(output[1]) + return output[0][index] + + +cap = cv2.VideoCapture(0 ) + +# Face Detection +face_cascade = cv2.CascadeClassifier("haarcascade_frontalface_alt.xml") + +skip = 0 +dataset_path = './data/' +face_data = [] +labels = [] +class_id = 0 +names ={} # mapping between id - name + + +# Data preparation +for fx in os.listdir(dataset_path): + if fx.endswith('.npy'): + names[class_id] = fx[:-4] + print("Loaded "+fx) + data_item = np.load(dataset_path+fx) + face_data.append(data_item) + + # create labels + target = class_id*np.ones((data_item.shape[0],)) + class_id+=1 + labels.append(target) + +face_dataset = np.concatenate(face_data, axis=0) +face_labels = np.concatenate(labels,axis=0) + +print(face_dataset.shape) +print(face_labels.shape) +trainset = np.concatenate((face_dataset,face_labels),axis=1) +print(trainset.shape) + + + +while True: + ret,frame = cap.read() + + if ret==False: + continue + + faces = face_cascade.detectMultiScale(frame,1.3,5) + + for face in faces[-1:]: + x,y,w,h = face + offset = 10 + face_section = frame[y-offset:y+h+offset,x-offset:x+w+offset] + face_section = cv2.resize(face_section,(100,100)) + out = knn(trainset,face_section.flatten()) + pred_name = names[int(out)] + cv2.putText(frame,pred_name,(x,y-10),cv2.FONT_HERSHEY_SIMPLEX,1,(255,0,0),2,cv2.LINE_AA) + cv2.rectangle(frame,(x,y),(x+w,y+h),(0,255,255),2) + + cv2.imshow("Faces", frame) + + + + key_pressed = cv2.waitKey(1) & 0xFF + if key_pressed == ord('q'): + break +cap.release() +cv2.destroyAllWindows()

AltStyle によって変換されたページ (->オリジナル) /