提交 b8a80373 编写于 作者: A Adam Geitgey

Add tolerance parameter to CLI

上级 f2163140
......@@ -130,6 +130,20 @@ with the filename and the name of the person found.
An `unknown_person` is a face in the image that didn't match anyone in
your folder of known people.
If you are getting multiple matches for the same person, it might be that
the people in your photos look very similar and a lower tolerance value
is needed to make face comparisons more strict.
You can do that with the `--tolerance` parameter. The default tolerance
value is 0.6 and lower numbers make face comparisons more strict:
```bash
$ face_recognition --tolerance 0.54 ./pictures_of_people_i_know/ ./unknown_pictures/
/unknown_pictures/unknown.jpg,Barack Obama
/face_recognition_test/unknown_pictures/unknown.jpg,unknown_person
```
If you simply want to know the names of the people in each photograph but don't
care about file names, you could do this:
......
......@@ -32,7 +32,7 @@ def scan_known_people(known_people_folder):
return known_names, known_face_encodings
def test_image(image_to_check, known_names, known_face_encodings):
def test_image(image_to_check, known_names, known_face_encodings, tolerance=0.6):
unknown_image = face_recognition.load_image_file(image_to_check)
# Scale down image if it's giant so things run a little faster
......@@ -45,7 +45,7 @@ def test_image(image_to_check, known_names, known_face_encodings):
unknown_encodings = face_recognition.face_encodings(unknown_image)
for unknown_encoding in unknown_encodings:
result = face_recognition.compare_faces(known_face_encodings, unknown_encoding)
result = face_recognition.compare_faces(known_face_encodings, unknown_encoding, tolerance=tolerance)
if True in result:
[print("{},{}".format(image_to_check, name)) for is_match, name in zip(result, known_names) if is_match]
......@@ -57,7 +57,7 @@ def image_files_in_folder(folder):
return [os.path.join(folder, f) for f in os.listdir(folder) if re.match(r'.*\.(jpg|jpeg|png)', f, flags=re.I)]
def process_images_in_process_pool(images_to_check, known_names, known_face_encodings, number_of_cpus):
def process_images_in_process_pool(images_to_check, known_names, known_face_encodings, number_of_cpus, tolerance):
if number_of_cpus == -1:
processes = None
else:
......@@ -69,7 +69,7 @@ def process_images_in_process_pool(images_to_check, known_names, known_face_enco
context = multiprocessing.get_context("forkserver")
pool = context.Pool(processes=processes)
function_parameters = zip(images_to_check, itertools.repeat(known_names), itertools.repeat(known_face_encodings))
function_parameters = zip(images_to_check, itertools.repeat(known_names), itertools.repeat(known_face_encodings), itertools.repeat(tolerance))
pool.starmap(test_image, function_parameters)
......@@ -78,7 +78,8 @@ def process_images_in_process_pool(images_to_check, known_names, known_face_enco
@click.argument('known_people_folder')
@click.argument('image_to_check')
@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"')
def main(known_people_folder, image_to_check, cpus):
@click.option('--tolerance', default=0.6, help='Tolerance to use for face comparisons. Default is 0.6 and lower is more strict matching. Lower this if you get multiple matches for the same person. Try 0.54 for example.')
def main(known_people_folder, image_to_check, cpus, tolerance):
known_names, known_face_encodings = scan_known_people(known_people_folder)
# Multi-core processing only supported on Python 3.4 or greater
......@@ -88,9 +89,9 @@ def main(known_people_folder, image_to_check, cpus):
if os.path.isdir(image_to_check):
if cpus == 1:
[test_image(image_file, known_names, known_face_encodings) for image_file in image_files_in_folder(image_to_check)]
[test_image(image_file, known_names, known_face_encodings, tolerance) for image_file in image_files_in_folder(image_to_check)]
else:
process_images_in_process_pool(image_files_in_folder(image_to_check), known_names, known_face_encodings, cpus)
process_images_in_process_pool(image_files_in_folder(image_to_check), known_names, known_face_encodings, cpus, tolerance)
else:
test_image(image_to_check, known_names, known_face_encodings)
......
......@@ -183,7 +183,7 @@ class Test_face_recognition(unittest.TestCase):
self.assertListEqual(match_results, [])
def test_command_line_interface_options(self):
target_string = '--help Show this message and exit.'
target_string = '--help Show this message and exit.'
runner = CliRunner()
help_result = runner.invoke(cli.main, ['--help'])
self.assertEqual(help_result.exit_code, 0)
......@@ -195,7 +195,18 @@ class Test_face_recognition(unittest.TestCase):
image_folder = os.path.join(os.path.dirname(__file__), 'test_images')
image_file = os.path.join(os.path.dirname(__file__), 'test_images', 'obama.jpg')
help_result = runner.invoke(cli.main, args=[image_folder, image_file])
result = runner.invoke(cli.main, args=[image_folder, image_file])
self.assertEqual(help_result.exit_code, 0)
self.assertTrue(target_string in help_result.output)
self.assertEqual(result.exit_code, 0)
self.assertTrue(target_string in result.output)
def test_command_line_interface_tolerance(self):
target_string = 'obama.jpg,obama'
runner = CliRunner()
image_folder = os.path.join(os.path.dirname(__file__), 'test_images')
image_file = os.path.join(os.path.dirname(__file__), 'test_images', 'obama.jpg')
result = runner.invoke(cli.main, args=[image_folder, image_file, "--tolerance", "0.55"])
self.assertEqual(result.exit_code, 0)
self.assertTrue(target_string in result.output)
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册