Skip to content

Commit 245160c

Browse files
committed
All support for parallel processing in the CLI
1 parent 0e68c52 commit 245160c

File tree

2 files changed

+43
-3
lines changed

2 files changed

+43
-3
lines changed

README.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,18 @@ Barack Obama
140140
unknown_person
141141
```
142142

143+
Face recognition can also be done in parallel if you have a computer with
144+
multiple CPU cores. For example if your system has 4 CPU cores, you can
145+
process about 4 times as many images in the same amount of time by using
146+
all your CPU cores in parallel.
147+
148+
If you are using Python 3.4 or newer, pass in a `--cpus <number_of_cpu_cores_to_use>` parameter:
149+
150+
```bash
151+
$ face_recognition -cpus 4 ./pictures_of_people_i_know/ ./unknown_pictures/
152+
```
153+
154+
You can also pass in `--cpus -1` to use all CPU cores in your system.
143155

144156
#### Python Module
145157

face_recognition/cli.py

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,9 @@
66
import scipy.misc
77
import warnings
88
import face_recognition.api as face_recognition
9-
9+
import multiprocessing
10+
import itertools
11+
import sys
1012

1113
def scan_known_people(known_people_folder):
1214
known_names = []
@@ -54,14 +56,40 @@ def image_files_in_folder(folder):
5456
return [os.path.join(folder, f) for f in os.listdir(folder) if re.match(r'.*\.(jpg|jpeg|png)', f, flags=re.I)]
5557

5658

59+
def process_images_in_process_pool(images_to_check, known_names, known_face_encodings, number_of_cpus):
60+
if number_of_cpus == -1:
61+
processes = None
62+
else:
63+
processes = number_of_cpus
64+
65+
# macOS will crash due to a bug in libdispatch if you don't use 'forkserver'
66+
context = multiprocessing
67+
if "forkserver" in multiprocessing.get_all_start_methods():
68+
context = multiprocessing.get_context("forkserver")
69+
70+
pool = context.Pool(processes=processes)
71+
function_parameters = zip(images_to_check, itertools.repeat(known_names), itertools.repeat(known_face_encodings))
72+
73+
pool.starmap(test_image, function_parameters)
74+
75+
5776
@click.command()
5877
@click.argument('known_people_folder')
5978
@click.argument('image_to_check')
60-
def main(known_people_folder, image_to_check):
79+
@click.option('--cpus', default=1, help='number of CPU cores to use in parallel (can speed up processing lots of images). -1 means "use all in system"')
80+
def main(known_people_folder, image_to_check, cpus):
6181
known_names, known_face_encodings = scan_known_people(known_people_folder)
6282

83+
# Multi-core processing only supported on Python 3.4 or greater
84+
if (sys.version_info < (3, 4)) and cpus != 1:
85+
click.echo("WARNING: Multi-processing support requires Python 3.4 or greater. Falling back to single-threaded processing!")
86+
cpus = 1
87+
6388
if os.path.isdir(image_to_check):
64-
[test_image(image_file, known_names, known_face_encodings) for image_file in image_files_in_folder(image_to_check)]
89+
if cpus == 1:
90+
[test_image(image_file, known_names, known_face_encodings) for image_file in image_files_in_folder(image_to_check)]
91+
else:
92+
process_images_in_process_pool(image_files_in_folder(image_to_check), known_names, known_face_encodings, cpus)
6593
else:
6694
test_image(image_to_check, known_names, known_face_encodings)
6795

0 commit comments

Comments
 (0)