Welcome to MicroROS V2 Robot Car repository
6. Facial Special Effects
Face Effects
1. Experiment Objective
Use the dlib 68-point facial landmark detection model to add AR effects such as eye filling, lip beautification and eyebrow highlighting to the face.
2. Experiment Principle
1. Key Terms
| Keyword | Description |
|---|---|
| dlib 68 points | The classic 68 facial landmark model, covering eyebrows (10 points), eyes (12 points), nose (9 points), lips (20 points) and jawline (17 points) |
| Eye filling | Extracts an ROI from the eye contour landmarks (36-47) and fills the pupil region with a semi-transparent color |
| Lip beautification | Extracts an ROI from the lip contour landmarks (48-67) and applies color overlay and blur for beautification |
2. Technical Architecture
Terminal 1: start agent + camera + joint modelsTerminal 2: start face effects
3. Experiment Steps
1. Hardware Preparation
| Hardware | Requirement |
|---|---|
| PTZ version | ✅ Supported |
| No-PTZ version | ✅ Supported |
| Required peripherals | ESP32 camera |
2. Start the agent + camera + joint models (Terminal 1)
xxxxxxxxxxros2 launch microros_v2_bringup car_base.launch.py
3. Start face effects (Terminal 2)
xxxxxxxxxxros2 launch microros_v2_mediapipe_pkg face_landmarks.launch.py4. Observed Results
- The face is annotated with 68 cyan landmarks
- The eye region is filled with semi-transparent blue, and the lip region is beautified with a pink overlay
- The eyebrow region is highlighted

5. Code Walkthrough
Source code paths:
- Launch:
~/microros_ws/src/microros_v2_mediapipe_pkg/launch/face_landmarks.launch.py- Node:
~/microros_ws/src/microros_v2_mediapipe_pkg/microros_v2_mediapipe_pkg/FaceLandmarks.py
1. Core Node Analysis
x# Source file: ~/microros_ws/src/microros_v2_mediapipe_pkg/microros_v2_mediapipe_pkg/FaceLandmarks.pyclass FaceLandmarks(Node): def __init__(self): super().__init__("face_landmarks_node") self.detector = dlib.get_frontal_face_detector() self.predictor = dlib.shape_predictor("shape_predictor_68_face_landmarks.dat") def image_callback(self, msg): frame = self.bridge.imgmsg_to_cv2(msg, 'bgr8') gray = cv.cvtColor(frame, cv.COLOR_BGR2GRAY) faces = self.detector(gray) for face in faces: landmarks = self.predictor(gray, face) # Eye ROI (landmarks 36-47) eye_pts = np.array([[landmarks.part(n).x, landmarks.part(n).y] for n in range(36, 48)], np.int32) cv.fillPoly(overlay, [eye_pts], (255, 0, 0)) # Lip ROI (landmarks 48-67) lip_pts = np.array([[landmarks.part(n).x, landmarks.part(n).y] for n in range(48, 68)], np.int32) cv.fillPoly(overlay, [lip_pts], (255, 0, 255)) frame = cv.addWeighted(frame, 0.7, overlay, 0.3, 0) cv.imshow(self.window_name, frame)Key logic:
dlib.shape_predictor("shape_predictor_68_face_landmarks.dat"): loads the 68-point model file- Eye landmark indices 36-47 (12 points, 6 per eye); lip indices 48-67 (20 points)
cv.fillPolydraws filled polygons on the overlay layer, andcv.addWeightedblends them with the original image at 0.3 opacity- dlib 68 points vs MediaPipe Face Mesh 468 points: dlib is lighter and starts faster; the 468-point mesh is finer but more computationally expensive
2. Key Parameters
Parameter definition files:
- Launch:
~/microros_ws/src/microros_v2_mediapipe_pkg/launch/face_landmarks.launch.py- Node:
~/microros_ws/src/microros_v2_mediapipe_pkg/microros_v2_mediapipe_pkg/FaceLandmarks.py
| Parameter | Type | Default | Description |
|---|---|---|---|
predictor_path | string | shape_predictor_68_face_landmarks.dat | Path to the 68-point model file |
3. Node Description
| Node | Function |
|---|---|
face_landmarks_node | dlib 68-point detection + eye/lip/eyebrow effect overlay |
6. Frequently Asked Questions
| Issue | Cause | Solution |
|---|---|---|
| Model fails to load | The 68-point .dat file is missing | Verify that shape_predictor_68_face_landmarks.dat exists |