Alternatives for OpenCV at recognizing facial parts? (eyes, nose, mouth)

After using OpenCv for a while I figured out it does recognize the face very well but not the eyes, nose and mouth. When applying this the detection isn’t stable enough and will create rectangles everywhere. Especially when I want to detect the mouth…

So I was wondering if there was a way to stabilize this or if there is any alternative for OpenCV? I’ve been looking online but it seems like theres not a lot of options… So I’m trying my last shot here, please feel free to come with any type of advice. Thank you.

opencv.loadCascade(OpenCV.CASCADE_FRONTALFACE);

face

opencv.loadCascade(OpenCV.CASCADE_EYE); 

eyes

opencv.loadCascade(OpenCV.CASCADE_NOSE);

nose

opencv.loadCascade(OpenCV.CASCADE_MOUTH); 

mouth

Full Code:

import java.awt.*;
import processing.video.*;
import gab.opencv.*;

Capture video;

OpenCV opencv;

void setup() {
  size(640, 480, P3D);
  video = new Capture(this, 640, 480, "pipeline:autovideosrc");
  opencv = new OpenCV(this, 640, 480);
  video.start();
}

void draw() {
  opencv.loadImage(video);
  image(video, 0, 0 );

  noFill();
  stroke(0, 0, 0);
  strokeWeight(3);
  
  opencv.loadCascade(OpenCV.CASCADE_FRONTALFACE);
  Rectangle[] faces = opencv.detect();
  
  for (int i = 0; i < faces.length; i++) {
    rect(faces[i].x, faces[i].y, faces[i].width, faces[i].height);
  }
  
  noFill();
  stroke(0, 55, 0);
  strokeWeight(3);
  
  opencv.loadCascade(OpenCV.CASCADE_EYE); 
   Rectangle[] eye = opencv.detect();
  
  for (int i = 0; i < eye.length; i++) {
    rect(eye[i].x, eye[i].y, eye[i].width, eye[i].height);
  }
 
  noFill();
  stroke(0, 155, 0);
  strokeWeight(3);
  
  opencv.loadCascade(OpenCV.CASCADE_NOSE); 
   Rectangle[] nose = opencv.detect();
  
  for (int i = 0; i < nose.length; i++) {
    rect(nose[i].x, nose[i].y, nose[i].width, nose[i].height);
  }

  noFill();
  stroke(0, 255, 0);
  strokeWeight(3);
  
  opencv.loadCascade(OpenCV.CASCADE_MOUTH); 
   Rectangle[] mouth = opencv.detect();
  
  for (int i = 0; i < mouth.length; i++) {
    rect(mouth[i].x, mouth[i].y, mouth[i].width, mouth[i].height);
  }
}

void captureEvent(Capture c) {
  c.read();
}