Face key point contour drawing: an effective cross-domain application technology

Table of Contents

1. The importance of contour drawing of facial key points

2. How to find key points on faces

3. Specific implementation of facial key point contour drawing

1. Define the line drawing function

2. Define key point drawing function

3. Positioning of key points

4. Key point drawing

5. Complete code and effect display

4. Summary


1. The importance of drawing the outline of key points on the face

Face contour is one of the important features for face recognition. Through the extraction and comparison of facial contours, applications such as identity verification and face recognition can be realized, and it has extensive application value in security monitoring, public transportation, social networks and other fields. Moreover, facial contour drawing can be used in facial animation, virtual reality, game entertainment and other fields in human-computer interaction. By capturing and simulating the outline of a human face, the facial expressions of characters can be realistically presented, improving the experience and effect of human-computer interaction. Face contour drawing, as an important computer vision and image processing technology, has broad application prospects and value.

2. How to find the key points of the face

In opencv, the following functions are often used to find key points on faces:

cv2.convexHull(points, hull=None, clockwise=None, returnPoints=None)

This function is mainly used to calculate the convex hull of a point set. The details of each parameter are as follows:

  • points: A two-dimensional numpy array containing the input points. Each point should be represented as a tuple, such as (x, y).
  • hull: An optional parameter used to specify the array of output convex hull. If this parameter is not specified, the function creates a new array to store the results.
  • clockwise: An optional Boolean value used to determine the order of point sets. If this parameter is not specified, the function is automatically determined based on the shape of the input point set.
  • returnPoints: An optional Boolean value that determines whether to return points in the convex hull. If this parameter is not specified, the function returns an array containing the convex hull points.

This function receives a set of face key points and returns a two-dimensional numpy array representing the convex hull of these points. This convex hull is the smallest convex polygon that contains all facial key points. This polygon can be used to represent the outer contour of the human face, and then the convex hull marked above is drawn through the drawing function, that is, the outline of the key points of the human face.

3. Specific implementation of facial key point contour drawing

Here, the actual face key point contour drawing demonstration will be carried out through the above functions combined with the drawing function.

1. Define line drawing function
def drawLine(start,end): #Connect the specified points
    pts = np.array(shape[start:end]) # Get the point set and convert the matrix data into array data
    for l in range(1, len(pts)):
        ptA = tuple(pts[l - 1])
        ptB = tuple(pts[l])
        cv2.line(image, ptA, ptB, (0, 255, 0), 2)

Define a function used to draw line segments on the image. After finding the key points of the face, use this function to connect the points with line segments, which forms the outline of the key points of the face. Some of the parameters have the following meanings:

  • pts = np.array(shape[start:end]):Convert the shape subsequence of the array from start to end indexes converted to Numpy arrays. This is done to facilitate subsequent array operations.
  • ptA = tuple(pts[l - 1]):Within the loop, this line gets the coordinates of the previous point and converts them into a tuple for < strong>cv2.line() function is used.
  • cv2.line(image, ptA, ptB, (0, 255, 0), 2):Use cv2.line()Function draws a line segment on an image. The parameters of this function include:
    • image:The image on which to draw the line segment.
    • ptA and ptB:Coordinates (tuple form) of the two endpoints of the line segment.
    • (0, 255, 0): The color of the line segment, expressed here as a tuple in BGR (blue, green, red) format.
    • 2: The thickness of the line segment.

Note: The remaining parameters of the cv2.line(img, pt1, pt2, color, thickness=None, lineType=None, shift=None) line segment drawing function are detailed as follows:

  1. lineType: The type of line segment. This can be a constant, such as cv2.LINE_AA for an anti-aliased line style or cv2.LINE_4 for a four-pixel line style. If not specified, defaults to cv2.LINE_8.
  2. shift: The number of decimal places in the coordinates. If it is positive, then the coordinate value will be multiplied by a power of 10 (for example, if shift=2, then the coordinate value will be multiplied by 100). If it is negative, then the coordinate value will be divided by a power of 10 (for example, if shift=-2, then the coordinate value will be divided by 100). If not specified, defaults to 8.
2. Define key point drawing function
def drawConvexHull(start,end):
    #Construct the specified points into a convex hull and draw it into an outline. Generally, eyes and mouths are drawn using convex hulls.
    Facial = shape[start:end + 1]
    mouthHull = cv2.convexHull(Facial) # Convex hull function
    cv2.drawContours(image, [mouthHull], -1, (0, 255, 0), 2)

Define a function that accepts two parameters (indicating the starting and ending indices of the point set), then extracts the point sets corresponding to these indices, finds the convex hull of these points, and draws this convex hull on the image.

The use of cv2.convexHull has been explained in detail above in this article and will not be described again. Here is a further explanation of the use of cv2.drawContours. First, the complete function is as follows:

cv2.drawContours(image, contours, contourIdx, color, thickness=None, lineType=None, hierarchy=None, maxLevel=None, offset=None)

Each parameter is explained in detail below:

  • contours: This is a list of contours. A contour can be a set of vertices of a polygon, where each contour is a nested list. The outermost list contains all contours, and the inner list represents the polygon vertices of each contour.
  • contourIdx: This parameter is used to select the contour to be drawn on the image. If it is -1, then all contours will be drawn. Otherwise, it should be an integer representing the index of the contour to draw.
  • lineType: This parameter is used to specify the type of outline drawn. Possible values include 8, 4, CV_AAWait. The default value is 8.
  • hierarchy: This parameter is optional and is usually used to store the relationship between contours.
  • maxLevel: This parameter is also optional and is used to limit the number of layers of the drawn outline. If this parameter is provided, only contours with a layer number less than or equal to this parameter will be drawn. The default value is -1, which means drawing all outline layers.
  • offset: This parameter is also optional and is used to offset the outline to a specific position on the image. It should be an (x, y) tuple representing the offset.
