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.

## Overview

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:

1. Load the XML file of required classifiers.
2. Load image in gray-scale mode as OpenCV mostly operates in gray scale.
3. 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

## Detecting Face

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

#4 corrdinates in faces
for (x_face, y_face, w_face, h_face) in face:

# ears
ear_width= w_face

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[0], img_ear.shape[0])
min_w= min(roi_ear.shape[1], img_ear.shape[1])
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

#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() 

## Conclusion

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.

-Suniti Jain

$${}$$