Python and get a camera with real-time control face

Implementation process
obtained from the camera video stream, and converted to an image of one, and then passes the information to the image processing library opencv this tool returns a grayscale image (just as you use the same local static picture)

After the program starts, according to the listener information, use a while loop, continue to load the video image, and then returned to the opencv tool presents image information.

Create a keyboard event listener, press the "d" key, then began to perform face matching, and mask loading (this process is dynamic, you can move at any time).

Face matching using the face detection algorithm Dlib in to see if there is a face present. If so, it will create an end position, glasses and cigarette ends will move there for everyone to face.

Then we need to scale and rotate our glasses to suit everyone's face. We will use the center to find the eyes and mouth from the point set Dlib model returns 68 points and rotate the space between them.

After we finally get real-time location of cigarettes and glasses, glasses and cigarette into the top of the screen, began to match your glasses and mouth.

If there is no human face, the program will return directly to your video information will not have the effect of moving the mask.

The default is a period of 4 seconds. Then you can "d" key test again.

Exit the program using "q" key.

Here I will this functionality is abstracted into a mask loading service, please follow my code to see what all of it.
1. Import corresponding toolkit

 

from time import sleep

import cv2
import numpy as np
from PIL import Image
from imutils import face_utils, resize

try:
    from dlib import get_frontal_face_detector, shape_predictor
except ImportError:
    raise


Create a mask to load its corresponding service class DynamicStreamMaskService initialization properties:

 

DynamicStreamMaskService class (Object):
    "" "
    dynamic adhesive mask service
    " ""

    __init __ DEF (Self, saved = False):
        self.saved = # saved to save pictures
        self.listener = True # startup parameters
        self.video_capture = cv2.VideoCapture (0) # call local camera
        self.doing = False # whether face mask
        self.speed = 0.1 # mask moving speed
        self.detector = get_frontal_face_detector () # face recognizer
        self.predictor = shape_predictor ( "shape_predictor_68_face_landmarks.dat") # facial analyzer
        self.fps = 4 there is a time period based # mask
        self. animation_time = 0 # initial value of the animation cycle
        self.duration = self.fps * 4 # animation cycle maximum
        self.fixed_time = # 4 after drawing, the residence time
        self.max_width = 500 # image size
        self.deal, self.text, self .cigarette = None, None, None # mask objects


According to the above introduction, we first realize read function video stream into the picture:

 

read_data DEF (Self):
    "" "
    acquires a video stream from the camera, and the image is converted into a frame
    : return: Returns information about an image of a
    " ""
    _, = self.video_capture.read Data ()
    return data


Next, we realize face location function, and location of glasses and cigarette:

 

def get_glasses_info(self, face_shape, face_width):
    """
    获取当前面部的眼镜信息
    :param face_shape:
    :param face_width:
    :return:
    """
    left_eye = face_shape[36:42]
    right_eye = face_shape[42:48]

    left_eye_center = left_eye.mean(axis=0).astype("int")
    right_eye_center = right_eye.mean(axis=0).astype("int")

    y = left_eye_center[1] - right_eye_center[1]
    x = left_eye_center[0] - right_eye_center[0]
    eye_angle = np.rad2deg(np.arctan2(y, x))

    deal = self.deal.resize(
        (face_width, int(face_width * self.deal.size[1] / self.deal.size[0])),
        resample=Image.LANCZOS)

    deal = deal.rotate(eye_angle, expand=True)
    deal = deal.transpose(Image.FLIP_TOP_BOTTOM)

    left_eye_x = left_eye[0, 0] - face_width // 4
    left_eye_y = left_eye[0, 1] - face_width // 6

    return {"image": deal, "pos": (left_eye_x, left_eye_y)}

def get_cigarette_info(self, face_shape, face_width):
    """
    获取当前面部的烟卷信息
    :param face_shape:
    :param face_width:
    :return:
    """
    mouth = face_shape[49:68]
    mouth_center = mouth.mean(axis=0).astype("int")
    cigarette = self.cigarette.resize(
        (face_width, int(face_width * self.cigarette.size[1] / self.cigarette.size[0])),
        resample=Image.LANCZOS)
    x = mouth[0, 0] - face_width + int(16 * face_width / self.cigarette.size[0])
    y = mouth_center[1]
    return {"image": cigarette, "pos": (x, y)}

