Hello Guys ! Today I will be showing the process of drawing Delaunay triangles on face on live Webcam. I will be using OpenCV and Dlib modules of python for this project. So in case you have not installed these libraries I would suggest you to install them. Now before moving further lets first deal with this scary term “DELAUNAY TRIANGULATION” .
So What are Delaunay Triangles ?
A Delaunay triangulation for a given set P of discrete points in a plane is a triangulation DT(P) such that no point in P is inside the circumcircle of any triangle in DT(P). Delaunay triangulations maximize the minimum angle of all the angles of the triangles in the triangulation; they tend to avoid sliver triangles. The triangulation is named after Boris Delaunay for his work on this topic from 1934.
For a set of points on the same line there is no Delaunay triangulation (the notion of triangulation is degenerate for this case). For four or more points on the same circle (e.g., the vertices of a rectangle) the Delaunay triangulation is not unique: each of the two possible triangulations that split the quadrangle into two triangles satisfies the “Delaunay condition”, i.e., the requirement that the circumcircles of all triangles have empty interiors.
OK GOT IT..BUT WHAT DELAUNAY HAS TO DO WITH HUMAN FACES ?
We can use Delaunay triangulation to mark sectors of vital points of human faces. This methodology is used widely for face warping, face swapping etc.
Enough Talks ! Show me how it is done.
Below is the code for drawing delaunay triangles on your webcam feed in Python.
from imutils import face_utils import numpy as np import dlib import cv2 import random import time #Initialise Webcam cap = cv2.VideoCapture(0) time.sleep(3) # Added few seconds of sleep to get the camera heated detector = dlib.get_frontal_face_detector() #Initialise dlib face detector #Make sure you download the dlib weight file in the same directory predictor = dlib.shape_predictor('shape_predictor_68_face_landmarks.dat') # Check if a point is inside a rectangle def rect_contains(rect, point): if point[0] < rect[0]: return False elif point[1] < rect[1]: return False elif point[0] > rect[2]: return False elif point[1] > rect[3]: return False return True #Function to draw circular point on image def draw_point(img, p, color ) : cv2.circle( img, p, 1, color, -1, cv2.LINE_AA, 0 ) # Function to draw delaunay triangles def draw_delaunay(img, subdiv, delaunay_color ) : triangleList = subdiv.getTriangleList(); size = img.shape r = (0, 0, size[1], size[0]) for t in triangleList : pt1 = (t[0], t[1]) pt2 = (t[2], t[3]) pt3 = (t[4], t[5]) if rect_contains(r, pt1) and rect_contains(r, pt2) and rect_contains(r, pt3) : cv2.line(img, pt1, pt2, delaunay_color, 1, cv2.LINE_AA, 0) cv2.line(img, pt2, pt3, delaunay_color, 1, cv2.LINE_AA, 0) cv2.line(img, pt3, pt1, delaunay_color, 1, cv2.LINE_AA, 0) if __name__ == __main__ : while (cap.isOpened()): # Read webcam feed ret, image = cap.read() # Flipped the image to avoid mirror effect image = np.flip(image, axis=1) gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) rects = detector(gray, 1) for (i, rect) in enumerate(rects): shape = predictor(gray, rect) shape = face_utils.shape_to_np(shape) img_orig = image.copy(); size = image.shape rect = (0, 0, size[1], size[0]) subdiv = cv2.Subdiv2D(rect); # Insert points into subdiv for p in shape: subdiv.insert((p[0],p[1])) # Draw delaunay triangles draw_delaunay(image, subdiv, (255, 255, 255)); # Draw points for p in shape: draw_point(image, (p[0],p[1]), (0, 0, 255)) # Show results out.write(image) cv2.imshow("Delaunay Triangle", image) if cv2.waitKey(1) & 0xFF == ord('q'): break cap.release() out.release() cv2.destroyAllWindows()
Result :-
That was simple enough right ! For any clarifications regarding this code please do comment below. I will see you in the next tutorial, till then keep Coding and Stay Safe 🙂 .
References :-
https://www.learnopencv.com/delaunay-triangulation-and-voronoi-diagram-using-opencv-c-python/
https://en.wikipedia.org/wiki/Delaunay_triangulation