SaraKIT is an easy-to-use face analysis solution for Raspberry Pi 4 CM4, powered by state-of-the-art algorithms based on MediaPipe from Google. It provides robust functionality for face detection, face landmark detection, and face mesh processing, specifically optimized for the Raspberry Pi 64-bit platform.

 

MediaPipe Face Landmarker

The MediaPipe Face Landmarker task enables the detection of face landmarks and facial expressions in real-time images and videos. It empowers various applications such as facial expression analysis, facial filters and effects, and virtual avatar creation. This task outputs 3D face landmarks, blendshape scores (coefficients representing facial expressions), and transformation matrices for seamless real-time rendering of detailed facial surfaces.

To utilize SaraKIT for face analysis, follow these steps:

  1. Clone repository, compile the code by running the command 'make' and execute the program:
    git clone https://github.com/SaraEye/SaraKIT-MediaPipe-Face-Detection-Face-Mesh-Face-Landmark-Raspberry-Pi-64bit FaceDetection
    cd FaceDetection
    make
    ./FaceDetection


  2. The program captures frames from the camera, processes them, and sends the output.
  3. Preview the operation in your web browser by accessing the Raspberry Pi's IP address followed by port 7777 (e.g., http://raspberrypi:7777/ or http://192.168.1.16:7777).
    If you have the Linux Desktop version and want to display the image from the camera in a window, change this line:
    init_viewer(ViewMode::Camera0,ViewMode::Processed, 1, true, false);
  4. The browser preview displays one or two images side by side, where the content of each image can be customized. By default, the left image shows the camera preview, while the right image displays the detected face along with face landmarks. Refer to the video below for a similar visualization.

Both the standard Raspberry Pi MMAL functions and OpenCV (slightly slower) functions can be used to capture frames from the camera.

#include <iostream>
#include <signal.h>
#include <stdio.h>
#include <math.h>
#include <arm_neon.h>
#include "unistd.h"

#include "struct.hpp"
#include "lib/viewer/viewer.hpp"
#include "lib/mediapipe/Mediapipe.hpp"

using namespace std;
 
cv::Mat frame0, frame0Gray, frame0GrayHalf, frame0GrayHalfEdge; // cam0
cv::Mat frame1, frame1Gray, frame1GrayHalf, frame1GrayHalfEdge; // cam1
cv::Mat imgProcessed;

ViewerStatus viewStatus;

//ctrl-c 
void ctrlc_handler(sig_atomic_t s){
    printf("\nCaught signal %d\n",s);
    control_c=true;
    exit(1);
}

int main(int argc, char** argv){
    signal(SIGINT,ctrlc_handler);
	
	camwidth=640;
	camheight=480;

    imgProcessed=cv::Mat(camheight, camwidth, CV_8UC3);

    init_camera(0, camwidth, camheight, false, false, true, true, true);
    //init_camera(1, camwidth, camheight, false, camOpenCV, true, true, true);
    sleepms(200);

    //init_viewer(ViewMode::Camera0, ViewMode::Camera1, 1, false, true);
    init_viewer(ViewMode::Camera0,ViewMode::Processed);

    std::vector<std::vector<cv::Point2f>> faceLandmarks;
    std::vector<mpface::Face> faces;

    //for Face Mesh
    MediapipeFaceMesh mfm;
    FrameResultSynchroniser meshSync(100);

    printf("Start Loop\n");
    do {
        // Get frame to frame,frameGray,frameGrayHalf
        if (GetFrame()==0) { //GetFrame()==1 (new frame from cam0 ==1, ==2 from cam1, ==3 from cam0 & cam 1)

            //here you have time to do anything

            sleepms(1);
            continue;
        }

        std::vector<std::vector<cv::Point2f>> faceLandmarks;
        faces.clear();

        //face Mesh
        meshSync.pushFrame(mfm.pushFrame(frame0),frame0);
        int resm=meshSync.getFrameFromId(mfm.getFaceMesh(faceLandmarks),imgProcessed);

        if (resm&&faceLandmarks.size()) {
            mfm.drawFaceMesh(imgProcessed,faceLandmarks);
            std::vector<cv::Rect> facesRects;
            mfm.getFacesRectsFromLandmarks(faceLandmarks,facesRects);
            mfm.drawFacesRects(imgProcessed,facesRects,greenScalar);
            tick2on=true;
        }      

        viewStatus = viewer_refresh();
    } while (viewStatus != ViewerStatus::Exit && control_c != true);
    closing_function(0);
    return 1;
}
 
You can find C++ and Python code for Raspberry Pi4 in the
SaraKIT Github repository:
https://github.com/SaraEye