seetapsych-gaze 0.0.2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (32) hide show
  1. seetapsych_gaze-0.0.2/.github/workflows/ci.yml +160 -0
  2. seetapsych_gaze-0.0.2/.github/workflows/publish.yml +190 -0
  3. seetapsych_gaze-0.0.2/.gitignore +40 -0
  4. seetapsych_gaze-0.0.2/DEVELOPMENT.md +96 -0
  5. seetapsych_gaze-0.0.2/LICENSE +15 -0
  6. seetapsych_gaze-0.0.2/PKG-INFO +155 -0
  7. seetapsych_gaze-0.0.2/README.md +89 -0
  8. seetapsych_gaze-0.0.2/examples/gaze_screen.py +155 -0
  9. seetapsych_gaze-0.0.2/pyproject.toml +163 -0
  10. seetapsych_gaze-0.0.2/seetapsych_gaze/__init__.py +13 -0
  11. seetapsych_gaze-0.0.2/seetapsych_gaze/_version.py +24 -0
  12. seetapsych_gaze-0.0.2/seetapsych_gaze/modules/affnet.yml +68 -0
  13. seetapsych_gaze-0.0.2/seetapsych_gaze/modules/itracker-plus.yml +69 -0
  14. seetapsych_gaze-0.0.2/seetapsych_gaze/modules/tdgazenet.yml +91 -0
  15. seetapsych_gaze-0.0.2/seetapsych_gaze/opengaze/affnet/example.json +23 -0
  16. seetapsych_gaze-0.0.2/seetapsych_gaze/opengaze/affnet/model.py +37 -0
  17. seetapsych_gaze-0.0.2/seetapsych_gaze/opengaze/affnet/package.py +456 -0
  18. seetapsych_gaze-0.0.2/seetapsych_gaze/opengaze/itracker_plus/example.json +23 -0
  19. seetapsych_gaze-0.0.2/seetapsych_gaze/opengaze/itracker_plus/model.py +37 -0
  20. seetapsych_gaze-0.0.2/seetapsych_gaze/opengaze/itracker_plus/package.py +414 -0
  21. seetapsych_gaze-0.0.2/seetapsych_gaze/opengaze/tddfa/model.py +46 -0
  22. seetapsych_gaze-0.0.2/seetapsych_gaze/opengaze/tdgazenet/example.json +49 -0
  23. seetapsych_gaze-0.0.2/seetapsych_gaze/opengaze/tdgazenet/model.py +37 -0
  24. seetapsych_gaze-0.0.2/seetapsych_gaze/opengaze/tdgazenet/package.py +597 -0
  25. seetapsych_gaze-0.0.2/seetapsych_gaze/opengaze/xgaze224/ethxgaze-generic.txt +50 -0
  26. seetapsych_gaze-0.0.2/seetapsych_gaze/opengaze/xgaze224/example.json +34 -0
  27. seetapsych_gaze-0.0.2/seetapsych_gaze/opengaze/xgaze224/model.py +37 -0
  28. seetapsych_gaze-0.0.2/seetapsych_gaze/opengaze/xgaze224/package.py +546 -0
  29. seetapsych_gaze-0.0.2/seetapsych_gaze/opengaze/xgaze224/tddfa.py +349 -0
  30. seetapsych_gaze-0.0.2/tests/__init__.py +0 -0
  31. seetapsych_gaze-0.0.2/tests/test_gaze.py +57 -0
  32. seetapsych_gaze-0.0.2/uv.lock +3891 -0
