Hey there !! Getting bored in this lockdown ?? Then why don’t you explore your creativity by creating an amazing filter that adds up bunny years to your face. Sounds amazing, right? Wanna know how? Then, let’s get started!!!
The trick is quite simple, our agorithm will first be detecting your face and then adds the bunny ears and save your filtered image.
The underlying concept used here is Computer Vision and Image Processing.
Here we’ll be using haar cascade file and OpenCV library.
Haar cascades can be used for face detection which is a machine learning algorithm where a cascade function is trained from a lot of positive and negative images. It is then used to detect objects in other images.
OpenCV already contains many pre-trained Haar classifiers such as smile which is used in this model.
To apply these pre-trained classifiers, follow the following steps:
- Load the XML file of required classifiers.
- Load image in gray-scale mode as OpenCV mostly operates in gray scale.
- Apply necessary classifiers on the image.
Importing necessary libraries
We’ll be using four main libraries of python.
- “cv2” for video capturing, frame reading, pixel management, color management of the video,
- “NumPy” which is used to do mathematical manipulation with the pixels of the video, flipping the order of matrices,
- “datetime” for saving date and time and adding delays and
- “os” for performing operations on directory.
import cv2 for reading the image import datetime import os import numpy as np
Now, we’ll detect the face using the cascade file. We need to load the required XML classifiers. Then load our input image (or video) in grayscale mode.
cascade_face = cv2.CascadeClassifier('haarcascade_frontalface_default.xml') # if you want to add sticker on image img = cv2.imread('image.png')
Function to detect the face
Now, we’ll find the face in the image. If faces are found, it returns the positions of detected faces as Rect(x,y,w,h). Once we get these locations, we can create a ROI for the face and apply smile detection on this ROI.
I have created a detection function that takes two arguments: the image and the grayscale i.e. black and white image. I have used haar cascade to detect the face and stored the result in face variable. x_face, y_face, w_face, h_face are 2 top coordinates and width , depth of face respectively. In the loop, we are importing the ear image and defining the area of interest in grayscale and coloured image.
def detection(grayscale, img): #1.3 is the scale factor , 5 is te min neighbours face = cascade_face.detectMultiScale(grayscale, 1.3, 5) #4 corrdinates in faces for (x_face, y_face, w_face, h_face) in face: # ears ear_width= w_face img_ear= cv2.imread('bunny2.png',-1) h,w,c= img_ear.shape ratio= ear_width/w w= int(w*ratio) d= int(h*ratio) img_ear= cv2.resize(img_ear, (w,d)) roi_ear= img[y_face-d: y_face,x_face:x_face+w] min_d= min(roi_ear.shape, img_ear.shape) min_w= min(roi_ear.shape, img_ear.shape) roi_ear= img[y_face-min_d: y_face,x_face:x_face+min_w] img_ear= img_ear[0: min_d,0: min_w] bg = img[y_face-min_d: y_face,x_face:x_face+min_w] sg = np.atleast_3d(255 - img_ear[:, :, 3])/255.0 np.multiply(bg, sg, out=bg, casting="unsafe") np.add(bg, 255-img_ear[:, :, 0:3] * np.atleast_3d(img_ear[:, :, 3]), out=bg) # put the changed image back into the scene img[y_face-min_d: y_face,x_face:x_face+min_w] = bg #return image return img
We are then resizing the ear_image according to the width of the face and maintaining the aspect ratio.We are defining the area of interest of image of person and crop the two images to maintain the dimensions.
Numpy provides the powerful data structure known as n-d array and function to manipulate that n-d array. This data structure is used by other library to represent complex data such as images. Therefore we have used numpy function to parse the image of tongue and replace the white colour by black. Note that white coordinates are [255,255,255] and black coordinates as [0, 0, and 0]. It will create a 3d array of all the pixel values sane as that of ear_image.We are multiplying the image and adding them and storing the value in the bg variable.
Capturing the Image and calling the function to add sticker
Now, I have created a variable to capture the video and set the path to store the output file. If the file already exists, then we update the path therefore, the code is placed in try catch block to handle these exceptions.
vc = cv2.VideoCapture(0) #path path= os.getcwd() # Create directory dirName = 'tempimage_folder' try: os.mkdir(dirName) except FileExistsError: print("Directory " , dirName , " already exists") path= path+'/'+dirName
Now, after creating the directory, we have to capture the image and convert it into grayscale using cv2.cvtColour() function.Then, we’ll pass the arguments in detection function and store the result in final variable.
After getting the result we’ll display the image using cv2.imshow() function and then save image with name and current date and time appended. We’ll save the file using the cv2.imwrite() function which writes the next video frame.
cnt=0 while cnt<500: #read status of camera and frame _, img = vc.read() #convert image ot grayscale grayscale = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) #reuslt from detection function final = detection(grayscale, img) #showing captured image cv2.imshow('Video', final) #name of our image, wiht current time , so that it has new name each time. string = "pic"+str(datetime.datetime.now())+".jpg" #save image cv2.imwrite(os.path.join(path, string),final) if cv2.waitKey(1) & 0xFF == ord('q'): break cnt+=1 vc.release() cv2.destroyAllWindows()
Yaayyy, we have implemented our own tool to add bunny ear sticker on the face. If you like my work, please feel free to share it and also share your views in comments section.