Python OpenCv realizes real-time face recognition and face distance measurement

Python OpenCv realizes real-time face recognition and face ranging

prepare
Before the development of facial ranging, first install four libraries in your Python, namely cvzone library, mediapipe library, tensorflow library and tensorflow GPU library. It is faster to install cvzone library and mediapipe library. You can install them quickly by using the following statement directly

pip install cvzone
pip install mediapipe

When installing the tensorflow library and tensorflow GPU library, because the library file is large, the conventional installation method often fails to download halfway. Here, the following command is recommended. I have tested it myself and can install it quickly.

pip install -i https://pypi.tuna.tsinghua.edu.cn/simple tensorflow
pip install -i https://pypi.tuna.tsinghua.edu.cn/simple tensorflow-gpu

After ensuring that the above four libraries are installed successfully, you can start writing code.

principle
OpenCv realizes face ranging mainly by using the principle of similar triangle, as shown in the figure below

Parameter Description:
(1) The focal length f of the camera is fixed;
(2) W is the pixel distance of human eyes after camera imaging. The pixel distance w of human eyes can be measured after the face grid is recognized by findFaceMesh();
(3) W is the distance between the left eye and the right eye in reality. The average pupil distance of men is 64mm and that of women is 62mm. The middle value of 63mm is taken for the development of this project;
(4) d is the distance from the actual person to the camera that you want to obtain. Through the principle of similar triangle, the distance formula from the person to the camera can be calculated after transforming the formula: d=(f*W)/w

Note:
Different cameras have different focal lengths. If you know that the parameters of the camera itself are the best, you can directly substitute them for accurate calculation. If you don't know the camera parameters, you need to manually correct and determine the focal length f for many times. Manual correction needs to measure several more data, and then calculate the mean value to ensure the accuracy of focal length f, so as to improve the ranging accuracy. For manual correction, first fix the distance between an eye and the camera, such as 50cm, measure accurately with a tape measure, and measure several times to find the focal length F. The specific code of measuring focal length f is shown below:

import cv2
import cvzone
from cvzone.FaceMeshModule import FaceMeshDetector   #Import detector

## Here is the import camera
cap = cv2.VideoCapture(0)
detector = FaceMeshDetector(maxFaces = 1)  #Detect faces and only one face. The last 1 means that only one face can be detected at most

while True:
    success,img = cap.read()
    img,faces = detector.findFaceMesh(img,draw = False)    #After we find the face, we will return to the face = false

    if faces:      #If faces are available
        ##Find the two points of the left eye and the right eye through the following statement
        face = faces[0]   #First stage
        pointLeft = face[145]     #The value on the left is basically 145
        pointRight = face[374]    #The value on the right is basically 374
        
        ###The following is the process of finding the focal length
        ##Find distance in pixels
        w,_ = detector.findDistance(pointLeft,pointRight)    #Assign the distance from the position of the left eye point to the position of the right eye point to W. the underline after w ignores other values
        W = 6.3   #This is the distance between the left eye and the right eye of the human eye, which is 63mm. Taking the middle value, it is 64mm for men and 62mm for women
        d = 50    #The distance is assumed to be 50cm
        f = (w * d) / W     #Substitute the formula for the focal length into
        print(f)

    cv2.imshow("Iamge",img)
    cv2.waitKey(1)

Measure the focal length f several times through the above code to find the average. The focal length of the camera I use is 300, so f = 300 in my code later. Here, substitute the measurement according to my actual focal length. Next, the focal length f is substituted into the measurement formula d = (f*W) / w, and the specific code is shown below:

import cv2
import cvzone
from cvzone.FaceMeshModule import FaceMeshDetector   #Import detector

## Here is the import camera
cap = cv2.VideoCapture(0)
detector = FaceMeshDetector(maxFaces = 1)  #Face detection

while True:
    success,img = cap.read()
    img,faces = detector.findFaceMesh(img,draw = False)    #Make a detector, find the face grid, and return the image (img) and our faces. draw = False. With this sentence, we can't see the grid

    if faces:      #If faces are available
        ##Find the two points of the left eye and the right eye through the following statement
        face = faces[0]   #First stage
        pointLeft = face[145]     #The value on the left is basically 145
        pointRight = face[374]    #The value on the right is basically 374
        ##Here is the distance between the two points of the eye
        # cv2.line(img, pointLeft, pointRight, (0, 200, 0), 3)  # Draw a line between the two points of the eye. The starting point is pointLeft and the ending point is pointRight. The line color is green and the line width is 3
        # cv2.circle(img,pointLeft,5,(255,0,255),cv2.FILLED)     #Draw a circle on the img image. The center point is pointLeft, the radius is 5, and the color is purple. The final running result can mark purple dots in the left eye of the imager
        # cv2.circle(img,pointRight,5,(255,0,255),cv2.FILLED)    #Draw a circle on the img image. The center point is pointRighe, the radius is 5, and the color is purple. The final running result can mark purple dots in the right eye of the imager

        w, _ = detector.findDistance(pointLeft, pointRight)  # Assign the distance from the position of the left eye point to the position of the right eye point to W. the underline after w ignores other values
        W = 6.3  # This is the distance between the left eye and the right eye of the human eye, which is 63mm. Taking the middle value, it is 64mm for men and 62mm for women

        ###Find distance
        ##According to the above formula f = (w * d) / W, it can be roughly measured that when the human eye is 50cm away from the camera, the focal length of the camera is about 300
        ##Then substitute the found focal length into the formula for calculating the distance, and the distance can be calculated
        f = 300
        d = (W * f) / w
        print(d)

        ##The following is the text of the distance, which follows the face and is output at the forehead position
        cvzone.putTextRect(img,f'Depth:{int(d)}cm',(face[10][0]-95,face[10][1]-5),scale = 1.8)   #The distance text is displayed on the image in the form of string, with the unit of cm. The position of the text value is displayed on the forehead following the movement of the human face (the id on the forehead is 10, that is, face[10], the following face[10][0] represents the first element and face[10][1] represents the second element),
        ##scale = 2 above indicates the size of the output text box on the picture
        ##face[10][0] changes the left and right, and face[10][1] changes the height of the display

    cv2.imshow("Iamge",img)
    cv2.waitKey(1)