3. Key point positioning
image=cv2.imread("teacherli.jpg")
detector = dlib.get_frontal_face_detector()# Construct a face position detector
faces = detector(image, 0)#Detect face box position
#Read the face key point positioning model
predictor = dlib.shape_predictor("shape_predictor_68_face_landmarks.dat")

Among them, some parameters are explained in detail as follows:

  • detector = dlib.get_frontal_face_detector(): Construct a detector for detecting frontal faces. This is a function provided by the dlib library.
  • faces = detector(image, 0): Use the detector created above to detect faces in the image. image is the image to be detected, 0 is an optional parameter, indicating the search for faces in the image starting position. This function returns an array of rectangular objects, each representing a face detected in the image.
  • predictor = dlib.shape_predictor("shape_predictor_68_face_landmarks.dat"): Load a pre-trained model for predicting 68 key points of the face. This model file is usually trained through machine learning and can accurately predict the shape and characteristics of human faces.

By loading an image, then detecting frontal faces in the image, and using a pre-trained model to predict 68 keypoint locations for each detected face. This is very useful in applications such as face recognition, expression analysis, animated character driving, etc.

4. Key point drawing
for face in faces:# Traverse the detected rects one by one
    shape = predictor(image, face) # Get key points
    #Convert the key points into the form of coordinates (x, y)
    shape = np.matrix([[p.x, p.y] for p in shape.parts()])

    drawConvexHull(36,41) # Draw the right eye convex hull
    drawConvexHull(42,47) # Draw the left eye convex hull
    drawConvexHull(48,59) #Draw the external convex hull of the mouth
    drawConvexHull(60,67) # Draw the internal convex hull of the mouth

    drawLine(0,17) # Draw cheek point line
    drawLine(17,22) # Draw the left eyebrow point line
    drawLine(22,27) # Draw the right eyebrow point line
    drawLine(27,36) # Draw nose point line

Keypoints are positioned on the detected faces, and then the convex hulls and line segments of the eyes, mouth, cheeks, eyebrows and nose are drawn using these keypoints through the previously defined keypoint drawing function and line drawing function.

5. Complete code and effect display
import numpy as np
importdlib
import cv2

def drawLine(start,end): #Connect the specified points
    pts = np.array(shape[start:end]) # Get the point set and convert the matrix data into array data
    for l in range(1, len(pts)):
        ptA = tuple(pts[l - 1])
        ptB = tuple(pts[l])
        cv2.line(image, ptA, ptB, (0, 255, 0), 2)

def drawConvexHull(start,end):
    #Construct the specified points into a convex hull and draw it into an outline. Generally, eyes and mouths are drawn using convex hulls.
    Facial = shape[start:end + 1]
    mouthHull = cv2.convexHull(Facial) # Convex hull function
    cv2.drawContours(image, [mouthHull], -1, (0, 255, 0), 2)


image=cv2.imread("teacherli.jpg")

detector = dlib.get_frontal_face_detector()# Construct a face position detector
faces = detector(image, 0)#Detect face box position

#Read the face key point positioning model
predictor = dlib.shape_predictor("shape_predictor_68_face_landmarks.dat")

for face in faces: #Get the key points of each face (implement detection)
    shape=predictor(img, face)# Get key points
    #Convert the key points into the form of coordinates (x, y)
    landmarks = np.matrix([[p.x, p.y] for p in shape.parts()])
    #Draw the key points of each face (draw each point in the shape)
    for idx, point in enumerate(landmarks):
        pos = (point[0, 0], point[0, 1])# The coordinates of the current key
        # Draw a solid circle for the current key point
        cv2.circle(img, pos, 2, color=(0, 255, 0))
        font = cv2.FONT_HERSHEY_SIMPLEX # Font
        cv2.putText(img, str(idx), pos, font, 0.4, (255, 255, 255), 1, cv2.LINE_AA)

for face in faces:# Traverse the detected rects one by one
    shape = predictor(image, face) # Get key points
    #Convert the key points into the form of coordinates (x, y)
    shape = np.matrix([[p.x, p.y] for p in shape.parts()])

    drawConvexHull(36,41) # Draw the right eye convex hull
    drawConvexHull(42,47) # Draw the left eye convex hull
    drawConvexHull(48,59) #Draw the external convex hull of the mouth
    drawConvexHull(60,67) # Draw the internal convex hull of the mouth

    drawLine(0,17) # Draw cheek point line
    drawLine(17,22) # Draw the left eyebrow point line
    drawLine(22,27) # Draw the right eyebrow point line
    drawLine(27,36) # Draw nose point line

cv2.imshow("Frame", image)
cv2.waitKey()
cv2.destroyAllWindows()

The original picture is as follows:

Key point contour drawing renderings:

4. Summary

Face key point contour drawing technology is one of the important applications in the field of computer vision and will continue to receive widespread attention and research in the future. As learners, we need to continuously learn relevant knowledge in depth, strengthen practical application capabilities, and contribute to the development of this field.