Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions .sieveignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
__pycache__/
.venv/
*.png
*.mp4
urls.json
*.jsonl
from typing import Optional

def _blinking_ratio(self, landmarks, points: list, frame_shape: tuple) -> Optional[float]:
3 changes: 1 addition & 2 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
FROM ubuntu:18.04
FROM ubuntu:22.04
RUN apt-get update
RUN apt install -y python3
RUN apt install -y python3-pip
RUN apt install -y cmake
RUN apt install -y libsm6
RUN apt install -y libxext6
RUN apt install -y libxrender1
Expand Down
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,17 +20,17 @@ git clone https://github.com/antoinelame/GazeTracking.git
```

### For Pip install
Install these dependencies (NumPy, OpenCV, Dlib):
Install these dependencies (NumPy, OpenCV, MediaPipe):

```shell
pip install -r requirements.txt
```

> The Dlib library has four primary prerequisites: Boost, Boost.Python, CMake and X11/XQuartx. If you doesn't have them, you can [read this article](https://www.pyimagesearch.com/2017/03/27/how-to-install-dlib/) to know how to easily install them.
> MediaPipe is much easier to install than dlib and doesn't require additional system dependencies.


### For Anaconda install
Install these dependencies (NumPy, OpenCV, Dlib):
Install these dependencies (NumPy, OpenCV, MediaPipe):

```shell
conda env create --file environment.yml
Expand Down
61 changes: 61 additions & 0 deletions calibrate_gaze.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
"""
Gaze calibration script - shows ratio values for fine-tuning
"""

import cv2
from gaze_tracking import GazeTracking

gaze = GazeTracking()
webcam = cv2.VideoCapture(0)

print("Gaze Calibration")
print("Look left, center, and right with just your eyes (keep head still)")
print("Watch the ratio values change")
print("Press 'q' to quit")

while True:
_, frame = webcam.read()
gaze.refresh(frame)

frame = gaze.annotated_frame()

# Show ratio and direction
ratio = gaze.horizontal_ratio()
if ratio is not None:
# Show ratio value
ratio_text = f"Ratio: {ratio:.3f}"
cv2.putText(frame, ratio_text, (10, 30), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 2)

# Show current direction
if gaze.is_right():
direction = "RIGHT"
color = (0, 0, 255) # Red
elif gaze.is_left():
direction = "LEFT"
color = (255, 0, 0) # Blue
elif gaze.is_center():
direction = "CENTER"
color = (0, 255, 0) # Green
else:
direction = "UNKNOWN"
color = (255, 255, 0) # Yellow

cv2.putText(frame, direction, (10, 80), cv2.FONT_HERSHEY_SIMPLEX, 1.5, color, 3)

# Show thresholds
cv2.putText(frame, "Thresholds: <=0.45=RIGHT, 0.45-0.55=CENTER, >=0.55=LEFT",
(10, 120), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255, 255, 255), 1)

# Show instructions
cv2.putText(frame, "Look left/right with eyes only (keep head still)",
(10, 150), cv2.FONT_HERSHEY_SIMPLEX, 0.6, (255, 255, 255), 1)
else:
cv2.putText(frame, "No eyes detected", (10, 30), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 255), 2)

cv2.imshow("Gaze Calibration", frame)

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

webcam.release()
cv2.destroyAllWindows()
6 changes: 3 additions & 3 deletions environment.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,6 @@ channels:
- anaconda
- defaults
dependencies:
- numpy == 1.16.1
- opencv == 3.4.*
- dlib == 19.17.*
- numpy == 2.2.6
- opencv == 4.12.*
- mediapipe == 0.11.1
64 changes: 37 additions & 27 deletions example.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
"""
Demonstration of the GazeTracking library.
Check the README.md for complete documentation.
Simple gaze direction test - shows ratio values for calibration
"""

import cv2
Expand All @@ -9,36 +8,47 @@
gaze = GazeTracking()
webcam = cv2.VideoCapture(0)

print("Gaze Direction Test")
print("Look left, center, and right to see the ratio values")
print("Press 'q' to quit")

while True:
# We get a new frame from the webcam
_, frame = webcam.read()

# We send this frame to GazeTracking to analyze it
gaze.refresh(frame)

frame = gaze.annotated_frame()
text = ""

if gaze.is_blinking():
text = "Blinking"
elif gaze.is_right():
text = "Looking right"
elif gaze.is_left():
text = "Looking left"
elif gaze.is_center():
text = "Looking center"

cv2.putText(frame, text, (90, 60), cv2.FONT_HERSHEY_DUPLEX, 1.6, (147, 58, 31), 2)

left_pupil = gaze.pupil_left_coords()
right_pupil = gaze.pupil_right_coords()
cv2.putText(frame, "Left pupil: " + str(left_pupil), (90, 130), cv2.FONT_HERSHEY_DUPLEX, 0.9, (147, 58, 31), 1)
cv2.putText(frame, "Right pupil: " + str(right_pupil), (90, 165), cv2.FONT_HERSHEY_DUPLEX, 0.9, (147, 58, 31), 1)

cv2.imshow("Demo", frame)

if cv2.waitKey(1) == 27:

# Get and display ratio
ratio = gaze.horizontal_ratio()
if ratio is not None:
ratio_text = f"Ratio: {ratio:.3f}"
cv2.putText(frame, ratio_text, (10, 30), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 2)

# Show pupil positions for debugging
if gaze.eye_left and gaze.eye_right and gaze.eye_left.pupil and gaze.eye_right.pupil:
left_abs = gaze.eye_left.origin[0] + gaze.eye_left.pupil.x
right_abs = gaze.eye_right.origin[0] + gaze.eye_right.pupil.x
cv2.putText(frame, f"Left: {left_abs:.0f}, Right: {right_abs:.0f}", (10, 60), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (255, 255, 255), 1)

# Determine direction
if ratio <= 0.4:
direction = "RIGHT"
color = (0, 0, 255) # Red
elif ratio >= 0.6:
direction = "LEFT"
color = (255, 0, 0) # Blue
else:
direction = "CENTER"
color = (0, 255, 0) # Green

cv2.putText(frame, direction, (10, 100), cv2.FONT_HERSHEY_SIMPLEX, 1.5, color, 3)
else:
cv2.putText(frame, "No eyes detected", (10, 30), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 255), 2)

cv2.imshow("Gaze Test", frame)

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

webcam.release()
cv2.destroyAllWindows()
cv2.destroyAllWindows()
Loading