-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathcollect_faces.py
More file actions
130 lines (111 loc) · 4.1 KB
/
collect_faces.py
File metadata and controls
130 lines (111 loc) · 4.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
```python
from pathlib import Path
import argparse
import time
import cv2
from face_utils import IMAGE_SIZE, build_face_detector, detect_and_preprocess, ensure_dir
def collect_faces(
label: str,
output_dir: Path,
target_count: int,
camera_index: int,
delay: float,
use_dnn: bool = True,
use_alignment: bool = True,
) -> None:
"""
Capture faces for the dataset.
Args:
label: Destination label folder (e.g., "authorized", "others", "user_1", "user_2")
output_dir: Root dataset directory
target_count: Number of face samples to capture
camera_index: Camera index
delay: Seconds to wait between saved frames
use_dnn: Use DNN face detector if available
use_alignment: Enable face alignment
"""
# Initialize face detector
detector = build_face_detector(use_dnn=use_dnn)
# Create output directory if it doesn't exist
save_dir = output_dir / label
ensure_dir(save_dir)
# Open camera
cap = cv2.VideoCapture(camera_index)
if not cap.isOpened():
raise RuntimeError(f"Cannot open camera {camera_index}")
# Initialize capture counters
captured = 0
last_face_time = 0
try:
# Capture loop
while captured < target_count:
# Read frame from camera
ret, frame = cap.read()
if not ret:
break
# Detect and preprocess face
face = detect_and_preprocess(
frame, detector, image_size=IMAGE_SIZE, use_alignment=use_alignment
)
# Save face if it's not None and delay has passed
if face is not None:
current_time = time.time()
if current_time - last_face_time >= delay:
# Create filename and save face
filename = save_dir / f"{int(time.time() * 1000)}.png"
cv2.imwrite(str(filename), face)
captured += 1
last_face_time = current_time
print(f"[{captured}/{target_count}] saved {filename}")
# Display capture counter on frame
cv2.putText(
frame,
f"Capture: {captured}/{target_count}",
(10, 30),
cv2.FONT_HERSHEY_SIMPLEX,
1.0,
(0, 255, 0),
2,
)
# Display frame
cv2.imshow("Face Capture", frame)
# Exit on 'q' or ESC key press
if (cv2.waitKey(1) & 0xFF) in (ord("q"), 27):
break
finally:
# Release camera and close windows
cap.release()
cv2.destroyAllWindows()
# Print capture summary
print(f"\n[OK] Capture complete: {captured} images saved in {save_dir}")
def parse_args() -> argparse.Namespace:
"""
Parse command line arguments.
Returns:
argparse.Namespace: Parsed arguments
"""
parser = argparse.ArgumentParser(description="Capture faces for dataset.")
parser.add_argument(
"--label",
default="authorized",
help='Destination label folder (e.g., "authorized", "others", "user_1", "user_2").',
)
parser.add_argument("--output-dir", type=Path, default=Path("data"), help="Root dataset directory.")
parser.add_argument("--count", type=int, default=40, help="Number of face samples to capture.")
parser.add_argument("--camera-index", type=int, default=0, help="Camera index.")
parser.add_argument("--delay", type=float, default=0.25, help="Seconds to wait between saved frames.")
parser.add_argument("--use-dnn", action="store_true", default=True, help="Use DNN face detector if available")
parser.add_argument("--use-alignment", action="store_true", default=True, help="Enable face alignment")
return parser.parse_args()
if __name__ == "__main__":
args = parse_args()
collect_faces(
args.label,
args.output_dir,
args.count,
args.camera_index,
args.delay,
use_dnn=args.use_dnn,
use_alignment=args.use_alignment,
)
```