Example Code for MicroPython-Face Detection

Last revision 2026/01/22

This example demonstrates how to use the ESP32-P4 to detect human faces in an image. The ESP32-P4 will mark the detected faces and save the annotated image as a new file.

Hardware Preparation

Software Preparation

Usage steps

This example demonstrates how to use the ESP32-P4 to detect human faces in an image. The ESP32-P4 will mark the detected faces and save the annotated image as a new file.

  1. Upload the face.jpg file to the ESP32-P4.
  2. Run the script to view the position information of the detected faces.
  3. Click the Stop/Restart Backend Process button to view the marked image on the MicroPython device.

face.jpg

Sample Code

from espdl import FaceDetector
from jpeg import Decoder, Encoder

decoder = Decoder()
encoder = Encoder(width=320, height=240, pixel_format="RGB888")
face_detector = FaceDetector()

# Capture and process the image
img = open("face.jpg", "rb").read()  # Capture the original image (usually in JPEG format)
framebuffer = decoder.decode(img)  # Convert to RGB888 format
# Convert memoryview to bytearray for modification
framebuffer = bytearray(framebuffer)
# Run face detection
results = face_detector.run(framebuffer)

# Draw bounding box
def draw_rectangle(buffer, width, height, x, y, w, h, list1, color=(255, 0, 0)):
    """
    Draw a rectangular bounding box on an RGB888 format image buffer
    :param buffer: Image buffer
    :param width: Image width
    :param height: Image height
    :param x: X-coordinate of the top-left corner of the bounding box
    :param y: Y-coordinate of the top-left corner of the bounding box
    :param w: Width of the bounding box
    :param h: Height of the bounding box
    :param color: Bounding box color (in RGB format)
    """
    # Helper function: Set color for a single pixel
    def set_pixel(buffer, width, x, y, color):
        offset = (y * width + x) * 3
        buffer[offset] = color[0]  # R (Red channel)
        buffer[offset + 1] = color[1]  # G (Green channel)
        buffer[offset + 2] = color[2]  # B (Blue channel)

    # Helper function: Draw a larger dot
    def draw_large_dot(buffer, width, x, y, color, size=3):
        for i in range(x - size, x + size + 1):
            for j in range(y - size, y + size + 1):
                if 0 <= i < width and 0 <= j < height:
                    set_pixel(buffer, width, i, j, color)

    # Draw top edge of the bounding box
    for i in range(x, x + w):
        if 0 <= i < width and 0 <= y < height:
            set_pixel(buffer, width, i, y, color)

    # Draw bottom edge of the bounding box
    for i in range(x, x + w):
        if 0 <= i < width and 0 <= y + h < height:
            set_pixel(buffer, width, i, y + h, color)

    # Draw left edge of the bounding box
    for j in range(y, y + h):
        if 0 <= j < height and 0 <= x < width:
            set_pixel(buffer, width, x, j, color)

    # Draw right edge of the bounding box
    for j in range(y, y + h):
        if 0 <= j < height and 0 <= x + w < width:
            set_pixel(buffer, width, x + w, j, color)

    # Draw feature points
    if list1:
        draw_large_dot(buffer, width, list1[0], list1[1], (0, 0, 255), size=2)
        draw_large_dot(buffer, width, list1[2], list1[3], (0, 0, 255), size=2)
        draw_large_dot(buffer, width, list1[4], list1[5], (0, 255, 0), size=2)
        draw_large_dot(buffer, width, list1[6], list1[7], (255, 0, 0), size=2)
        draw_large_dot(buffer, width, list1[8], list1[9], (255, 0, 0), size=2)

# Draw bounding boxes for detected faces on the image
for face in results:
    print(face)
    x1, y1, x2, y2 = face['box']
    draw_rectangle(framebuffer, 320, 240, x1, y1, x2 - x1, y2 - y1, face['features'], color=(255, 0, 0))  # Use red bounding box

# Re-encode the image with bounding boxes to JPEG format and save
marked_img = encoder.encode(framebuffer)
with open("face_marked.jpg", "wb") as f:
    f.write(marked_img)

Result

Result

Marked Result

Marked Result

Was this article helpful?

TOP