人眼凝视检测:识别用户在看板上的注视点

8
我正在处理一个项目,其中有一块板子和一个相机放在上面。 目标是识别看着黑板的学生,并确定他们视线的位置(在黑板上)。
目前,我计划从以下几个方面解决这个挑战:
1. 识别学生的脸部。 2. 从检测到的脸部中识别双眼的ROI。 3. 识别他们的瞳孔/虹膜中心和头部姿势的位置。 4. 判断这个人是否在看黑板? 5. 如果是,学生正在看黑板的哪个区域?
到目前为止,我能够完成以下事项:
1. 识别脸部和眼睛的关键点以及面部位置向量(X、Y、Z)。
以下是代码:
from scipy.spatial import distance as dist
from imutils.video import FileVideoStream
from imutils.video import VideoStream
from imutils import face_utils
from gaze_codefiles import get_head_pose,draw_border,iris_center
import numpy as np
import imutils
import time
import dlib
import cv2

line_pairs = [[0, 1], [1, 2], [2, 3], [3, 0],
              [4, 5], [5, 6], [6, 7], [7, 4],
              [0, 4], [1, 5], [2, 6], [3, 7]]


print("[INFO] loading facial landmark predictor...")
detector = dlib.get_frontal_face_detector()
predictor = dlib.shape_predictor('./shape_predictor_68_face_landmarks.dat')

print("[INFO] camera sensor warming up...")
vs = VideoStream(src=0).start()
(lStart, lEnd) = face_utils.FACIAL_LANDMARKS_IDXS["left_eye"]
(rStart, rEnd) = face_utils.FACIAL_LANDMARKS_IDXS["right_eye"]
# vs = VideoStream(usePiCamera=True).start() # Raspberry Pi
time.sleep(2.0)

while True:
    frame = vs.read()
    frame = imutils.resize(frame, width=400)
    gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
    rects = detector(gray,0)

    for rect in rects:
        (bx,by,bw,bh) = face_utils.rect_to_bb(rect)
        draw_border(frame,(bx,by),(bx+bw,by+bh),(127,255,255),1,10,20)

        shape = predictor(gray,rect)

        shape = face_utils.shape_to_np(shape)

        leftEye = shape[lStart:lEnd]

        rightEye = shape[rStart:rEnd]



        leftEyeHull = cv2.convexHull(leftEye)

        rightEyeHull = cv2.convexHull(rightEye)

        cv2.drawContours(frame, [leftEyeHull], -1, (127, 255, 255), 1)

        cv2.drawContours(frame, [rightEyeHull], -1, (127, 255, 255), 1)

        reprojectdst, euler_angle = get_head_pose(shape)

        image_points = np.float32([shape[17], shape[21], shape[22], shape[26], shape[36],
                            shape[39], shape[42], shape[45], shape[31], shape[35],
                            shape[48], shape[54], shape[57], shape[8]])

        #for start, end in line_pairs:
            #cv2.line(frame, reprojectdst[start], reprojectdst[end], (0, 0, 255))

        for p in image_points:
            cv2.circle(frame, (int(p[0]), int(p[1])), 1, (0,0,255), -1)

        #p1 = (int(shape[34][0]), int(shape[34][1]))
        #p2 = (int(reprojectdst[0][0]), int(reprojectdst[0][1]))

        #cv2.line(frame, p1, p2, (255,0,0), 2)

        cv2.putText(frame, "X: " + "{:7.2f}".format(euler_angle[0, 0]), (20, 20), cv2.FONT_HERSHEY_SIMPLEX,
                            0.5, (127, 255, 255), thickness=1)
        cv2.putText(frame, "Y: " + "{:7.2f}".format(euler_angle[1, 0]), (20, 50), cv2.FONT_HERSHEY_SIMPLEX,
                            0.5, (127, 255, 255), thickness=1)
        cv2.putText(frame, "Z: " + "{:7.2f}".format(euler_angle[2, 0]), (20, 80), cv2.FONT_HERSHEY_SIMPLEX,
                            0.5, (127, 255, 255), thickness=1)

        #cv2.putText(frame,"Left Eye Center is:{}".format(tuple(lefteyecenter)),(20,100),cv2.FONT_HERSHEY_SIMPLEX,0.75, (127, 255, 255), thickness=2)

        #cv2.putText(frame,"Left Eye Center is:{}".format(tuple(righteyecenter)),(20,100),cv2.FONT_HERSHEY_SIMPLEX,0.75, (127, 255, 255), thickness=2)

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

    if key == ord("q"):
        break

cv2.destroyAllWindows()
vs.stop()        

这是相同内容的输出:

enter image description here

我已经能够获取两只眼睛的注视方向,现在我只需要将这些向量投影到真实世界的3D空间中(白板或笔记本电脑屏幕)。有人可以指导我吗?

enter image description here

1个回答

0

我认为你对这个问题的方法很好:你已经将它分解成了子问题。

在三维空间中定位眼睛。完成后,您可以创建一个平面,上面有眼睛:眼睛之间的向量及其法线足以定义此平面。看起来您已经找到了面部标志。如果您的检测结果是二维的,可以尝试类似于this的方法。有关立体对 -> 3D 转换的更多信息,请单击here

底部的图片看起来像是GazeML。了解您用于注视的算法以及它所提供的输出类型将会有所帮助。无论如何,您应该有两个描述眼睛方向的角度。这些注视向量始于我们在前一步中定义的平面的起点和方向。现在,您已经拥有了在三维空间中矢量的起点和方向。

如果您只知道3D凝视向量的2D投影,但您知道向量的长度,则可以使用数学来解决3D凝视向量。请参考向量投影

您可能需要先校准相机,因为它们具有不同类型的畸变。您可以通过在板上放置测试图片(例如一条直线)并让测试对象用眼睛跟随该图片来校准算法。然后,您可以计算误差并进行必要的调整。

祝你好运!


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接