-
Notifications
You must be signed in to change notification settings - Fork 53
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #55 from itsFDavid/compare_with_file
add program to compare template with fingerprint folfer
- Loading branch information
Showing
1 changed file
with
273 additions
and
0 deletions.
There are no files selected for viewing
273 changes: 273 additions & 0 deletions
273
examples/fingerprint_template_folder_compare_with_file_rpi.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,273 @@ | ||
# SPDX-FileCopyrightText: 2024 itsFDavid | ||
# SPDX-License-Identifier: MIT | ||
""" | ||
`fingerprint_template_folder_compare_with_file.py` | ||
==================================================== | ||
This is an example program to demo storing fingerprint templates in a folder. It also allows | ||
comparing a newly obtained print with one stored in the folder in the previous step. This is helpful | ||
when fingerprint templates are stored centrally (not on sensor's flash memory) and shared | ||
between multiple sensors. | ||
* Author(s): itsFDavid | ||
Implementation Notes | ||
-------------------- | ||
This program was used on other fingerprint sensors, | ||
and everything worked as expected, including testing with Raspberry Pi Zero 2W. | ||
To run the program: | ||
1. Connect the fingerprint sensor to your Raspberry Pi. | ||
2. Install required libraries. | ||
3. Execute the script using Python. | ||
""" | ||
|
||
import os | ||
import time | ||
|
||
import serial | ||
from PIL import Image | ||
import adafruit_fingerprint | ||
|
||
# If using with a computer such as Linux/RaspberryPi, Mac, Windows with USB/serial converter: | ||
# uart = serial.Serial("COM6", baudrate=57600, timeout=1) | ||
|
||
# If using with Linux/Raspberry Pi and hardware UART: | ||
uart = serial.Serial("/dev/ttyUSB0", baudrate=57600, timeout=1) | ||
|
||
finger = adafruit_fingerprint.Adafruit_Fingerprint(uart) | ||
|
||
# Folder where fingerprint templates are stored | ||
FINGERPRINT_FOLDER = "fingerprint/" | ||
|
||
|
||
# Enroll and verification functions | ||
def get_num(max_num): | ||
"""Prompts the user to enter a valid template number within the available range.""" | ||
while True: | ||
try: | ||
num = int(input(f"Enter a template number (0-{max_num}): ")) | ||
if 0 <= num <= max_num: | ||
return num | ||
print(f"Please enter a number between 0 and {max_num}.") | ||
except ValueError: | ||
print("Invalid input. Please enter a valid number.") | ||
|
||
|
||
def get_fingerprint(): | ||
"""Get an image from the fingerprint sensor for search, process for a match.""" | ||
print("Waiting for finger...") | ||
while finger.get_image() != adafruit_fingerprint.OK: | ||
pass | ||
print("Processing image...") | ||
if finger.image_2_tz(1) != adafruit_fingerprint.OK: | ||
print("Error processing image.") | ||
return False | ||
print("Searching for matches...") | ||
return finger.finger_search() == adafruit_fingerprint.OK | ||
|
||
|
||
def enroll_finger(location): | ||
"""Enroll a fingerprint and store it in the specified location.""" | ||
for fingerimg in range(1, 3): | ||
action = "Place finger on sensor" if fingerimg == 1 else "Same finger again" | ||
print(action, end="") | ||
while True: | ||
if finger.get_image() == adafruit_fingerprint.OK: | ||
print("Image captured") | ||
break | ||
print(".", end="") | ||
print("Processing image...", end="") | ||
if finger.image_2_tz(fingerimg) != adafruit_fingerprint.OK: | ||
print("Error processing image.") | ||
return False | ||
if fingerimg == 1: | ||
print("Remove finger") | ||
time.sleep(1) | ||
while finger.get_image() != adafruit_fingerprint.NOFINGER: | ||
pass | ||
print("Creating model...", end="") | ||
if finger.create_model() != adafruit_fingerprint.OK: | ||
print("Error creating model.") | ||
return False | ||
print(f"Storing model in location #{location}...", end="") | ||
if finger.store_model(location) != adafruit_fingerprint.OK: | ||
print("Error storing model.") | ||
return False | ||
print("Model stored.") | ||
return True | ||
|
||
|
||
def save_fingerprint_image(filename): | ||
"""Capture a fingerprint and save the image to a file.""" | ||
print("Waiting for finger...") | ||
while finger.get_image() != adafruit_fingerprint.OK: | ||
pass | ||
img = Image.new("L", (256, 288), "white") | ||
pixeldata = img.load() | ||
mask = 0b00001111 | ||
result = finger.get_fpdata(sensorbuffer="image") | ||
coor_x, coor_y = 0, 0 | ||
for i, value in enumerate(result): | ||
if i % 100 == 0: | ||
print("", end="") | ||
pixeldata[coor_x, coor_y] = (int(value) >> 4) * 17 | ||
coor_x += 1 | ||
pixeldata[coor_x, coor_y] = (int(value) & mask) * 17 | ||
if coor_x == 255: | ||
coor_x = 0 | ||
coor_y += 1 | ||
else: | ||
coor_x += 1 | ||
img.save(filename) | ||
print(f"\nImage saved to {filename}") | ||
return True | ||
|
||
|
||
def enroll_save_to_file(): | ||
"""Capture a fingerprint, create a model, and save it to a file.""" | ||
for fingerimg in range(1, 3): | ||
action = "Place finger on sensor" if fingerimg == 1 else "Same finger again" | ||
print(action, end="") | ||
while True: | ||
if finger.get_image() == adafruit_fingerprint.OK: | ||
print("Image captured") | ||
break | ||
print(".", end="") | ||
print("Processing image...", end="") | ||
if finger.image_2_tz(fingerimg) != adafruit_fingerprint.OK: | ||
print("Error processing image.") | ||
return False | ||
if fingerimg == 1: | ||
print("Remove finger") | ||
while finger.get_image() != adafruit_fingerprint.NOFINGER: | ||
pass | ||
print("Creating model...", end="") | ||
if finger.create_model() != adafruit_fingerprint.OK: | ||
print("Error creating model.") | ||
return False | ||
print("Storing template...") | ||
data = finger.get_fpdata("char", 1) | ||
filename = os.path.join(FINGERPRINT_FOLDER, f"template_{int(time.time())}.dat") | ||
with open(filename, "wb") as file: | ||
file.write(bytearray(data)) | ||
print(f"Template saved to {filename}") | ||
return True | ||
|
||
|
||
def fingerprint_check_folder(): | ||
"""Compare a fingerprint with all files in the fingerprint folder.""" | ||
print("Waiting for fingerprint...") | ||
while finger.get_image() != adafruit_fingerprint.OK: | ||
pass | ||
print("Processing image...") | ||
if finger.image_2_tz(1) != adafruit_fingerprint.OK: | ||
print("Error processing image.") | ||
return False | ||
print("Searching for matches in the template folder...", end="") | ||
found_match = False | ||
matched_filename = None | ||
for filename in os.listdir(FINGERPRINT_FOLDER): | ||
if filename.endswith(".dat"): | ||
file_path = os.path.join(FINGERPRINT_FOLDER, filename) | ||
with open(file_path, "rb") as file: | ||
data = file.read() | ||
finger.send_fpdata(list(data), "char", 2) | ||
if finger.compare_templates() == adafruit_fingerprint.OK: | ||
matched_filename = filename | ||
found_match = True | ||
break | ||
if found_match: | ||
print(f"Fingerprint matches the template in the file {matched_filename}!") | ||
else: | ||
print("No match found.") | ||
return found_match | ||
|
||
|
||
def main(): | ||
"""Main function to run the fingerprint enrollment and verification program. | ||
This function provides a menu for the user to enroll fingerprints, search for | ||
fingerprints, delete templates, save fingerprint images, and reset the fingerprint library. | ||
It interacts with the user via the console and performs the necessary actions based on | ||
user input. | ||
""" | ||
while True: | ||
print("----------------") | ||
if finger.read_templates() != adafruit_fingerprint.OK: | ||
raise RuntimeError("Could not read templates.") | ||
print("Stored fingerprint templates: ", finger.templates) | ||
|
||
if finger.count_templates() != adafruit_fingerprint.OK: | ||
raise RuntimeError("Could not count templates.") | ||
print("Number of templates found: ", finger.template_count) | ||
|
||
if finger.read_sysparam() != adafruit_fingerprint.OK: | ||
raise RuntimeError("Could not retrieve system parameters.") | ||
print("Template library size: ", finger.library_size) | ||
print("Options:") | ||
print("e) Enroll fingerprint") | ||
print("f) Search fingerprint") | ||
print("d) Delete fingerprint") | ||
print("s) Save fingerprint image") | ||
print("cf) Compare template with file") | ||
print("esf) Enroll and save to file") | ||
print("r) Reset library") | ||
print("q) Exit") | ||
print("----------------") | ||
user_choice = input("> ") | ||
match user_choice.lower(): | ||
case "e": | ||
enroll_finger(get_num(finger.library_size)) | ||
case "f": | ||
print_fingerprint() | ||
case "d": | ||
delete_fingerprint() | ||
case "s": | ||
save_fingerprint_image(f"fingerprint_{int(time.time())}.png") | ||
case "cf": | ||
fingerprint_check_folder() | ||
case "esf": | ||
enroll_save_to_file() | ||
case "r": | ||
reset_library() | ||
case "q": | ||
exit_program() | ||
case _: | ||
print("Invalid option.") | ||
|
||
|
||
def print_fingerprint(): | ||
"""Prints the fingerprint detection result.""" | ||
if get_fingerprint(): | ||
output_finger_detected = f"Fingerprint detected with ID #{finger.finger_id}" | ||
output_finger_confidence = f"Confidence: {finger.confidence}" | ||
print(output_finger_detected) | ||
print(output_finger_confidence) | ||
else: | ||
print("Fingerprint not found.") | ||
|
||
|
||
def delete_fingerprint(): | ||
"""Deletes a fingerprint model based on user input.""" | ||
if finger.delete_model(get_num(finger.library_size)) == adafruit_fingerprint.OK: | ||
print("Deleted successfully!") | ||
else: | ||
print("Failed to delete.") | ||
|
||
|
||
def reset_library(): | ||
"""Resets the fingerprint library.""" | ||
if finger.empty_library() == adafruit_fingerprint.OK: | ||
print("Library reset.") | ||
else: | ||
print("Failed to reset library.") | ||
|
||
|
||
def exit_program(): | ||
"""Exits the program.""" | ||
print("Exiting...") | ||
raise SystemExit | ||
|
||
|
||
if __name__ == "__main__": | ||
main() |