faceswitch 0.2.0__tar.gz → 0.2.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 (35) hide show
  1. faceswitch-0.2.2/PKG-INFO +218 -0
  2. faceswitch-0.2.2/README.md +177 -0
  3. {faceswitch-0.2.0 → faceswitch-0.2.2}/pyproject.toml +12 -3
  4. {faceswitch-0.2.0 → faceswitch-0.2.2}/src/faceswitch/__init__.py +8 -1
  5. {faceswitch-0.2.0 → faceswitch-0.2.2}/src/faceswitch/detectors/__init__.py +8 -1
  6. faceswitch-0.2.2/src/faceswitch/detectors/retinaface/__init__.py +6 -0
  7. faceswitch-0.2.2/src/faceswitch/detectors/retinaface/config.py +10 -0
  8. faceswitch-0.2.2/src/faceswitch/detectors/retinaface/detector.py +40 -0
  9. {faceswitch-0.2.0 → faceswitch-0.2.2}/src/faceswitch/detectors/yolo/detector.py +2 -2
  10. faceswitch-0.2.2/src/faceswitch.egg-info/PKG-INFO +218 -0
  11. {faceswitch-0.2.0 → faceswitch-0.2.2}/src/faceswitch.egg-info/SOURCES.txt +4 -0
  12. faceswitch-0.2.2/src/faceswitch.egg-info/requires.txt +23 -0
  13. faceswitch-0.2.2/tests/test_hog_detector.py +97 -0
  14. faceswitch-0.2.2/tests/test_retinaface_detector.py +79 -0
  15. faceswitch-0.2.2/tests/test_yolo_detector.py +98 -0
  16. faceswitch-0.2.0/PKG-INFO +0 -66
  17. faceswitch-0.2.0/README.md +0 -34
  18. faceswitch-0.2.0/src/faceswitch.egg-info/PKG-INFO +0 -66
  19. faceswitch-0.2.0/src/faceswitch.egg-info/requires.txt +0 -11
  20. faceswitch-0.2.0/tests/test_hog_detector.py +0 -34
  21. faceswitch-0.2.0/tests/test_yolo_detector.py +0 -36
  22. {faceswitch-0.2.0 → faceswitch-0.2.2}/LICENSE +0 -0
  23. {faceswitch-0.2.0 → faceswitch-0.2.2}/setup.cfg +0 -0
  24. {faceswitch-0.2.0 → faceswitch-0.2.2}/src/faceswitch/core/__init__.py +0 -0
  25. {faceswitch-0.2.0 → faceswitch-0.2.2}/src/faceswitch/core/interfaces.py +0 -0
  26. {faceswitch-0.2.0 → faceswitch-0.2.2}/src/faceswitch/core/types.py +0 -0
  27. {faceswitch-0.2.0 → faceswitch-0.2.2}/src/faceswitch/detectors/hog/__init__.py +0 -0
  28. {faceswitch-0.2.0 → faceswitch-0.2.2}/src/faceswitch/detectors/hog/config.py +0 -0
  29. {faceswitch-0.2.0 → faceswitch-0.2.2}/src/faceswitch/detectors/hog/detector.py +0 -0
  30. {faceswitch-0.2.0 → faceswitch-0.2.2}/src/faceswitch/detectors/yolo/__init__.py +0 -0
  31. {faceswitch-0.2.0 → faceswitch-0.2.2}/src/faceswitch/detectors/yolo/config.py +0 -0
  32. {faceswitch-0.2.0 → faceswitch-0.2.2}/src/faceswitch/py.typed +0 -0
  33. {faceswitch-0.2.0 → faceswitch-0.2.2}/src/faceswitch.egg-info/dependency_links.txt +0 -0
  34. {faceswitch-0.2.0 → faceswitch-0.2.2}/src/faceswitch.egg-info/top_level.txt +0 -0
  35. {faceswitch-0.2.0 → faceswitch-0.2.2}/tests/test_public_api.py +0 -0