@@ -0,0 +1,160 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches:
6
+ - main
7
+ - workflows
8
+ - "workflows/**"
9
+ tags-ignore: ["r*"]
10
+ pull_request:
11
+
12
+ concurrency:
13
+ group: ci-${{ github.ref }}
14
+ cancel-in-progress: true
15
+
16
+ jobs:
17
+ lint:
18
+ name: Lint & Type & Security
19
+ runs-on: ubuntu-latest
20
+ steps:
21
+ - uses: actions/checkout@v4
22
+ with:
23
+ fetch-depth: 0
24
+
25
+ - name: Derive package directory
26
+ id: pkg
27
+ run: |
28
+ REPO_NAME="${{ github.event.repository.name }}"
29
+ PACKAGE_DIR="${REPO_NAME//-/_}"
30
+ echo "PACKAGE_DIR=$PACKAGE_DIR" >> "$GITHUB_OUTPUT"
31
+ shell: bash
32
+
33
+ - name: Set up Python
34
+ uses: actions/setup-python@v5
35
+ with:
36
+ python-version: "3.12"
37
+
38
+ - name: Install uv
39
+ uses: astral-sh/setup-uv@v3
40
+ with:
41
+ enable-cache: true
42
+
43
+ - name: Install dependencies
44
+ env:
45
+ UV_TORCH_BACKEND: auto
46
+ run: uv sync --group dev
47
+
48
+ - name: Run all lint/type/security checks (collect all failures)
49
+ env:
50
+ PACKAGE_DIR: ${{ steps.pkg.outputs.PACKAGE_DIR }}
51
+ run: |
52
+ set +e
53
+ EXIT_CODE=0
54
+
55
+ echo "=== ruff check ==="
56
+ uv run ruff check .
57
+ EC=$?; [ $EC -ne 0 ] && EXIT_CODE=$EC
58
+
59
+ echo ""
60
+ echo "=== ruff format --check ==="
61
+ uv run ruff format --check .
62
+ EC=$?; [ $EC -ne 0 ] && EXIT_CODE=$EC
63
+
64
+ echo ""
65
+ echo "=== mypy ==="
66
+ uv run mypy "$PACKAGE_DIR"
67
+ EC=$?; [ $EC -ne 0 ] && EXIT_CODE=$EC
68
+
69
+ echo ""
70
+ echo "=== bandit ==="
71
+ uv run bandit -r "$PACKAGE_DIR" -c pyproject.toml
72
+ EC=$?; [ $EC -ne 0 ] && EXIT_CODE=$EC
73
+
74
+ exit $EXIT_CODE
75
+ shell: bash
76
+
77
+ test:
78
+ name: Test (Python ${{ matrix.python-version }} on ${{ matrix.os }})
79
+ runs-on: ${{ matrix.os }}
80
+ needs: lint
81
+ strategy:
82
+ fail-fast: false
83
+ matrix:
84
+ include:
85
+ - python-version: "3.10"
86
+ os: ubuntu-latest
87
+ - python-version: "3.10"
88
+ os: windows-latest
89
+ - python-version: "3.11"
90
+ os: ubuntu-latest
91
+ - python-version: "3.11"
92
+ os: windows-latest
93
+ - python-version: "3.12"
94
+ os: ubuntu-latest
95
+ - python-version: "3.12"
96
+ os: windows-latest
97
+ - python-version: "3.12"
98
+ os: macos-latest
99
+ - python-version: "3.13"
100
+ os: ubuntu-latest
101
+ - python-version: "3.13"
102
+ os: windows-latest
103
+ - python-version: "3.14"
104
+ os: ubuntu-latest
105
+ - python-version: "3.14"
106
+ os: windows-latest
107
+
108
+ steps:
109
+ - uses: actions/checkout@v4
110
+ with:
111
+ fetch-depth: 0
112
+
113
+ - name: Set up Python ${{ matrix.python-version }}
114
+ uses: actions/setup-python@v5
115
+ with:
116
+ python-version: ${{ matrix.python-version }}
117
+
118
+ - name: Install uv
119
+ uses: astral-sh/setup-uv@v3
120
+ with:
121
+ enable-cache: true
122
+
123
+ - name: Install dependencies
124
+ env:
125
+ UV_TORCH_BACKEND: auto
126
+ run: uv sync --group dev
127
+
128
+ - name: Run pytest
129
+ run: uv run pytest
130
+
131
+ build:
132
+ name: Build package
133
+ runs-on: ubuntu-latest
134
+ needs: test
135
+
136
+ steps:
137
+ - uses: actions/checkout@v4
138
+ with:
139
+ fetch-depth: 0
140
+
141
+ - name: Set up Python
142
+ uses: actions/setup-python@v5
143
+ with:
144
+ python-version: "3.12"
145
+
146
+ - name: Install build tools
147
+ run: python -m pip install --upgrade build twine
148
+
149
+ - name: Build package
150
+ run: python -m build
151
+
152
+ - name: Verify built artifacts
153
+ run: twine check dist/*
154
+
155
+ - name: Upload dist artifacts
156
+ uses: actions/upload-artifact@v4
157
+ with:
158
+ name: dist-artifacts
159
+ path: dist/
160
+ if-no-files-found: error
@@ -0,0 +1,190 @@
1
+ name: Publish to PyPI & GitHub Release
2
+
3
+ on:
4
+ push:
5
+ tags:
6
+ - "r*"
7
+
8
+ jobs:
9
+ test:
10
+ name: Pytest smoke gate
11
+ runs-on: ubuntu-latest
12
+ steps:
13
+ - uses: actions/checkout@v4
14
+ with:
15
+ fetch-depth: 0
16
+
17
+ - name: Set up Python
18
+ uses: actions/setup-python@v5
19
+ with:
20
+ python-version: "3.12"
21
+
22
+ - name: Install uv
23
+ uses: astral-sh/setup-uv@v3
24
+ with:
25
+ enable-cache: true
26
+
27
+ - name: Install dependencies
28
+ env:
29
+ UV_TORCH_BACKEND: auto
30
+ run: uv sync --group dev
31
+
32
+ - name: Run pytest (release gate)
33
+ run: uv run pytest
34
+
35
+ github-release:
36
+ name: Build and create GitHub Release
37
+ runs-on: ubuntu-latest
38
+ needs: test
39
+ permissions:
40
+ contents: write
41
+
42
+ steps:
43
+ - uses: actions/checkout@v4
44
+ with:
45
+ fetch-depth: 0
46
+
47
+ - name: Set up Python
48
+ uses: actions/setup-python@v5
49
+ with:
50
+ python-version: "3.12"
51
+
52
+ - name: Install build tools
53
+ run: python -m pip install --upgrade build twine
54
+
55
+ - name: Build package
56
+ run: python -m build
57
+
58
+ - name: Verify built artifacts
59
+ run: twine check dist/*
60
+
61
+ - name: Extract tag name
62
+ id: get_tag
63
+ run: echo "TAG=${GITHUB_REF#refs/tags/}" >> "$GITHUB_OUTPUT"
64
+ shell: bash
65
+
66
+ - name: Determine release type
67
+ id: release_type
68
+ run: |
69
+ TAG="${{ steps.get_tag.outputs.TAG }}"
70
+ if [[ "$TAG" == *-* ]]; then
71
+ echo "PYPI_PUBLISH=false" >> "$GITHUB_OUTPUT"
72
+ echo "PRERELEASE=true" >> "$GITHUB_OUTPUT"
73
+ else
74
+ echo "PYPI_PUBLISH=true" >> "$GITHUB_OUTPUT"
75
+ echo "PRERELEASE=false" >> "$GITHUB_OUTPUT"
76
+ fi
77
+ shell: bash
78
+
79
+ - name: Discover dist assets
80
+ id: assets
81
+ run: |
82
+ SDIST=$(ls dist/*.tar.gz | head -n1)
83
+ WHEEL=$(ls dist/*.whl | head -n1)
84
+ echo "SDIST=$SDIST" >> "$GITHUB_OUTPUT"
85
+ echo "WHEEL=$WHEEL" >> "$GITHUB_OUTPUT"
86
+ echo "SDIST_NAME=$(basename $SDIST)" >> "$GITHUB_OUTPUT"
87
+ echo "WHEEL_NAME=$(basename $WHEEL)" >> "$GITHUB_OUTPUT"
88
+ shell: bash
89
+
90
+ - name: Compose release body
91
+ id: release_body
92
+ env:
93
+ PYPI_PUBLISH: ${{ steps.release_type.outputs.PYPI_PUBLISH }}
94
+ REPO: ${{ github.repository }}
95
+ GITHUB_REF_NAME: ${{ github.ref_name }}
96
+ run: |
97
+ PROJ_NAME="${REPO#*/}"
98
+ VERSION="${GITHUB_REF_NAME#r}"
99
+ BODY_FILE=$(mktemp)
100
+ if [ "$PYPI_PUBLISH" = "true" ]; then
101
+ {
102
+ echo "Install from PyPI:"
103
+ echo ""
104
+ echo '```bash'
105
+ echo "pip install ${PROJ_NAME}==${VERSION}"
106
+ echo '```'
107
+ echo ""
108
+ echo "PyPI page: https://pypi.org/project/${PROJ_NAME}/${VERSION}/"
109
+ } >"$BODY_FILE"
110
+ else
111
+ {
112
+ echo "**Preview build** \u2014 available only from GitHub Assets."
113
+ echo ""
114
+ echo "This build is not published to PyPI."
115
+ echo ""
116
+ echo "To try it, download the wheel from the Assets section below and install:"
117
+ echo ""
118
+ echo '```bash'
119
+ echo "pip install ./${PROJ_NAME}-*.whl"
120
+ echo '```'
121
+ } >"$BODY_FILE"
122
+ fi
123
+ {
124
+ echo "BODY<<GITHUB_EOF_MARKER"
125
+ cat "$BODY_FILE"
126
+ echo "GITHUB_EOF_MARKER"
127
+ } >> "$GITHUB_OUTPUT"
128
+ rm -f "$BODY_FILE"
129
+ shell: bash
130
+
131
+ - name: Upload dist artifacts
132
+ uses: actions/upload-artifact@v4
133
+ with:
134
+ name: dist-artifacts-${{ steps.get_tag.outputs.TAG }}
135
+ path: dist/
136
+ if-no-files-found: error
137
+
138
+ - name: Create GitHub Release
139
+ id: create_release
140
+ uses: actions/create-release@v1
141
+ env:
142
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
143
+ with:
144
+ tag_name: ${{ steps.get_tag.outputs.TAG }}
145
+ release_name: Release ${{ steps.get_tag.outputs.TAG }}
146
+ body: ${{ steps.release_body.outputs.BODY }}
147
+ draft: false
148
+ prerelease: ${{ steps.release_type.outputs.PRERELEASE }}
149
+
150
+ - name: Upload sdist to GitHub Release
151
+ uses: actions/upload-release-asset@v1
152
+ env:
153
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
154
+ with:
155
+ upload_url: ${{ steps.create_release.outputs.upload_url }}
156
+ asset_path: ${{ steps.assets.outputs.SDIST }}
157
+ asset_name: ${{ steps.assets.outputs.SDIST_NAME }}
158
+ asset_content_type: application/gzip
159
+
160
+ - name: Upload wheel to GitHub Release
161
+ uses: actions/upload-release-asset@v1
162
+ env:
163
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
164
+ with:
165
+ upload_url: ${{ steps.create_release.outputs.upload_url }}
166
+ asset_path: ${{ steps.assets.outputs.WHEEL }}
167
+ asset_name: ${{ steps.assets.outputs.WHEEL_NAME }}
168
+ asset_content_type: application/zip
169
+
170
+ pypi-publish:
171
+ name: Publish to PyPI
172
+ runs-on: ubuntu-latest
173
+ needs: github-release
174
+ if: startsWith(github.ref, 'refs/tags/r') && !contains(github.ref_name, '-')
175
+ environment:
176
+ name: pypi
177
+ url: https://pypi.org/p/${{ github.event.repository.name }}
178
+ permissions:
179
+ id-token: write
180
+ contents: read
181
+
182
+ steps:
183
+ - name: Download dist artifacts from github-release job
184
+ uses: actions/download-artifact@v4
185
+ with:
186
+ name: dist-artifacts-${{ github.ref_name }}
187
+ path: dist
188
+
189
+ - name: Publish package distributions to PyPI
190
+ uses: pypa/gh-action-pypi-publish@release/v1
@@ -0,0 +1,40 @@
1
+ # project
2
+ /.idea/
3
+ /.venv/
4
+ /build/
5
+ /dist/
6
+ /*.egg-info/
7
+ /.eggs/
8
+ /.pytest_cache/
9
+ /.mypy_cache/
10
+ /.ruff_cache/
11
+ /.tox/
12
+ /.nox/
13
+ /htmlcov/
14
+ /.coverage
15
+ /coverage.xml
16
+ /.hypothesis/
17
+ /.cache/
18
+ /.upload/
19
+ /.streamlit/
20
+ /.ipynb_checkpoints/
21
+ *.log
22
+ .env
23
+
24
+ # generated files
25
+ seetapsych_gaze/_version.py
26
+
27
+ # compiled files
28
+ *.pyc
29
+ __pycache__/
30
+ *.pyo
31
+ *.pyd
32
+ *.so
33
+ *$py.class
34
+
35
+ # models
36
+ *.pth
37
+ *.onnx
38
+ *.safetensors
39
+ *.pkl
40
+ *.zip
@@ -0,0 +1,96 @@
1
+ # Development Guide
2
+
3
+ ## Local Verification (Before Creating a Release Tag)
4
+
5
+ Run these commands from the repository root. Make sure you have [`uv`](https://github.com/astral-sh/uv) installed.
6
+
7
+ ```bash
8
+ # Per-project: set PACKAGE to the top-level importable package directory
9
+ PACKAGE=seetapsych_gaze
10
+ # For any seetapsych-* project, auto-detect instead:
11
+ # PACKAGE="$(ls -d seetapsych_* 2>/dev/null | head -n1)"
12
+
13
+ # 1. Sync dependencies (installs the package + dev tools)
14
+ uv sync --group dev
15
+
16
+ # 2. Lint (ruff) (use `ruff check . --fix` to fix)
17
+ uv run ruff check .
18
+
19
+ # 3. Format check (ruff format -- non-destructive; use `ruff format` to apply)
20
+ uv run ruff format --check .
21
+
22
+ # 4. Static type check (mypy, strict mode)
23
+ uv run mypy "$PACKAGE"
24
+
25
+ # 5. Security scan (bandit)
26
+ uv run bandit -r "$PACKAGE" -c pyproject.toml
27
+
28
+ # 6. Unit tests (pytest)
29
+ uv run pytest
30
+
31
+ # 7. Build the distribution packages + verify metadata
32
+ uv run python -m build
33
+ uv run twine check dist/*
34
+ ```
35
+
36
+ If all seven steps pass, the code is ready to be tagged for release.
37
+
38
+ ## Tag Naming and Release Pipeline
39
+
40
+ Tag format is managed by [`hatch-vcs`](https://github.com/ofek/hatch-vcs) with the following pattern in `pyproject.toml`:
41
+
42
+ ```
43
+ tag-pattern = "^r(?P<version>[^-]+)$"
44
+ ```
45
+
46
+ This separates tags into two classes that drive the GitHub Actions pipeline in `.github/workflows/publish.yml`:
47
+
48
+ ### Class A — Official Release: `r<version>` (no `-`)
49
+
50
+ **Format**: `r` + a version string that contains **no hyphen** `-`.
51
+
52
+ Examples:
53
+ - `r0.1.0`
54
+ - `r2026.08.30`
55
+ - `r1.0.0.post1`
56
+
57
+ Pipeline behavior:
58
+ 1. CI runs (lint + test + build).
59
+ 2. `github-release` job builds sdist + wheel, **creates a GitHub Release** (`prerelease: false`), attaches both assets, and links to the PyPI version page.
60
+ 3. `pypi-publish` job runs (`if: no '-' in tag`) and uploads the same sdist + wheel to PyPI via Trusted Publisher (OIDC, no API token required).
61
+
62
+ ### Class B — Temporary / Pre-release: `r<version>-<suffix>`
63
+
64
+ **Format**: `r` + anything + **at least one hyphen** `-` + anything.
65
+
66
+ Examples:
67
+ - `r0.2.0-alpha`
68
+ - `r0.2.0-rc1`
69
+ - `r2026.08.30-tmp-hotfix-42`
70
+ - `r1.0.0-just-testing-release-flow`
71
+
72
+ Pipeline behavior:
73
+ 1. CI still runs (same lint + test + build gates — everything must still pass).
74
+ 2. `github-release` job builds sdist + wheel, creates a GitHub Release **marked as `prerelease: true`**, attaches both assets, and the release body clearly states "not published to PyPI".
75
+ 3. `pypi-publish` job is **skipped** (`if:` condition fails because the tag contains `-`). Nothing is uploaded to PyPI.
76
+
77
+ ### Quick Tagging Recipe
78
+
79
+ ```bash
80
+ # --- official release (PyPI + GitHub Release) ---
81
+ git tag r0.1.0
82
+ git push origin r0.1.0
83
+
84
+ # --- temp / pre-release (GitHub Release only, PyPI skipped) ---
85
+ git tag r0.1.0-alpha
86
+ git push origin r0.1.0-alpha
87
+ ```
88
+
89
+ ### Why the two classes?
90
+
91
+ Use Class B tags whenever you want to:
92
+ - exercise the full build + release-creation pipeline end-to-end without polluting PyPI,
93
+ - ship a throwaway build for QA or a staging consumer that can pull GitHub Release assets directly,
94
+ - share candidate wheels for a hotfix before cutting the final tag.
95
+
96
+ When the candidate is validated, re-tag without the suffix (e.g., `r0.1.0`) and push — the same CI gates run again, followed by the official PyPI publish.
@@ -0,0 +1,15 @@
1
+ Copyright (c) 2026, Visual Information Processing and Learning (VIPL) group,
2
+ Institute of Computing Technology, Chinese Academy of Sciences, Beijing, China;
3
+ Southeast University, China;
4
+ Beijing Seetatech Co., Ltd.
5
+ All rights reserved.
6
+
7
+ Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
8
+
9
+ 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
10
+
11
+ 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
12
+
13
+ 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
14
+
15
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
@@ -0,0 +1,155 @@
1
+ Metadata-Version: 2.5
2
+ Name: seetapsych-gaze
3
+ Version: 0.0.2
4
+ Summary: Gaze estimation modules for SeetaPsych
5
+ Project-URL: Homepage, https://github.com/seetapsych/seetapsych-gaze
6
+ Project-URL: Repository, https://github.com/seetapsych/seetapsych-gaze
7
+ Project-URL: Issues, https://github.com/seetapsych/seetapsych-gaze/issues
8
+ License: Copyright (c) 2026, Visual Information Processing and Learning (VIPL) group,
9
+ Institute of Computing Technology, Chinese Academy of Sciences, Beijing, China;
10
+ Southeast University, China;
11
+ Beijing Seetatech Co., Ltd.
12
+ All rights reserved.
13
+
14
+ Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
15
+
16
+ 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
17
+
18
+ 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
19
+
20
+ 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
21
+
22
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23
+ License-File: LICENSE
24
+ Requires-Python: >=3.10
25
+ Requires-Dist: seetapsych-lib
26
+ Provides-Extra: all
27
+ Requires-Dist: mediapipe>=0.10.33; extra == 'all'
28
+ Requires-Dist: mmengine>=0.10.7; extra == 'all'
29
+ Requires-Dist: numpy>=2.2.6; extra == 'all'
30
+ Requires-Dist: onnx>=1.20.1; extra == 'all'
31
+ Requires-Dist: onnxruntime-gpu<1.24; (sys_platform != 'darwin' and python_version <= '3.10') and extra == 'all'
32
+ Requires-Dist: onnxruntime-gpu>=1.24; (sys_platform != 'darwin' and python_version > '3.10') and extra == 'all'
33
+ Requires-Dist: onnxruntime<1.24; (sys_platform == 'darwin' and python_version <= '3.10') and extra == 'all'
34
+ Requires-Dist: onnxruntime>=1.24; (sys_platform == 'darwin' and python_version > '3.10') and extra == 'all'
35
+ Requires-Dist: opencv-python>=4.13.0.92; extra == 'all'
36
+ Requires-Dist: pillow>=12.2.0; extra == 'all'
37
+ Requires-Dist: safetensors>=0.7.0; extra == 'all'
38
+ Requires-Dist: scipy>=1.15.3; extra == 'all'
39
+ Requires-Dist: timm>=1.0.26; extra == 'all'
40
+ Requires-Dist: torch>=2.10.0; extra == 'all'
41
+ Requires-Dist: torchvision>=0.25.0; extra == 'all'
42
+ Provides-Extra: dev
43
+ Requires-Dist: bandit>=1.7; extra == 'dev'
44
+ Requires-Dist: build>=1.4.4; extra == 'dev'
45
+ Requires-Dist: mediapipe>=0.10.33; extra == 'dev'
46
+ Requires-Dist: mmengine>=0.10.7; extra == 'dev'
47
+ Requires-Dist: mypy>=1.11; extra == 'dev'
48
+ Requires-Dist: numpy>=2.2.6; extra == 'dev'
49
+ Requires-Dist: onnx>=1.20.1; extra == 'dev'
50
+ Requires-Dist: onnxruntime-gpu<1.24; (sys_platform != 'darwin' and python_version <= '3.10') and extra == 'dev'
51
+ Requires-Dist: onnxruntime-gpu>=1.24; (sys_platform != 'darwin' and python_version > '3.10') and extra == 'dev'
52
+ Requires-Dist: onnxruntime<1.24; (sys_platform == 'darwin' and python_version <= '3.10') and extra == 'dev'
53
+ Requires-Dist: onnxruntime>=1.24; (sys_platform == 'darwin' and python_version > '3.10') and extra == 'dev'
54
+ Requires-Dist: opencv-python>=4.13.0.92; extra == 'dev'
55
+ Requires-Dist: pillow>=12.2.0; extra == 'dev'
56
+ Requires-Dist: pytest>=8.0; extra == 'dev'
57
+ Requires-Dist: ruff>=0.6; extra == 'dev'
58
+ Requires-Dist: safetensors>=0.7.0; extra == 'dev'
59
+ Requires-Dist: scipy-stubs>=1.15.3.0; extra == 'dev'
60
+ Requires-Dist: scipy>=1.15.3; extra == 'dev'
61
+ Requires-Dist: timm>=1.0.26; extra == 'dev'
62
+ Requires-Dist: torch>=2.10.0; extra == 'dev'
63
+ Requires-Dist: torchvision>=0.25.0; extra == 'dev'
64
+ Requires-Dist: twine>=6.2.0; extra == 'dev'
65
+ Description-Content-Type: text/markdown
66
+
67
+ # SeetaPsych Gaze
68
+
69
+ > Gaze estimation modules for SeetaPsych
70
+
71
+ ## Usage
72
+
73
+ This project is already included in the seetapsych-lib default configuration. Download and use it via `seetapsych-manager download`.
74
+
75
+ For usage, refer to [SeetaPsych](https://github.com/seetapsych/seetapsych-lib).
76
+
77
+ The gaze estimation algorithms depend on `open-gaze-estimation`. Please install it from GitHub separately:
78
+
79
+ ```bash
80
+ uv pip install git+https://github.com/Elorfiniel/open-gaze-estimation-2025-release.git
81
+ ```
82
+
83
+ You can additionally add this algorithm module using the following methods.
84
+
85
+ ### WebUI
86
+
87
+ Run `seetapsych-webui` with the `--files` argument to use it.
88
+
89
+ ```
90
+ seetapsych-webui --files \
91
+ seetapsych_gaze/modules/affnet.yml \
92
+ seetapsych_gaze/modules/itracker-plus.yml \
93
+ seetapsych_gaze/modules/tdgazenet.yml
94
+ ```
95
+
96
+ ### Programmatic Usage
97
+
98
+ Add the following code in your program to use this algorithm module.
99
+
100
+ ```python
101
+ from seetapsych_lib.runtime.factory import Factory
102
+ from seetapsych_lib.runtime.pipeline import Pipeline
103
+
104
+ factory = Factory()
105
+ factory.load_file_modules("seetapsych_gaze/modules/affnet.yml")
106
+
107
+ pipeline = Pipeline(factory, ...)
108
+
109
+ pipeline.add_attributes("face/gaze-screen")
110
+ ```
111
+
112
+ ## Introduction
113
+
114
+ ### OpenGaze-AFFNet
115
+
116
+ PyTorch-based appearance feature fusion gaze estimation model (AFFNet). Accepts face image, left/right eye crops, and face bounding box rectangles as input. Estimates 2D gaze point on screen. Requires `face/mesh` (MediaPipe 468 landmarks) for eye alignment and face cropping.
117
+
118
+ Module config: [affnet.yml](seetapsych_gaze/modules/affnet.yml).
119
+ Provide Attributes: `face/gaze-screen`.
120
+
121
+ Requires: `face/mesh`.
122
+
123
+ Available model: `model-AFFNet-mit-gaze-capture-e20.safetensors`.
124
+
125
+ Parameters:
126
+ - `data` (object): Camera and screen calibration settings including intrinsic/extrinsic matrices, screen dimensions.
127
+
128
+ ### OpenGaze-ITrackerPlus
129
+
130
+ ONNX-based ITrackerPlus gaze estimation model. Accepts face crop, left/right eye crops, and facial keypoints as input. Uses MediaPipe FaceMesh for landmark detection. Estimates 2D gaze point on screen.
131
+
132
+ Module config: [itracker-plus.yml](seetapsych_gaze/modules/itracker-plus.yml).
133
+ Provide Attributes: `face/gaze-screen`.
134
+
135
+ Requires: `face/mesh`.
136
+
137
+ Available model: `model-ITrackerPlus-oppo-data-e12.onnx`.
138
+
139
+ Parameters:
140
+ - `data` (object): Camera and screen calibration settings.
141
+
142
+ ### OpenGaze-TdGazeNet
143
+
144
+ PyTorch-based TdGazeNet (multi-task) gaze estimation model. Predicts 3D face keypoints (151 pts), eye keypoints (110 pts each), and 3D gaze vectors simultaneously. Supports reparameterization optimization for faster inference.
145
+
146
+ Module config: [tdgazenet.yml](seetapsych_gaze/modules/tdgazenet.yml).
147
+ Provide Attributes: `face/gaze-screen`.
148
+
149
+ Requires: `face/mesh`.
150
+
151
+ Available model: `model-TdGazeNet-ucas-synthgaze-e50.safetensors`.
152
+
153
+ Parameters:
154
+ - `optimize` (selection, default `none`): `none` or `reparameterize`. Optionally reparameterize the model for inference speedup.
155
+ - `data` (object): Camera intrinsic, extrinsic, distortion, screen settings, and model architecture config.