**已关闭。**此问题为not reproducible or was caused by typos。当前不接受答案。
这个问题是由打字错误或无法再重现的问题引起的。虽然类似的问题在这里可能是on-topic,但这个问题的解决方式不太可能帮助未来的读者。
昨天关门了。
Improve this question
我正在做一个项目,上面有一个板子和一个摄像头,目的是识别学生谁在看板子,同时也识别他们视线的位置(在板子上)。
目前,我计划从以下几个方面应对挑战:
1.识别学生面孔
1.从检测到的人脸中识别出双眼的ROI
1.确定其瞳孔/虹膜中心的位置和头部姿势
1.决定这个人是否在看董事会?
1.如果是,学生正在查看白板的哪个区域?
到目前为止,我能够做以下事情:
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()
下面是相同的输出:
我能够得到双眼的注视方向,现在我只需要将这些矢量投影到真实的世界中的3D空间(电路板或笔记本电脑屏幕)。有人能指导我吗?
1条答案
按热度按时间nx7onnlm1#
我认为你对这个问题有一个很好的解决办法:你已经把它分解成子问题了。
在3D中定位眼睛。之后,您可以创建一个平面,眼睛位于该平面上:眼睛和法线之间的矢量足以定义这个平面。看起来你已经找到了面部标志。如果你的检测是在2D中,你可以尝试像this这样的东西。立体对的更多信息-〉3D转换here。
下面的图片看起来像GazeML。这将有助于了解您使用的凝视算法及其输出类型。无论如何,您应该有两个Angular 来描述眼睛方向。这些凝视向量从我们在上一步中定义的平面开始。现在您有了3D向量的起点和方向。
如果你只知道3D凝视向量的2D投影,但你知道向量的长度,你可以使用数学来求解3D凝视向量。请参考vector projection。
你可能需要先校准你的相机,因为它们有不同类型的失真。你可以校准你的算法,把一个测试图片放在板上(例如一条直线),让测试对象用他们的眼睛跟随它。然后你可以计算误差,并作出必要的调整。
祝你好运!