This is a first test on Huggingface to test and learn The project is mainly created with Claude 4, ChatGPT 4 and DeepSeek
This was the prompt given to Claude 4 Can you create a OpenCV program in python that moves a cross across the screen and saves the images and x,y coordinates. The Idea is to train a network that is good at gaze estimation. Preferably a fast network that can be run in real time. Training should be done in tensorflow. The cursor should move continuously back and forth from top to bottom and data should save x,y coordinate on the screen as well as the image captured. Data capture should wait for the user to press a key then continously capture data until done. Capture of data should be done under 5 minutes. When the program is finished we will have a dataset with ground truth. x,y of the screen.
To run this.
Create a virtual python env or use Conda. gaze_env
The best results was achived with this.
For each step update the dataset abd model names.
To collect data, for training
I recomend increasing the dataset by increasing the collection times Increase from 300 seconds python3 inference224x224.py
Train the neteork
python3 train224x224.py
Inference
python3 inference224x224.py
Model: "multi_branch_gaze_model"
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃ Layer (type) ┃ Output Shape ┃ Param # ┃ Connected to ┃
┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩
│ face_input (InputLayer) │ (None, 224, 224, 3) │ 0 │ - │
├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤
│ face_conv1 (Conv2D) │ (None, 224, 224, 32) │ 2,432 │ face_input[0][0] │
├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤
│ face_pool1 (MaxPooling2D) │ (None, 112, 112, 32) │ 0 │ face_conv1[0][0] │
├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤
│ face_bn1 (BatchNormalization) │ (None, 112, 112, 32) │ 128 │ face_pool1[0][0] │
├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤
│ face_conv2 (Conv2D) │ (None, 112, 112, 64) │ 18,496 │ face_bn1[0][0] │
├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤
│ face_pool2 (MaxPooling2D) │ (None, 56, 56, 64) │ 0 │ face_conv2[0][0] │
├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤
│ face_bn2 (BatchNormalization) │ (None, 56, 56, 64) │ 256 │ face_pool2[0][0] │
├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤
│ left_eye_input (InputLayer) │ (None, 60, 80, 3) │ 0 │ - │
├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤
│ right_eye_input (InputLayer) │ (None, 60, 80, 3) │ 0 │ - │
├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤
│ face_conv3 (Conv2D) │ (None, 56, 56, 128) │ 73,856 │ face_bn2[0][0] │
├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤
│ left_eye_conv1 (Conv2D) │ (None, 60, 80, 32) │ 896 │ left_eye_input[0][0] │
├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤
│ right_eye_conv1 (Conv2D) │ (None, 60, 80, 32) │ 896 │ right_eye_input[0][0] │
├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤
│ face_pool3 (MaxPooling2D) │ (None, 28, 28, 128) │ 0 │ face_conv3[0][0] │
├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤
│ left_eye_pool1 (MaxPooling2D) │ (None, 30, 40, 32) │ 0 │ left_eye_conv1[0][0] │
├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤
│ right_eye_pool1 │ (None, 30, 40, 32) │ 0 │ right_eye_conv1[0][0] │
│ (MaxPooling2D) │ │ │ │
├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤
│ face_bn3 (BatchNormalization) │ (None, 28, 28, 128) │ 512 │ face_pool3[0][0] │
├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤
│ left_eye_bn1 │ (None, 30, 40, 32) │ 128 │ left_eye_pool1[0][0] │
│ (BatchNormalization) │ │ │ │
├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤
│ right_eye_bn1 │ (None, 30, 40, 32) │ 128 │ right_eye_pool1[0][0] │
│ (BatchNormalization) │ │ │ │
├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤
│ face_conv4 (Conv2D) │ (None, 28, 28, 256) │ 295,168 │ face_bn3[0][0] │
├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤
│ left_eye_conv2 (Conv2D) │ (None, 30, 40, 64) │ 18,496 │ left_eye_bn1[0][0] │
├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤
│ right_eye_conv2 (Conv2D) │ (None, 30, 40, 64) │ 18,496 │ right_eye_bn1[0][0] │
├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤
│ face_pool4 (MaxPooling2D) │ (None, 14, 14, 256) │ 0 │ face_conv4[0][0] │
├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤
│ left_eye_pool2 (MaxPooling2D) │ (None, 15, 20, 64) │ 0 │ left_eye_conv2[0][0] │
├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤
│ right_eye_pool2 │ (None, 15, 20, 64) │ 0 │ right_eye_conv2[0][0] │
│ (MaxPooling2D) │ │ │ │
├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤
│ face_bn4 (BatchNormalization) │ (None, 14, 14, 256) │ 1,024 │ face_pool4[0][0] │
├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤
│ left_eye_bn2 │ (None, 15, 20, 64) │ 256 │ left_eye_pool2[0][0] │
│ (BatchNormalization) │ │ │ │
├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤
│ right_eye_bn2 │ (None, 15, 20, 64) │ 256 │ right_eye_pool2[0][0] │
│ (BatchNormalization) │ │ │ │
├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤
│ face_gap │ (None, 256) │ 0 │ face_bn4[0][0] │
│ (GlobalAveragePooling2D) │ │ │ │
├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤
│ left_eye_conv3 (Conv2D) │ (None, 15, 20, 128) │ 73,856 │ left_eye_bn2[0][0] │
├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤
│ right_eye_conv3 (Conv2D) │ (None, 15, 20, 128) │ 73,856 │ right_eye_bn2[0][0] │
├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤
│ face_fc1 (Dense) │ (None, 256) │ 65,792 │ face_gap[0][0] │
├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤
│ left_eye_gap │ (None, 128) │ 0 │ left_eye_conv3[0][0] │
│ (GlobalAveragePooling2D) │ │ │ │
├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤
│ right_eye_gap │ (None, 128) │ 0 │ right_eye_conv3[0][0] │
│ (GlobalAveragePooling2D) │ │ │ │
├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤
│ face_dropout1 (Dropout) │ (None, 256) │ 0 │ face_fc1[0][0] │
├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤
│ left_eye_fc1 (Dense) │ (None, 64) │ 8,256 │ left_eye_gap[0][0] │
├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤
│ right_eye_fc1 (Dense) │ (None, 64) │ 8,256 │ right_eye_gap[0][0] │
├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤
│ face_fc2 (Dense) │ (None, 128) │ 32,896 │ face_dropout1[0][0] │
├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤
│ left_eye_dropout1 (Dropout) │ (None, 64) │ 0 │ left_eye_fc1[0][0] │
├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤
│ right_eye_dropout1 (Dropout) │ (None, 64) │ 0 │ right_eye_fc1[0][0] │
├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤
│ combined_features │ (None, 256) │ 0 │ face_fc2[0][0], │
│ (Concatenate) │ │ │ left_eye_dropout1[0][0], │
│ │ │ │ right_eye_dropout1[0][0] │
├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤
│ fusion_fc1 (Dense) │ (None, 256) │ 65,792 │ combined_features[0][0] │
├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤
│ fusion_bn1 │ (None, 256) │ 1,024 │ fusion_fc1[0][0] │
│ (BatchNormalization) │ │ │ │
├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤
│ fusion_dropout1 (Dropout) │ (None, 256) │ 0 │ fusion_bn1[0][0] │
├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤
│ fusion_fc2 (Dense) │ (None, 128) │ 32,896 │ fusion_dropout1[0][0] │
├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤
│ fusion_bn2 │ (None, 128) │ 512 │ fusion_fc2[0][0] │
│ (BatchNormalization) │ │ │ │
├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤
│ fusion_dropout2 (Dropout) │ (None, 128) │ 0 │ fusion_bn2[0][0] │
├───────────────────────────────┼───────────────────────────┼─────────────────┼────────────────────────────┤
│ gaze_output (Dense) │ (None, 2) │ 258 │ fusion_dropout2[0][0] │
└───────────────────────────────┴───────────────────────────┴─────────────────┴────────────────────────────┘
Total params: 794,818 (3.03 MB)
Trainable params: 792,706 (3.02 MB)
Non-trainable params: 2,112 (8.25 KB)
Old versions, did not work so well probably due to an error. Files:
Creating a dataset
collector.py collector.html When creating a dataset in the browser you will have to convert it with convert.py When creating dataset with collector you have to preprocess it with preprocess.py
Training from web based dataset
training.py
Training from OpenCV created dataset
training_faces.py
training_deepseek.py
Inference
inference.py This does not work in a wsl environment as we cannot access the camera.
Mobilenet used Model architecture: Model: "functional"
- Downloads last month
- 15