Face orientor using RTSP camera

28 Views Asked by At

My face orientation detection code is detecting orientation of face but at near distance to camera only. How can i detect the orientation of face at the far distance to rtsp camera also?

Below is my code.

import cv2
import dlib
import imutils
import numpy as np

class FaceOrienter:
    def __init__(self):
        self.detect = dlib.get_frontal_face_detector()
        self.predict = dlib.shape_predictor(
            "shape_predictor_68_face_landmarks.dat")  # Dat file is the crux of the code
        self.frame_skip = 5
    @staticmethod
    def draw_line(frame, a, b, color=(255, 255, 0)):
        cv2.line(frame, a, b, color, 10)

    def orient(self):
        cap = cv2.VideoCapture('rtsp url')

        frame_count=0
        while True:
            ret, frame = cap.read()
            if frame_count % self.frame_skip != 0:
                frame_count += 1
                continue

            frame = imutils.resize(frame, width=600)
            gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
            subjects = self.detect(gray, 0)
            for subject in subjects:
                landmarks = self.predict(gray, subject)

                size = frame.shape
                # 2D image points. If you change the image, you need to change vector
                image_points = np.array([
                    (landmarks.part(33).x, landmarks.part(33).y), 
                    (landmarks.part(8).x, landmarks.part(8).y),
                    (landmarks.part(36).x, landmarks.part(36).y),
                    (landmarks.part(45).x, landmarks.part(45).y),
                    (landmarks.part(48).x, landmarks.part(48).y),
                    (landmarks.part(54).x, landmarks.part(54).y)  # Right mouth corner
                ], dtype="double")
 
                # 3D model points.
                model_points = np.array([
                    (0.0, 0.0, 0.0),  # Nose tip
                    (0.0, -330.0, -65.0),  # Chin
                    (-225.0, 170.0, -135.0),  # Left eye left corner
                    (225.0, 170.0, -135.0),  # Right eye right corner
                    (-150.0, -150.0, -125.0),  # Left Mouth corner
                    (150.0, -150.0, -125.0)  # Right mouth corner

                ])
                # Camera internals
                focal_length = size[1]
                center = (size[1] / 2, size[0] / 2)
                camera_matrix = np.array(
                    [[focal_length, 0, center[0]],
                     [0, focal_length, center[1]],
                     [0, 0, 1]], dtype="double"
                )

                dist_coeffs = np.zeros((4, 1))  # Assuming no lens distortion
                (success, rotation_vector, translation_vector) = cv2.solvePnP(model_points, image_points, camera_matrix,
                                                                              dist_coeffs)

                (b1, jacobian) = cv2.projectPoints(np.array([(350.0, 270.0, 0.0)]), rotation_vector, translation_vector,
                                                   camera_matrix, dist_coeffs)
                (b2, jacobian) = cv2.projectPoints(np.array([(-350.0, -270.0, 0.0)]), rotation_vector,
                                                   translation_vector, camera_matrix, dist_coeffs)
                (b3, jacobian) = cv2.projectPoints(np.array([(-350.0, 270, 0.0)]), rotation_vector, translation_vector,
                                                   camera_matrix, dist_coeffs)
                (b4, jacobian) = cv2.projectPoints(np.array([(350.0, -270.0, 0.0)]), rotation_vector,
                                                   translation_vector, camera_matrix, dist_coeffs)

                (b11, jacobian) = cv2.projectPoints(np.array([(450.0, 350.0, 400.0)]), rotation_vector,
                                                    translation_vector, camera_matrix, dist_coeffs)
                (b12, jacobian) = cv2.projectPoints(np.array([(-450.0, -350.0, 400.0)]), rotation_vector,
                                                    translation_vector, camera_matrix, dist_coeffs)
                (b13, jacobian) = cv2.projectPoints(np.array([(-450.0, 350, 400.0)]), rotation_vector,
                                                    translation_vector, camera_matrix, dist_coeffs)
                (b14, jacobian) = cv2.projectPoints(np.array([(450.0, -350.0, 400.0)]), rotation_vector,
                                                    translation_vector, camera_matrix, dist_coeffs)

                b1 = (int(b1[0][0][0]), int(b1[0][0][1]))
                b2 = (int(b2[0][0][0]), int(b2[0][0][1]))
                b3 = (int(b3[0][0][0]), int(b3[0][0][1]))
                b4 = (int(b4[0][0][0]), int(b4[0][0][1]))

                b11 = (int(b11[0][0][0]), int(b11[0][0][1]))
                b12 = (int(b12[0][0][0]), int(b12[0][0][1]))
                b13 = (int(b13[0][0][0]), int(b13[0][0][1]))
                b14 = (int(b14[0][0][0]), int(b14[0][0][1]))

                self.draw_line(frame, b1, b3)
                self.draw_line(frame, b3, b2)
                self.draw_line(frame, b2, b4)
                self.draw_line(frame, b4, b1)

                self.draw_line(frame, b11, b13)
                self.draw_line(frame, b13, b12)
                self.draw_line(frame, b12, b14)
                self.draw_line(frame, b14, b11)

                self.draw_line(frame, b11, b1, color=(0, 255, 0))
                self.draw_line(frame, b13, b3, color=(0, 255, 0))
                self.draw_line(frame, b12, b2, color=(0, 255, 0))
                self.draw_line(frame, b14, b4, color=(0, 255, 0))

            cv2.imshow("Frame", frame)
            key = cv2.waitKey(1) & 0xFF
            if key == ord("q"):
                break
            frame_count += 1 
        cv2.destroyAllWindows()
        cap.release()

if __name__ == '__main__':
    face = FaceOrienter()
    face.orient()

I am expecting to get the orientation detection at the far distances also.

0

There are 0 best solutions below