The final test results are as follows:

See the following code for multi person simultaneous ranging. I haven't optimized it yet. When multi person simultaneous ranging, it will float and be unstable.

import cv2
import cvzone
from cvzone.FaceMeshModule import FaceMeshDetector  #Import detector

## Here is the import camera
cap = cv2.VideoCapture(0)
detector = FaceMeshDetector(maxFaces=3)

while True:
    sucess,img = cap.read()
    img,faces1 = detector.findFaceMesh(img)
    img,faces2 = detector.findFaceMesh(img)
    img,faces3 = detector.findFaceMesh(img)
    W = 6.3  # This is the distance between the left eye and the right eye of the human eye, which is 63mm. Taking the middle value, it is 64mm for men and 62mm for women
    
    if faces1:      #If a face is detected
        face1 = faces1[0]
        pointLeft1 = face1[145]   #The face value of the left eye is 145
        pointRight1 = face1[374]  #The face value of the right eye is 374

        ##Here is the distance between two eyes
       # cv2.line(img,pointLeft1,pointRight1,(0,200,0),3)   #In the eyes
       # cv2.circle(img,pointLeft1,5,(255,0,255),cv2.FILLED)   #Draw a circle on the img image, the center point is pointLeft, the radius is 5, and the color is purple
        #cv2.circle(img,pointRight1,5,(255,0,255),cv2.FILLED)  #Draw a circle on the img image, the center point is pointRight, the radius is 5, and the color is purple

        w1, _ = detector.findDistance(pointLeft1, pointRight1)  # Assign the position distance from the left eye to the right eye of the first face to w1. The underline after w1 indicates that other values are ignored
        ###Find distance
        ##According to the above formula f = (w * d) / W, it can be roughly measured that when the human eye is 50cm away from the camera, the focal length of the camera is about 300
        ##Then substitute the found focal length into the formula for calculating the distance, and the distance can be calculated
        f = 300
        d1 = (W * f) / w1

        cvzone.putTextRect(img, f'Depth:{int(d1)}cm', (face1[10][0] - 95, face1[10][1] - 5), scale = 1.8)

        if faces2:    ##This means that when the first face is tested, if the second face appears again, the mark will be displayed
            face2 = faces2[0]
            pointLeft2 = face2[145]  # The face value of the left eye is 145
            pointRight2 = face2[374]  # The face value of the right eye is 374

            #cv2.line(img, pointLeft2, pointRight2, (0, 200, 0), 3)  # In the eyes
           # cv2.circle(img, pointLeft2, 5, (255, 0, 255), cv2.FILLED)  # Draw a circle on the img image, the center point is pointLeft, the radius is 5, and the color is purple
           # cv2.circle(img, pointRight2, 5, (255, 0, 255), cv2.FILLED)  # Draw a circle on the img image, the center point is pointRight, the radius is 5, and the color is purple

            w2,_ = detector.findDistance(pointLeft2,pointRight2)  #Assign the position distance from the left eye to the right eye of the first face to w1. The underline after w1 indicates that other values are ignored
            ###Find distance
            ##According to the above formula f = (w * d) / W, it can be roughly measured that when the human eye is 50cm away from the camera, the focal length of the camera is about 300
            ##Then substitute the found focal length into the formula for calculating the distance, and the distance can be calculated
            f = 300
            d2 = (W * f) / w2

            cvzone.putTextRect(img, f'Depth:{int(d2)}cm', (face2[10][0] - 95, face2[10][1] - 5), scale=1.8)

            if faces3:
                face3 = faces3[0]
                pointLeft3 = face3[145]  # The face value of the left eye is 145
                pointRight3 = face3[374]  # The face value of the right eye is 374

               # cv2.line(img, pointLeft3, pointRight3, (0, 200, 0), 3)  # In the eyes
              #  cv2.circle(img, pointLeft3, 5, (255, 0, 255), cv2.FILLED)  # Draw a circle on the img image, the center point is pointLeft, the radius is 5, and the color is purple
               # cv2.circle(img, pointRight3, 5, (255, 0, 255), cv2.FILLED)  # Draw a circle on the img image, the center point is pointRight, the radius is 5, and the color is purple

                w3, _ = detector.findDistance(pointLeft3, pointRight3)  # Assign the position distance from the left eye to the right eye of the first face to w1. The underline after w1 indicates that other values are ignored
                ###Find distance
                ##According to the above formula f = (w * d) / W, it can be roughly measured that when the human eye is 50cm away from the camera, the focal length of the camera is about 300
                ##Then substitute the found focal length into the formula for calculating the distance, and the distance can be calculated
                f = 300
                d3 = (W * f) / w2

                cvzone.putTextRect(img, f'Depth:{int(d3)}cm', (face3[10][0] - 95, face3[10][1] - 5), scale=1.8)
                
    cv2.imshow("img",img)
    cv2.waitKey(1)

The above is the process of realizing face recognition and face ranging through Python OpenCv. I wish all researchers more articles and less hair loss!

Keywords: Python OpenCV TensorFlow

Added by hollyspringer on Thu, 10 Feb 2022 16:49:06 +0200