def orientation(self, rects, img_gray):
    """
    人脸定位
    :return:
    """
    faces = []
    for rect in rects:
        face = {}
        face_shades_width = rect.right() - rect.left()
        predictor_shape = self.predictor(img_gray, rect)
        face_shape = face_utils.shape_to_np(predictor_shape)
        face['cigarette'] = self.get_cigarette_info(face_shape, face_shades_width)
        face['glasses'] = self.get_glasses_info(face_shape, face_shades_width)

        faces.append(face)

    return faces


We have just mentioned the keyboard to listen to events, where we realize what this function:

 

listener_keys DEF (Self):
    "" "
    Set keyboard monitor events
    : return:
    " ""
    Key = cv2.waitKey (1) & 0xFF
    IF Key == ord ( "q"):
        self.listener = False
        self.console ( " the program exits ")
        SLEEP (1)
        self.exit ()

    if key == ord("d"):
        self.doing = not self.doing


Next we come to realize function to load the mask information:

 

def init_mask(self):
    """
    加载面具
    :return:
    """
    self.console("加载面具...")
    self.deal, self.text, self.cigarette = (
        Image.open(x) for x in ["images/deals.png", "images/text.png", "images/cigarette.png"]
    )


The basic functions of the above are implemented, we realize drawing function, and the function principle and before I wrote the essay with AI face recognition technology to achieve vibrato effect is the same, I will not go into details, you can go github Python Chinese community or the public micro-channel number view.

 

def drawing(self, draw_img, faces):
    """
    画图
    :param draw_img:
    :param faces:
    :return:
    """
    for face in faces:
        if self.animation_time < self.duration - self.fixed_time:
            current_x = int(face["glasses"]["pos"][0])
            current_y = int(face["glasses"]["pos"][1] * self.animation_time / (self.duration - self.fixed_time))
            draw_img.paste(face["glasses"]["image"], (current_x, current_y), face["glasses"]["image"])

            cigarette_x = int(face["cigarette"]["pos"][0])
            cigarette_y = int(face["cigarette"]["pos"][1] * self.animation_time / (self.duration - self.fixed_time))
            draw_img.paste(face["cigarette"]["image"], (cigarette_x, cigarette_y),
                           face["cigarette"]["image"])
        else:
            draw_img.paste(face["glasses"]["image"], face["glasses"]["pos"], face["glasses"]["image"])
            draw_img.paste(face["cigarette"]["image"], face["cigarette"]["pos"], face["cigarette"]["image"])
            draw_img.paste(self.text, (75, draw_img.height // 2 + 128), self.text)


Since it is a service class that the function has started and quit it, and finally we have to write about it.

Simply describe the start () function, according to the initialization information after start listening to continuously monitor the video stream and stream information is converted into an image by opencv displayed.
And call the function key listener constantly monitor whether you press the "d" key to load the mask, if the listener is successful, the image face detection, and move the mask,
and the end of a sustained period of time, this time based on your mask the movement of facial movement. The final rendering of the article at the top of the picture.

def start(self):
    """
    启动程序
    :return:
    """
    self.console("程序启动成功.")
    self.init_mask()
    while self.listener:
        frame = self.read_data()
        frame = resize(frame, width=self.max_width)
        img_gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
        rects = self.detector(img_gray, 0)
        faces = self.orientation(rects, img_gray)
        draw_img = Image.fromarray(cv2.cvtColor(frame, cv2.COLOR_BGR2RGB))
        if self.doing:
            self.drawing(draw_img, faces)
            self.animation_time += self.speed
            self.save_data(draw_img)
            if self.animation_time > self.duration:
                self.doing = False
                self.animation_time = 0
            else:
                frame = cv2.cvtColor(np.asarray(draw_img), cv2.COLOR_RGB2BGR)
        cv2.imshow("hello mask", frame)
        self.listener_keys()

def exit(self):
    """
    程序退出
    :return:
    """
    self.video_capture.release()
    cv2.destroyAllWindows()


Finally, let's try:

 

if __name__ == '__main__':
    ms = DynamicStreamMaskService()
    ms.start()


I write to you, this little feature has been achieved, we may as well use something to look at.

 

--------------------- 

Guess you like

Origin www.cnblogs.com/ly570/p/10942301.html