-
Notifications
You must be signed in to change notification settings - Fork 1.9k
Description
Hi! I am trying to figure out if my participants are looking at the screen or not. For this, I will need to manually decide where the screen actually is (the camera may be above/below, etc.) which can be done manually, but I first need to understand where they are looking. However, I am having issues plotting gaze direction on video frames. I want to reproduce the green rays seen in the OpenFace output videos, but I think I am missing a piece of information about the gaze direction (gaze_0/1_x/y/z) scale.
I understand that it's in world coordinates (=camera coordinates) relative to the centre of the screen (= centre of the camera) on scale [-1 1], so I need to multiply it by some scaling factor. Yet, however I do it, the gaze plotted on the video frames does not seem to correspond to the gaze of the participant.
To Reproduce
Here is what I do:
- plot the video frame
- extract frame width and height
- rescale gaze data to pixels*
- plot the location of the eyes
- plot the vector of the eye gaze (origin: location of the eyes, end: gaze coordinates)
- The landmarks are in pixels, but the gaze direction is in world coordinated [-1 1] relative to the position of the eye. I tried two scenarios to rescale them to a common scale. In scenario 1, I add 1 ([0 2]), divide by 2 ([0 1]), and multiply by dimensions of the frame (for x: image width and for y: image height). This is all assuming that the scale [-1 1] is equivalent to the size of the frame, i.e., camera, but this would mean that the faze can fall outside of the frame (if the eyes are not perfectly in the middle). In scenario 2, I multiply the gaze by the middle point of the screen (i.e., camera origin) and a scaling factor.
Code in R:
f = 1000
c = video_df[video_df$frame == f,]
videoframename = "my_path_to_the_video"
img <- readPNG(videoframename)
# Define a scaling factor for the arrow length
scaling = 1
scale_factor_0 <- -1*c$gaze_0_z*scaling # depth
scale_factor_1 <- -1*c$gaze_1_z*scaling
# Get image dimensions
img_width <- dim(img)[2]
img_height <- dim(img)[1]
center_x <- img_width/2
center_y <- img_height/2
# Convert OpenFace data for this frame into a data frame
b <- data.frame(
eye_lmk_x_21 = c$eye_lmk_x_21,
eye_lmk_y_21 = c$eye_lmk_y_21,
eye_lmk_x_49 = c$eye_lmk_x_49,
eye_lmk_y_49 = c$eye_lmk_y_49,
#scenario 1:
gaze_0_x = ((c$gaze_0_x+1)/2)*img_width, # to pixel coordinates
gaze_0_y = ((c$gaze_0_y+1)/2)*img_height,
gaze_1_x = ((c$gaze_1_x+1)/2)*img_width,
gaze_1_y = ((c$gaze_1_y+1)/2)*img_height
#scenario 2:
gaze_0_x = c$gaze_0_x * center_x * scale_factor,
gaze_0_y = c$gaze_0_y * center_y * scale_factor,
gaze_1_x = c$gaze_1_x * center_x * scale_factor,
gaze_1_y = c$gaze_1_y * center_y * scale_factor,
)
ggplot() +
# Add image as background
annotation_raster(as.raster(img), xmin = 0, xmax = img_width, ymin = 0, ymax = img_height) +
# The eyes
geom_point(aes(x = b$eye_lmk_x_21, y = img_height - b$eye_lmk_y_21), color = "yellow", size = 1) +
geom_point(aes(x = b$eye_lmk_x_49, y = img_height - b$eye_lmk_y_49), color = "yellow", size = 1) +
# Left eye direction
geom_segment(
data = b,
aes(
x = eye_lmk_x_21,
y = img_height - eye_lmk_y_21, # Flip y-coordinates
xend = eye_lmk_x_21 + gaze_0_x,
yend = img_height - eye_lmk_y_21 - gaze_0_y
),
arrow = arrow(type = "closed", length = unit(0.2, "cm")), # Closed arrow with line
color = "red",
size = 0.5
) +
# Right eye direction
geom_segment(
data = b,
aes(
x = eye_lmk_x_49,
y = img_height - eye_lmk_y_49, # Flip y-coordinates
xend = eye_lmk_x_49 + gaze_1_x,
yend = img_height - eye_lmk_y_49 - gaze_1_y
),
arrow = arrow(type = "closed", length = unit(0.2, "cm")), # Closed arrow with line
color = "red",
size = 0.5
) +
coord_fixed(ratio = 1, expand = FALSE, xlim = c(0, img_width), ylim = c(0, img_height))
Expected behavior
I hope to reproduce the green gaze lines as seen in the video outputs of OpenFace, but this is not working. For some frames it's ok, for some the gaze is completely wrong, that is, pointing in a different direction than where the eyes in the video are clearly looking.
Screenshots
I cannot add a screenshot due to data protection and identifiable faces.
Desktop (please complete the following information):
Linux (can't check the version at the moment)
Any help would be appreciated! Thank you.