Mouth Open Detection

Tiếp nối bài hướng dẫn phát hiện hành động mở mắt trước camera mình sẽ hướng dẫn các bạn làm một ứng dụng đơn giản tương tự đó là chúng ta sẽ phát hiện hành động mở miệng khi đứng trước camera.


Đầu tiên chúng ta cần lần lược cài đặt các thư viện cần thiết cho dự án này:

pip install opencv-python
pip install dlib

Tiếp theo chúng ta cần tải file shape_predictor_68_face_landmarks.dat và thêm vào thư mục project của chúng ta. 

Sau khi cài đặt thành công tạo ngay 1 file python và copy đoạn code mẫu vào để test ngay nhé:

# import the necessary packages
from picamera.array import PiRGBArray
from picamera import PiCamera
import time
import cv2
import dlib
from math import hypot

# initialize the camera and grab a reference to the raw camera capture
camera = PiCamera()
camera.resolution = (640, 480)
camera.framerate = 32
rawCapture = PiRGBArray(camera, size=(640, 480))

# create default face detector
detector = dlib.get_frontal_face_detector()
predictor = dlib.shape_predictor("./shape_predictor_68_face_landmarks.dat")
count_mouth_open = 0
font = cv2.FONT_HERSHEY_SIMPLEX
mouth_points = [48, 49, 50, 51, 52, 53, 54, 55,
                56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67]


def midpoint(p1, p2):
    return int((p1.x + p2.x)/2), int((p1.y + p2.y)/2)


def get_mouth_pen_ratio(mouth_points, facial_landmarks):
    left_point = (facial_landmarks.part(
        mouth_points[12]).x, facial_landmarks.part(mouth_points[12]).y)
    right_point = (facial_landmarks.part(
        mouth_points[16]).x, facial_landmarks.part(mouth_points[16]).y)
    center_top = midpoint(facial_landmarks.part(
        mouth_points[13]), facial_landmarks.part(mouth_points[14]))
    center_bottom = midpoint(facial_landmarks.part(
        mouth_points[19]), facial_landmarks.part(mouth_points[18]))

    hor_line = cv2.line(image, left_point, right_point, (0, 255, 0), 2)
    ver_line = cv2.line(image, center_top, center_bottom, (0, 255, 0), 2)

    hor_line_lenght = hypot(
        (left_point[0] - right_point[0]), (left_point[1] - right_point[1]))
    ver_line_lenght = hypot(
        (center_top[0] - center_bottom[0]), (center_top[1] - center_bottom[1]))

    if ver_line_lenght != 0:
        ratio = hor_line_lenght / ver_line_lenght
    else:
        ratio = 60

    return ratio


# allow the camera to warmup
time.sleep(0.1)

# capture frames from the camera
for frame in camera.capture_continuous(rawCapture, format="bgr", use_video_port=True):
    # grab the raw NumPy array representing the image, then initialize the timestamp
    # and occupied/unoccupied text
    image = frame.array

    # convert frame to gray
    gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

    faces = detector(gray)

    for face in faces:
        landmarks = predictor(gray, face)
        mouths = get_mouth_pen_ratio(
            mouth_points, landmarks)

        if mouths <= 5.0:
            count_mouth_open += 1

    cv2.putText(image, "Mouth open: " + str(count_mouth_open),
                (50, 50), font, 2, (255, 0, 0))
    print("Mouth open: " + str(count_mouth_open))
    cv2.imshow("Frame", image)

    # show the frame
    cv2.imshow("Frame", image)
    key = cv2.waitKey(1) & 0xFF

    # clear the stream in preparation for the next frame
    rawCapture.truncate(0)

    # if the `q` key was pressed, break from the loop
    if key == ord("q"):
        break

Có thể bạn quan tâm ???