@@ -0,0 +1,218 @@
1
+ Metadata-Version: 2.4
2
+ Name: faceswitch
3
+ Version: 0.2.2
4
+ Summary: Simple multi-model face detection library
5
+ Author: FaceSwitch Contributors
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://github.com/game-sys/FaceSwitch
8
+ Project-URL: Bug Tracker, https://github.com/game-sys/FaceSwitch/issues
9
+ Project-URL: Documentation, https://github.com/game-sys/FaceSwitch/blob/main/README.md
10
+ Keywords: face-detection,computer-vision,hog,dlib
11
+ Classifier: Development Status :: 3 - Alpha
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: Programming Language :: Python :: 3
14
+ Classifier: Programming Language :: Python :: 3.10
15
+ Classifier: Programming Language :: Python :: 3.11
16
+ Classifier: Programming Language :: Python :: 3.12
17
+ Classifier: Programming Language :: Python :: 3.13
18
+ Classifier: Topic :: Scientific/Engineering :: Image Recognition
19
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
20
+ Requires-Python: >=3.10
21
+ Description-Content-Type: text/markdown
22
+ License-File: LICENSE
23
+ Provides-Extra: hog
24
+ Requires-Dist: dlib>=19.24; extra == "hog"
25
+ Provides-Extra: yolo
26
+ Requires-Dist: ultralytics>=8.0.0; extra == "yolo"
27
+ Requires-Dist: torch>=2.0.0; extra == "yolo"
28
+ Provides-Extra: examples
29
+ Requires-Dist: opencv-python>=4.8; extra == "examples"
30
+ Provides-Extra: dev
31
+ Requires-Dist: pytest>=8.0; extra == "dev"
32
+ Provides-Extra: retinaface
33
+ Requires-Dist: retina-face; extra == "retinaface"
34
+ Provides-Extra: all
35
+ Requires-Dist: dlib>=19.24; extra == "all"
36
+ Requires-Dist: ultralytics>=8.0.0; extra == "all"
37
+ Requires-Dist: torch>=2.0.0; extra == "all"
38
+ Requires-Dist: opencv-python>=4.8; extra == "all"
39
+ Requires-Dist: retina-face; extra == "all"
40
+ Dynamic: license-file
41
+
42
+ # FaceSwitch
43
+
44
+ **Detect faces in any image with one line of Python — swap the detector without changing your code.**
45
+
46
+ FaceSwitch is a lightweight Python library that wraps multiple face detection engines behind a single, consistent interface. Pick the detector that suits your needs, swap it later without rewriting anything, and only install what you actually use.
47
+
48
+ ---
49
+
50
+ ## What does it do?
51
+
52
+ You give it an image. It tells you where the faces are.
53
+
54
+ ```python
55
+ from faceswitch.detectors.yolo import YoloDetector
56
+ import cv2
57
+
58
+ image = cv2.imread("photo.jpg")
59
+ detector = YoloDetector()
60
+ faces = detector.detect(image)
61
+
62
+ for face in faces:
63
+ print(f"Face at ({face.x1}, {face.y1}) → ({face.x2}, {face.y2})")
64
+ ```
65
+
66
+ Every detector returns the same thing — a list of face boxes — so switching from YOLO to HOG (or any other detector) is just changing one import line.
67
+
68
+ ---
69
+
70
+ ## Installation
71
+
72
+ You need Python 3.10 or newer.
73
+
74
+ **Step 1 — install the base library:**
75
+
76
+ ```bash
77
+ pip install faceswitch
78
+ ```
79
+
80
+ **Step 2 — install the detector you want to use:**
81
+
82
+ | Detector | What it is | Install command |
83
+ |---|---|---|
84
+ | HOG | Classic CPU-based detector (fast, lightweight, no GPU needed) | `pip install "faceswitch[hog]"` |
85
+ | YOLO | Deep learning detector (more accurate, works best with GPU) | `pip install "faceswitch[yolo]"` |
86
+ | RetinaFace | High-accuracy ResNet detector (best for difficult angles and small faces) | `pip install "faceswitch[retinaface]"` |
87
+
88
+ | RetinaFace | Deep learning face detector using ResNet+FPN with multi-scale anchors for high-accuracy detection. | `pip install "faceswitch[retinaface]"` |
89
+
90
+ **Or install everything at once:**
91
+
92
+ ```bash
93
+ pip install "faceswitch[all]"
94
+ ```
95
+
96
+ ---
97
+
98
+ ## Quick start — 3 lines to detect faces
99
+
100
+ ```python
101
+ import cv2
102
+ from faceswitch.detectors.hog import HogDetector # swap this line to switch detectors
103
+
104
+ image = cv2.imread("photo.jpg")
105
+ faces = HogDetector().detect(image)
106
+
107
+ print(f"Found {len(faces)} face(s)")
108
+ ```
109
+
110
+ To use a different detector, change only the import:
111
+
112
+ ```python
113
+ from faceswitch.detectors.yolo import YoloDetector # YOLO
114
+ from faceswitch.detectors.retinaface import RetinaFaceDetector # RetinaFace
115
+ ```
116
+
117
+ Everything else stays exactly the same.
118
+
119
+ ---
120
+
121
+ ## Understanding the results
122
+
123
+ `detector.detect(image)` always returns a list of `FaceBox` objects. Each one looks like this:
124
+
125
+ ```
126
+ FaceBox(x1=120, y1=45, x2=210, y2=160, confidence=0.97)
127
+ ```
128
+
129
+ | Field | Meaning |
130
+ |---|---|
131
+ | `x1`, `y1` | Top-left corner of the face box (pixels) |
132
+ | `x2`, `y2` | Bottom-right corner of the face box (pixels) |
133
+ | `confidence` | How sure the detector is (0.0 to 1.0). Some detectors don't provide this (`None`). |
134
+
135
+ **Draw the boxes on your image:**
136
+
137
+ ```python
138
+ import cv2
139
+ from faceswitch.detectors.yolo import YoloDetector
140
+
141
+ image = cv2.imread("photo.jpg")
142
+ faces = YoloDetector().detect(image)
143
+
144
+ for face in faces:
145
+ cv2.rectangle(image, (face.x1, face.y1), (face.x2, face.y2), (0, 255, 0), 2)
146
+
147
+ cv2.imwrite("result.jpg", image)
148
+ print(f"Saved result.jpg with {len(faces)} face(s) highlighted")
149
+ ```
150
+
151
+ ---
152
+
153
+ ## Choosing the right detector
154
+
155
+ | | HOG | YOLO | RetinaFace |
156
+ |---|---|---|---|
157
+ | **Speed** | Fast | Medium | Slower |
158
+ | **Accuracy** | Basic | High | Very high |
159
+ | **GPU needed?** | No | Optional | No |
160
+ | **Best for** | Quick scripts, low-power machines | General use, real-time video | Difficult angles, small faces, production use |
161
+ | **Install size** | Small (~80MB) | Large (~500MB with torch) | Large (~200MB with TensorFlow) |
162
+
163
+ **Not sure?** Start with HOG. If it misses faces, switch to YOLO or RetinaFace — your code won't change.
164
+
165
+ ---
166
+
167
+ ## Available detectors
168
+
169
+ ### HOG — `pip install "faceswitch[hog]"`
170
+
171
+ Uses dlib's Histogram of Oriented Gradients detector. Works entirely on CPU, very fast, good for frontal faces.
172
+
173
+ ```python
174
+ from faceswitch.detectors.hog import HogDetector
175
+ faces = HogDetector().detect(image)
176
+ ```
177
+
178
+ ### YOLO — `pip install "faceswitch[yolo]"`
179
+
180
+ Uses Ultralytics YOLOv8. Deep learning-based, excellent accuracy on varied poses and lighting. Downloads a model on first use (~6MB).
181
+
182
+ ```python
183
+ from faceswitch.detectors.yolo import YoloDetector
184
+ faces = YoloDetector().detect(image)
185
+ ```
186
+
187
+ ### RetinaFace — `pip install "faceswitch[retinaface]"`
188
+
189
+ Uses the serengil/retinaface ResNet+FPN model. Best accuracy on small faces, side profiles, and crowded images. Downloads model weights on first use (~120MB).
190
+
191
+ ```python
192
+ from faceswitch.detectors.retinaface import RetinaFaceDetector
193
+ faces = RetinaFaceDetector().detect(image)
194
+ ```
195
+
196
+ ---
197
+
198
+ ## Common questions
199
+
200
+ **Do I need a GPU?**
201
+ No. All detectors run on CPU. YOLO and RetinaFace are faster with a GPU but don't require one.
202
+
203
+ **I get "ImportError: ... install faceswitch[hog]"**
204
+ You installed the base library but not the detector dependency. Run the install command from the table above.
205
+
206
+ **The detector downloads a model on first use — is that normal?**
207
+ Yes. YOLO (~6MB) and RetinaFace (~120MB) download their model weights automatically the first time you use them. After that, they're cached locally.
208
+
209
+ **Can I use my own image loading library instead of OpenCV?**
210
+ Yes, as long as the image is a NumPy array with shape `(height, width, 3)` and `uint8` dtype (standard BGR or RGB image). `cv2.imread()` gives you this automatically.
211
+
212
+ ---
213
+
214
+ ## More detectors coming
215
+
216
+ FaceSwitch is actively maintained. New detectors are added regularly — run `pip install --upgrade faceswitch` to get the latest.
217
+
218
+ Current version: **0.2.2** | [GitHub](https://github.com/game-sys/FaceSwitch) | [PyPI](https://pypi.org/project/faceswitch/)
@@ -0,0 +1,177 @@
1
+ # FaceSwitch
2
+
3
+ **Detect faces in any image with one line of Python — swap the detector without changing your code.**
4
+
5
+ FaceSwitch is a lightweight Python library that wraps multiple face detection engines behind a single, consistent interface. Pick the detector that suits your needs, swap it later without rewriting anything, and only install what you actually use.
6
+
7
+ ---
8
+
9
+ ## What does it do?
10
+
11
+ You give it an image. It tells you where the faces are.
12
+
13
+ ```python
14
+ from faceswitch.detectors.yolo import YoloDetector
15
+ import cv2
16
+
17
+ image = cv2.imread("photo.jpg")
18
+ detector = YoloDetector()
19
+ faces = detector.detect(image)
20
+
21
+ for face in faces:
22
+ print(f"Face at ({face.x1}, {face.y1}) → ({face.x2}, {face.y2})")
23
+ ```
24
+
25
+ Every detector returns the same thing — a list of face boxes — so switching from YOLO to HOG (or any other detector) is just changing one import line.
26
+
27
+ ---
28
+
29
+ ## Installation
30
+
31
+ You need Python 3.10 or newer.
32
+
33
+ **Step 1 — install the base library:**
34
+
35
+ ```bash
36
+ pip install faceswitch
37
+ ```
38
+
39
+ **Step 2 — install the detector you want to use:**
40
+
41
+ | Detector | What it is | Install command |
42
+ |---|---|---|
43
+ | HOG | Classic CPU-based detector (fast, lightweight, no GPU needed) | `pip install "faceswitch[hog]"` |
44
+ | YOLO | Deep learning detector (more accurate, works best with GPU) | `pip install "faceswitch[yolo]"` |
45
+ | RetinaFace | High-accuracy ResNet detector (best for difficult angles and small faces) | `pip install "faceswitch[retinaface]"` |
46
+
47
+ | RetinaFace | Deep learning face detector using ResNet+FPN with multi-scale anchors for high-accuracy detection. | `pip install "faceswitch[retinaface]"` |
48
+
49
+ **Or install everything at once:**
50
+
51
+ ```bash
52
+ pip install "faceswitch[all]"
53
+ ```
54
+
55
+ ---
56
+
57
+ ## Quick start — 3 lines to detect faces
58
+
59
+ ```python
60
+ import cv2
61
+ from faceswitch.detectors.hog import HogDetector # swap this line to switch detectors
62
+
63
+ image = cv2.imread("photo.jpg")
64
+ faces = HogDetector().detect(image)
65
+
66
+ print(f"Found {len(faces)} face(s)")
67
+ ```
68
+
69
+ To use a different detector, change only the import:
70
+
71
+ ```python
72
+ from faceswitch.detectors.yolo import YoloDetector # YOLO
73
+ from faceswitch.detectors.retinaface import RetinaFaceDetector # RetinaFace
74
+ ```
75
+
76
+ Everything else stays exactly the same.
77
+
78
+ ---
79
+
80
+ ## Understanding the results
81
+
82
+ `detector.detect(image)` always returns a list of `FaceBox` objects. Each one looks like this:
83
+
84
+ ```
85
+ FaceBox(x1=120, y1=45, x2=210, y2=160, confidence=0.97)
86
+ ```
87
+
88
+ | Field | Meaning |
89
+ |---|---|
90
+ | `x1`, `y1` | Top-left corner of the face box (pixels) |
91
+ | `x2`, `y2` | Bottom-right corner of the face box (pixels) |
92
+ | `confidence` | How sure the detector is (0.0 to 1.0). Some detectors don't provide this (`None`). |
93
+
94
+ **Draw the boxes on your image:**
95
+
96
+ ```python
97
+ import cv2
98
+ from faceswitch.detectors.yolo import YoloDetector
99
+
100
+ image = cv2.imread("photo.jpg")
101
+ faces = YoloDetector().detect(image)
102
+
103
+ for face in faces:
104
+ cv2.rectangle(image, (face.x1, face.y1), (face.x2, face.y2), (0, 255, 0), 2)
105
+
106
+ cv2.imwrite("result.jpg", image)
107
+ print(f"Saved result.jpg with {len(faces)} face(s) highlighted")
108
+ ```
109
+
110
+ ---
111
+
112
+ ## Choosing the right detector
113
+
114
+ | | HOG | YOLO | RetinaFace |
115
+ |---|---|---|---|
116
+ | **Speed** | Fast | Medium | Slower |
117
+ | **Accuracy** | Basic | High | Very high |
118
+ | **GPU needed?** | No | Optional | No |
119
+ | **Best for** | Quick scripts, low-power machines | General use, real-time video | Difficult angles, small faces, production use |
120
+ | **Install size** | Small (~80MB) | Large (~500MB with torch) | Large (~200MB with TensorFlow) |
121
+
122
+ **Not sure?** Start with HOG. If it misses faces, switch to YOLO or RetinaFace — your code won't change.
123
+
124
+ ---
125
+
126
+ ## Available detectors
127
+
128
+ ### HOG — `pip install "faceswitch[hog]"`
129
+
130
+ Uses dlib's Histogram of Oriented Gradients detector. Works entirely on CPU, very fast, good for frontal faces.
131
+
132
+ ```python
133
+ from faceswitch.detectors.hog import HogDetector
134
+ faces = HogDetector().detect(image)
135
+ ```
136
+
137
+ ### YOLO — `pip install "faceswitch[yolo]"`
138
+
139
+ Uses Ultralytics YOLOv8. Deep learning-based, excellent accuracy on varied poses and lighting. Downloads a model on first use (~6MB).
140
+
141
+ ```python
142
+ from faceswitch.detectors.yolo import YoloDetector
143
+ faces = YoloDetector().detect(image)
144
+ ```
145
+
146
+ ### RetinaFace — `pip install "faceswitch[retinaface]"`
147
+
148
+ Uses the serengil/retinaface ResNet+FPN model. Best accuracy on small faces, side profiles, and crowded images. Downloads model weights on first use (~120MB).
149
+
150
+ ```python
151
+ from faceswitch.detectors.retinaface import RetinaFaceDetector
152
+ faces = RetinaFaceDetector().detect(image)
153
+ ```
154
+
155
+ ---
156
+
157
+ ## Common questions
158
+
159
+ **Do I need a GPU?**
160
+ No. All detectors run on CPU. YOLO and RetinaFace are faster with a GPU but don't require one.
161
+
162
+ **I get "ImportError: ... install faceswitch[hog]"**
163
+ You installed the base library but not the detector dependency. Run the install command from the table above.
164
+
165
+ **The detector downloads a model on first use — is that normal?**
166
+ Yes. YOLO (~6MB) and RetinaFace (~120MB) download their model weights automatically the first time you use them. After that, they're cached locally.
167
+
168
+ **Can I use my own image loading library instead of OpenCV?**
169
+ Yes, as long as the image is a NumPy array with shape `(height, width, 3)` and `uint8` dtype (standard BGR or RGB image). `cv2.imread()` gives you this automatically.
170
+
171
+ ---
172
+
173
+ ## More detectors coming
174
+
175
+ FaceSwitch is actively maintained. New detectors are added regularly — run `pip install --upgrade faceswitch` to get the latest.
176
+
177
+ Current version: **0.2.2** | [GitHub](https://github.com/game-sys/FaceSwitch) | [PyPI](https://pypi.org/project/faceswitch/)
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "faceswitch"
7
- version = "0.2.0"
7
+ version = "0.2.2"
8
8
  description = "Simple multi-model face detection library"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.10"
@@ -22,7 +22,7 @@ classifiers = [
22
22
  "Topic :: Scientific/Engineering :: Image Recognition",
23
23
  "Topic :: Software Development :: Libraries :: Python Modules",
24
24
  ]
25
- dependencies = ["dlib>=19.24"]
25
+ dependencies = []
26
26
 
27
27
  [project.urls]
28
28
  "Homepage" = "https://github.com/game-sys/FaceSwitch"
@@ -30,9 +30,18 @@ dependencies = ["dlib>=19.24"]
30
30
  "Documentation" = "https://github.com/game-sys/FaceSwitch/blob/main/README.md"
31
31
 
32
32
  [project.optional-dependencies]
33
- hog = ["dlib>=19.24", "ultralytics>=8.0.0"]
33
+ hog = ["dlib>=19.24"]
34
+ yolo = ["ultralytics>=8.0.0", "torch>=2.0.0"]
34
35
  examples = ["opencv-python>=4.8"]
35
36
  dev = ["pytest>=8.0"]
37
+ retinaface = ["retina-face"]
38
+ all = [
39
+ "dlib>=19.24",
40
+ "ultralytics>=8.0.0",
41
+ "torch>=2.0.0",
42
+ "opencv-python>=4.8",
43
+ "retina-face"
44
+ ]
36
45
 
37
46
  [tool.setuptools]
38
47
  package-dir = {"" = "src"}
@@ -13,4 +13,11 @@ try:
13
13
  except ImportError:
14
14
  pass
15
15
 
16
- __version__ = "0.2.0"
16
+ __version__ = "0.2.2"
17
+
18
+ try:
19
+ from faceswitch.detectors.retinaface import RetinaFaceDetector, RetinaFaceDetectorConfig # noqa: F401
20
+
21
+ __all__ += ["RetinaFaceDetector", "RetinaFaceDetectorConfig"]
22
+ except ImportError:
23
+ pass
@@ -9,4 +9,11 @@ try:
9
9
 
10
10
  __all__ += ["YoloDetector", "YoloDetectorConfig"]
11
11
  except ImportError:
12
- pass
12
+ pass
13
+
14
+ try:
15
+ from faceswitch.detectors.retinaface import RetinaFaceDetector, RetinaFaceDetectorConfig # noqa: F401
16
+
17
+ __all__ += ["RetinaFaceDetector", "RetinaFaceDetectorConfig"]
18
+ except ImportError:
19
+ pass
@@ -0,0 +1,6 @@
1
+ """RetinaFace detector package."""
2
+
3
+ from faceswitch.detectors.retinaface.config import RetinaFaceDetectorConfig
4
+ from faceswitch.detectors.retinaface.detector import RetinaFaceDetector
5
+
6
+ __all__ = ["RetinaFaceDetector", "RetinaFaceDetectorConfig"]
@@ -0,0 +1,10 @@
1
+ from __future__ import annotations
2
+
3
+ from dataclasses import dataclass
4
+
5
+
6
+ @dataclass(frozen=True)
7
+ class RetinaFaceDetectorConfig:
8
+ """Configuration for RetinaFace detector."""
9
+
10
+ pass
@@ -0,0 +1,40 @@
1
+ from __future__ import annotations
2
+
3
+
4
+ import numpy as np
5
+ from numpy.typing import NDArray
6
+
7
+ from faceswitch.core.interfaces import FaceDetector
8
+ from faceswitch.core.types import FaceBox
9
+ from faceswitch.detectors.retinaface.config import RetinaFaceDetectorConfig
10
+
11
+
12
+ class RetinaFaceDetector(FaceDetector):
13
+ """RetinaFace face detector."""
14
+
15
+ def __init__(self, config: RetinaFaceDetectorConfig | None = None) -> None:
16
+ try:
17
+ from retinaface import RetinaFace as _rf # type: ignore
18
+ except ImportError as exc:
19
+ raise ImportError(
20
+ "RetinaFaceDetector requires optional dependency 'retinaface'. "
21
+ "Install with: pip install 'faceswitch[retinaface]'"
22
+ ) from exc
23
+
24
+ self.config = config or RetinaFaceDetectorConfig()
25
+ self._model = _rf
26
+
27
+ def detect(self, image: NDArray[np.uint8]) -> list[FaceBox]:
28
+ """Detect faces and return list of FaceBox (xyxy)."""
29
+ if image is None:
30
+ return []
31
+
32
+ results = self._model.detect_faces(image)
33
+ if not isinstance(results, dict):
34
+ return []
35
+ boxes = []
36
+ for face in results.values():
37
+ x1, y1, x2, y2 = face["facial_area"]
38
+ score = float(face.get("score", 1.0))
39
+ boxes.append(FaceBox(x1=int(x1), y1=int(y1), x2=int(x2), y2=int(y2), confidence=score))
40
+ return boxes
@@ -18,8 +18,8 @@ class YoloDetector(FaceDetector):
18
18
  # Put the real URL(s) you want to support
19
19
  _MODEL_URLS: dict[str, str] = {
20
20
  "yolov8n-face.pt": "https://github.com/YapaLab/yolo-face/releases/download/1.0.0/yolov8n-face.pt",
21
- # "yolov11n-face.pt": "...",
22
- # "yolov12n-face.pt": "...",
21
+ "yolov8m-face.pt": "https://github.com/YapaLab/yolo-face/releases/download/1.0.0/yolov8m-face.pt",
22
+ "yolov8l-face.pt": "https://github.com/YapaLab/yolo-face/releases/download/1.0.0/yolov8l-face.pt",
23
23
  }
24
24
 
25
25
  def __init__(self, config: YoloDetectorConfig | None = None) -> None: