Add special effects (HAT) to the face in the picture

Add special effects (HAT) to the face in the picture

Face effect process and principle disassembly

1 data preparation

First, prepare the hat and face photos and load them into the project directory

2 face detection

Firstly, call the library function in OpenCV to detect the face of the photo and get the parameter values of the face rectangle, so as to get the position of the hat. Due to the different size and position of the face photo and the hat photo, when we want to splice the two photos, we have to take the upper part of the face, that is, the part of the forehead (as shown in the figure below)

Then re plan the size of the hat according to this size.

3 grayscale hat

Because we want to get the stitching appearance of two photos, we must use another image processing function of OpenCV to operate by pixel or phase, so we need to prepare two photos: 1 color hat, black background, 2 black hat, human forehead and color background
Therefore, we can reduce the scale of the problem by gray binarization. Because RGB is useless here, retention will increase the complexity of the problem, so we turn the hat image into gray.

4 threshold hat

After the graying operation, change the hat into black and white, similar to 0 and 1 (255), all 0 is black. We may wish to specify that when the gray value is greater than 10, it is recognized as white.

5 remove the reverse hat

As the name suggests, the photos with white hat and black background become black hat and white background. Why do you do this? Don't look at the next step.

6 match the black hat and white background with the face pixels

Using OpenCV's pixel by pixel and operation, you can get the next picture by comparing the picture obtained in the previous step with the person's forehead picture shown before

7 match the white hat with the black background and the colored hat

The following figure can be obtained by comparing the picture of the white hat with the black background obtained in the previous steps with the color hat picture with the same scale

Some partners may say that there is any difference between this picture and the hat picture prepared at the beginning. The only difference is that the size of this picture is a perfect match with the intercepted picture of people's forehead.

8 compare the results of the previous two steps or

This step can also solve the confusion of small and medium-sized partners in the previous step. Only two pictures with exactly the same size can be matched or matched. The final picture effect is shown in the figure below

Then assign this part of the image directly to the original face image in the corresponding position to get the final style image.

after effects

The main difference between here and the above is to transfer the processing of pictures to the processing of video. The method is very simple, that is, take out some equally spaced frames in the video for operations similar to picture processing. Here, the code is directly printed, and the comments are clearly marked.

# -*- coding:utf-8 -*-
Date: October 24, 2021
import cv2  # opencv library for image processing
import math  # Mathematical operation Library
import dlib  # Load dlib algorithm module
import argparse  # Load parsing module

def hat_face(opt):
    # Loading dlib's own face detection model
    detector = dlib.get_frontal_face_detector()
    # Read pictures of hat styles
    img_hat = cv2.imread(opt.hat_path)
    # Use the VideoCapture function in opencv to read the video
    cap = cv2.VideoCapture(opt.video_path)
    # Initialize definition frame_id to facilitate frame skipping later
    frame_id = 0
    # Judge whether the cap is read successfully
    while cap.isOpened():
        # Because of video capture, N frames of pictures may be collected per second, so use the read function to read pictures frame by frame
        # ret returns True or Fasle, indicating whether the picture is read
        # frame returns the read picture information
        ret, frame =
        # If ok is false, the collection ends
        if not ret:
            # Printout, prompt information
            print("Camera cap over!")
        # frame_id plus 1 for frame skipping
        frame_id += 1
        # If frame_ If the ID divided by 10 is not equal to 0, it will continue to cycle. Only when it is equal to 0, the following display steps will be carried out, so as to achieve the effect of frame skipping
        # Because in the algorithm processing, for example, there are 25 images per second, in order to improve the project speed, it is not necessary to perform algorithm processing on each frame
        # Note: the 10 here can be set by yourself. If you think the frame skipping is too slow, you can set it larger, such as 15
        if not int(frame_id) % 10 == 0: continue
        # Face detection is performed on the read original image
        faceRects = detector(frame)
        # If len (faces) > 0, it indicates that there are faces in the picture
        if len(faceRects) > 0:
            # There may be multiple faces in the picture. Traverse and output the position information of each face in turn, and add the Rabbit Hat special effect at a specific position
            for box_info in faceRects:
                # The face position information detected by dlib is of rectangle type, so x0 and Y0 in the upper left corner and X1 and Y1 in the lower right corner of the face frame can be extracted through left(), top(), right(), bottom().
                x0, y0, width_face, height_face = box_info.left(),, box_info.right() - box_info.left(), box_info.bottom() -
                # Get the height of the hat picture_ Hat, width_hat, easy to control the size of the hat display at the back
                height_hat, width_hat = img_hat.shape[0], img_hat.shape[1]
                # Change the height of the hat to fit the size of the detected face
                imgComposeSizeH = int(height_hat / width_hat * width_face)
                # Because the hat is above the face, when the face is close to the top of the video, in order to ensure that the hat can be displayed, the height of the hat defaults to the distance from the face to the top of the video
                if imgComposeSizeH > (y0 - 20):
                    imgComposeSizeH = (y0 - 20)
                # Normalize the picture of the hat to the appropriate width and height. The width is the width of the face and the height is the height of the hat adjusted above
                imgComposeSize = cv2.resize(img_hat, (width_face, imgComposeSizeH), interpolation=cv2.INTER_NEAREST)
                # In order to achieve the forehead above the face, add the Rabbit Hat effect, just stick the rabbit hat to the forehead
                # Note: Y0 is the Y coordinate of the top left vertex of the face detection frame, and y0-20 is almost located at the forehead. Subtract imgComposeSizeH to adjust the height of the rabbit hat
                #      That is, fitting the rabbit hat from this position can realize the special effect of face hat
                top = (y0 - 20 - imgComposeSizeH)
                # When the face is too close to the top of the picture, it may be negative through the calculation in the previous line, so when this happens, top is set to 0
                if top <= 0:
                    top = 0
                # Get the new height of the hat after resizing_ hat_ New, new width_hat_new
                height_hat_new, width_hat_new = imgComposeSize.shape[0], imgComposeSize.shape[1]
                # Cut out the corresponding hat area above the forehead
                # Note: it is usually used to extract small images from large images. For example, if the coordinates of the small image to be intercepted are [x0, y0, x1, y1], use img[y0:y1,x0:x1].
                small_img_hat = frame[top:top + height_hat_new, x0:x0 + width_hat_new]
                # To view the effect of the previous line, you can cv2.imwrite ahead#Cancel. After running, save to this directory for viewing
                # cv2.imwrite("small_img_hat.jpg",small_img_hat)
                # The hat image is converted from RGB color image to gray image
                small_img_hat_gray = cv2.cvtColor(imgComposeSize, cv2.COLOR_RGB2GRAY)
                # To view the effect of the previous line, you can cv2.imwrite ahead#Cancel. After running, save to this directory for viewing
                # cv2.imwrite("small_img_hat_gray.jpg", small_img_hat_gray)
                # Thresholding processing to pick out the image in the interval of 10 < pixels < 255
                # Because the background is black, the hat area can be extracted by setting the threshold value of 10 to 255
                ret, mask_hat = cv2.threshold(small_img_hat_gray, 10, 255, cv2.THRESH_BINARY)
                # To view the effect of the previous line, you can cv2.imwrite ahead#Cancel. After running, save to this directory for viewing
                # cv2.imwrite("mask_hat.jpg", mask_hat)
                # Use the reverse operation to change the image of the hat from black 0 to white 255 and white 255 to black 0
                mask_hat_inv = cv2.bitwise_not(mask_hat)
                # To view the effect of the previous line, you can cv2.imwrite ahead#Cancel. After running, save to this directory for viewing
                # cv2.imwrite("mask_hat_inv.jpg", mask_hat_inv)
                # Use the bitwise and operation to add the extracted hat area and the inverted hat image
                img1_bg = cv2.bitwise_and(small_img_hat, small_img_hat, mask=mask_hat_inv)
                # To view the effect of the previous line, you can cv2.imwrite ahead#Cancel. After running, save to this directory for viewing
                # cv2.imwrite("img1_bg.jpg", img1_bg)
                # Using bitwise and operation, pick out the RGB area of the hat with pixel value between [10255]
                img2_fg = cv2.bitwise_and(imgComposeSize, imgComposeSize, mask=mask_hat)
                # To view the effect of the previous line, you can cv2.imwrite ahead#Cancel. After running, save to this directory for viewing
                # cv2.imwrite("img2_fg.jpg", img2_fg)
                # Set img1_bg and img2_fg adds up to the image of the area with the hat on
                dst = cv2.add(img1_bg, img2_fg)
                # To view the effect of the previous line, you can cv2.imwrite ahead#Cancel. After running, save to this directory for viewing
                # cv2.imwrite("dst.jpg", dst)
                # Fit the local area with the hat onto the original image
                frame[top:top + height_hat_new, x0:x0 + width_hat_new] = dst
                # To view the effect of the previous line, you can cv2.imwrite ahead#Cancel. After running, save to this directory for viewing
                # cv2.imwrite("img.jpg", img)
        # Many times, the length and width of the picture are too large, and the screen display is incomplete
        # In order to view the picture easily, you can scale the size of the picture to a certain size, such as (800600), that is, 800 pixels wide and 600 pixels high
        img = cv2.resize(frame, (800, 600))
        # display picture
        cv2.imshow("image", img)
        # Display the pause time of the picture. If it is 0, it will be displayed all the time. If it is 100, 100ms is displayed

if __name__ == '__main__':
    # Create a new parser
    parser = argparse.ArgumentParser()
    # Add options for the parser, such as video_path to add the video address. (after default, add the video path to be read)
    # Note: if you need to capture the real-time video collected by the camera of this computer, you can set default = 0 (note that it is not default='0 ')
    # Note: different videos may have different width, height and size. You can debug the value in cv2.resize and modify the size of the display window according to your own video proportion.
    parser.add_argument('--video_path', default='', help='path of cap video')
    # Add options for the parser, such as hat_path, add the address of the hat picture, and try to replace other styles of hats. (after default, add the path to read the hat picture)
    parser.add_argument('--hat_path', default="maozi.png", help='path of hat image')
    # Parameters for parsing options
    opt = parser.parse_args()
    # Call hat_ The face function adds a hat effect to the face in the video

The style diagram of a frame is attached below


It's the last work of this week, and it ends after turning off the lights. How time flies. We only have one life. We need to think about how to choose the right things for ourselves in a limited life, and strive to make them our own style and leave their own traces. Planning and execution are always the most important par
Goodbye, my dear friend!
Best wishes!
Hope everything work out!

Pay attention to me, like coin and collection, AI learning and life do not get lost!

Tags: Python OpenCV AI Computer Vision image processing

Posted on Sun, 24 Oct 2021 12:15:07 -0400 by [PQ3]RogeR