|
| 1 | +import cv2 |
| 2 | +import mediapipe as mp |
| 3 | +import time |
| 4 | + |
| 5 | + |
| 6 | +class FaceMeshDetector: |
| 7 | + def __init__( |
| 8 | + self, staticMode=False, maxFaces=2, minDetectionCon=0.5, minTrackCon=0.5 |
| 9 | + ): |
| 10 | + # Initialize parameters |
| 11 | + self.staticMode = staticMode # Use static mode or not |
| 12 | + self.maxFaces = maxFaces # Maximum number of faces to detect |
| 13 | + self.minDetectionCon = minDetectionCon # Minimum detection confidence |
| 14 | + self.minTrackCon = minTrackCon # Minimum tracking confidence |
| 15 | + |
| 16 | + # Initialize MediaPipe drawing tools and face mesh model |
| 17 | + self.mpDraw = mp.solutions.drawing_utils # Drawing utilities |
| 18 | + self.mpFaceMesh = mp.solutions.face_mesh # Face mesh module |
| 19 | + self.faceMesh = self.mpFaceMesh.FaceMesh( |
| 20 | + static_image_mode=self.staticMode, |
| 21 | + max_num_faces=self.maxFaces, |
| 22 | + min_detection_confidence=self.minDetectionCon, |
| 23 | + min_tracking_confidence=self.minTrackCon, |
| 24 | + ) |
| 25 | + |
| 26 | + self.drawSpec = self.mpDraw.DrawingSpec( |
| 27 | + thickness=1, circle_radius=2 |
| 28 | + ) # Drawing specifications |
| 29 | + |
| 30 | + def findFaceMesh(self, img, draw=True): |
| 31 | + # Convert the image to RGB |
| 32 | + self.imgRGB = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) |
| 33 | + # Process the image to detect face mesh |
| 34 | + self.results = self.faceMesh.process(self.imgRGB) |
| 35 | + faces = [] # Store detected facial landmarks |
| 36 | + if self.results.multi_face_landmarks: |
| 37 | + for faceLms in self.results.multi_face_landmarks: |
| 38 | + if draw: |
| 39 | + # Draw the face mesh |
| 40 | + self.mpDraw.draw_landmarks( |
| 41 | + img, |
| 42 | + faceLms, |
| 43 | + self.mpFaceMesh.FACEMESH_TESSELATION, |
| 44 | + self.drawSpec, |
| 45 | + self.drawSpec, |
| 46 | + ) |
| 47 | + face = [] # Store landmarks for a single face |
| 48 | + for id, lm in enumerate(faceLms.landmark): |
| 49 | + ih, iw, ic = img.shape # Get image dimensions |
| 50 | + x, y = int(lm.x * iw), int( |
| 51 | + lm.y * ih |
| 52 | + ) # Convert normalized coordinates to pixel coordinates |
| 53 | + face.append([x, y]) # Add landmark coordinates |
| 54 | + faces.append(face) # Add to faces list |
| 55 | + return img, faces # Return image and facial landmarks |
| 56 | + |
| 57 | + |
| 58 | +def main(): |
| 59 | + # Open the video file |
| 60 | + cap = cv2.VideoCapture( |
| 61 | + "E:\\Advance Computer Vision with Python\\main\\Chapter 3 Face Detection\\Videos\\4.mp4" |
| 62 | + ) |
| 63 | + pTime = 0 # Previous frame time |
| 64 | + detector = FaceMeshDetector(maxFaces=2) # Initialize face mesh detector |
| 65 | + while True: |
| 66 | + success, img = cap.read() |
| 67 | + if not success: |
| 68 | + break |
| 69 | + img, faces = detector.findFaceMesh(img) # Detect face mesh |
| 70 | + if len(faces) != 0: |
| 71 | + print(faces[0]) # Print landmarks of the first face |
| 72 | + cTime = time.time() # Current time |
| 73 | + fps = 1 / (cTime - pTime) # Calculate frames per second |
| 74 | + pTime = cTime # Update previous frame time |
| 75 | + cv2.putText( |
| 76 | + img, f"FPS: {int(fps)}", (20, 70), cv2.FONT_HERSHEY_PLAIN, 3, (0, 255, 0), 3 |
| 77 | + ) # Display FPS on the image |
| 78 | + cv2.namedWindow("Image", cv2.WINDOW_NORMAL) # Create a resizable window |
| 79 | + cv2.imshow("Image", img) # Show image |
| 80 | + cv2.waitKey(1) # Wait for keyboard input |
| 81 | + |
| 82 | + |
| 83 | +if __name__ == "__main__": |
| 84 | + main() |
0 commit comments