1

我正在尝试通过使用对象检测的想法来实现一个更简单的眨眼版本。所以我的计划是在每个第一帧和第三帧获取眼睛区域周围的帧,并使用检测变化的结构相似度指标检查状态两帧。但我得到了错误的结果。

下面是我的代码

import cv2
import numpy as np
from skimage.measure import compare_ssim

# get the features for face from the file and pass it to the Cascade Classifier
face_cascade = cv2.CascadeClassifier("haarcascade_frontalface_default.xml")
# get the features for eyes from the file and pass it to the Cascade Classifier
eyes_cascade = cv2.CascadeClassifier("haarcascade_eye.xml")

#we can compare two images using Structural Similarity
#so a small change in pixel value won't prompt this method to term both images as dissimilar
#the closer the value is to 1,the more similar two images are
def ssim(A, B):
    return compare_ssim(A, B, data_range=A.max() - A.min())

#capture a video either from a file or a live video stream
cap = cv2.VideoCapture(0)
current_frame = None
eye_frame_now = None
eye_frame_last = None
#we keep a count of the frames
frame_counter = 0
while True:
    if frame_counter == 0:
        # get the frame
        ret, current_frame = cap.read()
        # once the video is over in case of video files
        if current_frame is None:
            break
        gray_frame = cv2.cvtColor(current_frame, cv2.COLOR_BGR2GRAY)
        faces = face_cascade.detectMultiScale(gray_frame, 1.05, 10)
        for face in faces:
            # get the coordinate of the detected face
            x, y, w, h = face
            # draw the rectangle on the image
            # cv2.rectangle(img, (x,y), (x + w, y + h), (0, 255, 0), 2)
            # the idea is instead of looking at the entire image for eyes,we can just look at the detected faces
            # and try to search for eye regions on those faces
            # get the detected face using image slicing
            face_color = current_frame[y: y + h, x: x + w]
            face_gray = gray_frame[y: y + h, x: x + w]
            # cv2.imshow("Sliced out face", gray_frame)
            eyes = eyes_cascade.detectMultiScale(face_gray, 1.11, 4)
            for eye in eyes:
                # get the coordinate of the detected eye
                x1, y1, w1, h1 = eye
                eye_frame = face_gray[y1:y1 + h1, x1:x1 + w1]
                print("Eye Frame", eye_frame)
                if eye_frame is not []:
                    eye_frame_last = cv2.resize(eye_frame, (50, 50))
                # draw a rectangle on the eyes of the face
                cv2.rectangle(face_color, (x1, y1), (x1 + w1, y1 + h1), (255, 0, 0), 2)

    #the idea is instead of comparing two consecutive eye frames,we compare frames that are 3 intervals apart.
    if frame_counter == 3:
        gray_frame = cv2.cvtColor(current_frame, cv2.COLOR_BGR2GRAY)
        faces = face_cascade.detectMultiScale(gray_frame, 1.05, 10)
        for face in faces:
            # get the coordinate of the detected face
            x, y, w, h = face
            # draw the rectangle on the image
            # cv2.rectangle(img, (x,y), (x + w, y + h), (0, 255, 0), 2)
            face_color = current_frame[y: y + h, x: x + w]
            face_gray = gray_frame[y: y + h, x: x + w]
            # cv2.imshow("Sliced out face", gray_frame)
            eyes = eyes_cascade.detectMultiScale(face_gray, 1.11, 4)
            for eye in eyes:
                # get the coordinate of the detected eye
                x1, y1, w1, h1 = eye
                eye_frame = face_gray[y1:y1 + h1, x1:x1 + w1]
                if eye_frame is not []:
                    eye_frame_now = cv2.resize(eye_frame, (50, 50))

                # draw a rectangle on the eyes of the face
                cv2.rectangle(face_color, (x1, y1), (x1 + w1, y1 + h1), (255, 0, 0), 2)
        #compare two images based on SSIM
        ssim_val = ssim(eye_frame_now, eye_frame_last)
        print(ssim_val)
        #if there is a major drop in the SSIM value ie it has detected a blink
        if ssim_val < 0.8:
            print("Blinking")

        frame_counter = -1

    #show the video as a series of frames
    cv2.imshow("Eye Detection",current_frame) #(name of the window,image file)
    frame_counter += 1

    key = cv2.waitKey(1) & 0xFF
    if key == ord('q'):
        break

#release the resources allocated to the video file or video stream
cap.release()
#destroy all the windows
cv2.destroyAllWindows()

这是我的输出

0.142644916596
Blinking
0.154798221175
Blinking
0.792948872827
0.584593035048
0.499610556414
0.194123593687
Blinking
0.838011295523
0.579537657669
0.080305786794
Blinking
0.189779706485
Blinking
0.457222729421
0.234885787265
Blinking

如您所见,即使我睁着眼睛,它也经常发出“闪烁”的信息。我哪里出错了?

4

0 回答 0