From 96461d98abfc28e5548abb58ac8902f9d5c2c767 Mon Sep 17 00:00:00 2001 From: Jim McKeown Date: Tue, 18 Apr 2023 04:32:21 +0700 Subject: [PATCH 01/12] Example with image rendering functionality Example from modified fingerprint_simpletest.py adding image viewing and saving functionality using matplotlib and numpy. This has been tested on a Linux PC but should work under Windows or MacOS. --- examples/fingerprint_picturetest.py | 247 ++++++++++++++++++++++++++++ 1 file changed, 247 insertions(+) create mode 100644 examples/fingerprint_picturetest.py diff --git a/examples/fingerprint_picturetest.py b/examples/fingerprint_picturetest.py new file mode 100644 index 0000000..3c0bbd3 --- /dev/null +++ b/examples/fingerprint_picturetest.py @@ -0,0 +1,247 @@ +# SPDX-FileCopyrightText: 2021 ladyada for Adafruit Industries +# SPDX-License-Identifier: MIT + +import time +import board +import busio +from digitalio import DigitalInOut, Direction +import adafruit_fingerprint +import numpy as np +from matplotlib import pyplot as plt + + +#led = DigitalInOut(board.D13) +#led.direction = Direction.OUTPUT + +# This has not been tested: +#uart = busio.UART(board.TX, board.RX, baudrate=57600) + +# If using with a computer such as Linux/RaspberryPi, Mac, Windows with USB/serial converter: +import serial +uart = serial.Serial("/dev/ttyACM0", baudrate=57600, timeout=1) + +# If using with Linux/Raspberry Pi and hardware UART: +# import serial +# uart = serial.Serial("/dev/ttyS0", baudrate=57600, timeout=1) + +finger = adafruit_fingerprint.Adafruit_Fingerprint(uart) + +################################################## + + +def get_fingerprint(): + """Get a finger print image, template it, and see if it matches!""" + print("Waiting for image...") + while finger.get_image() != adafruit_fingerprint.OK: + pass + print("Templating...") + if finger.image_2_tz(1) != adafruit_fingerprint.OK: + return False + print("Searching...") + if finger.finger_search() != adafruit_fingerprint.OK: + return False + return True + + +# pylint: disable=too-many-branches +def get_fingerprint_detail(): + """Get a finger print image, template it, and see if it matches! + This time, print out each error instead of just returning on failure""" + print("Getting image...", end="") + i = finger.get_image() + if i == adafruit_fingerprint.OK: + print("Image taken") + else: + if i == adafruit_fingerprint.NOFINGER: + print("No finger detected") + elif i == adafruit_fingerprint.IMAGEFAIL: + print("Imaging error") + else: + print("Other error") + return False + + print("Templating...", end="") + i = finger.image_2_tz(1) + if i == adafruit_fingerprint.OK: + print("Templated") + else: + if i == adafruit_fingerprint.IMAGEMESS: + print("Image too messy") + elif i == adafruit_fingerprint.FEATUREFAIL: + print("Could not identify features") + elif i == adafruit_fingerprint.INVALIDIMAGE: + print("Image invalid") + else: + print("Other error") + return False + + print("Searching...", end="") + i = finger.finger_fast_search() + # pylint: disable=no-else-return + # This block needs to be refactored when it can be tested. + if i == adafruit_fingerprint.OK: + print("Found fingerprint!") + return True + else: + if i == adafruit_fingerprint.NOTFOUND: + print("No match found") + else: + print("Other error") + return False + +def get_fingerprint_photo(): + """Get and show fingerprint image""" + print("Waiting for image...") + while finger.get_image() != adafruit_fingerprint.OK: + pass + print("Got image...Transferring image data...") + imgList = finger.get_fpdata('image', 2) + imgArray = np.zeros(73728,np.uint8) + for i, val in enumerate(imgList): + imgArray[(i * 2)] = (val & 240) + imgArray[(i * 2) + 1] = (val & 15) * 16 + imgArray = np.reshape(imgArray, (288, 256)) + plt.title("Fingerprint Image") + plt.imshow(imgArray) + plt.show() + +def get_fingerprint_preview(): + """Get a finger print image, show it, template it, and see if it matches!""" + print("Waiting for image...") + while finger.get_image() != adafruit_fingerprint.OK: + pass + print("Got image...Transferring image data...") + imgList = finger.get_fpdata('image', 2) + imgArray = np.zeros(73728,np.uint8) + for i, val in enumerate(imgList): + imgArray[(i * 2)] = (val & 240) + imgArray[(i * 2) + 1] = (val & 15) * 16 + imgArray = np.reshape(imgArray, (288, 256)) + plt.title("Fingerprint Image") + plt.imshow(imgArray) + plt.show() + print("Templating...") + if finger.image_2_tz(1) != adafruit_fingerprint.OK: + return False + print("Searching...") + if finger.finger_search() != adafruit_fingerprint.OK: + return False + return True + +# pylint: disable=too-many-statements +def enroll_finger(location): + """Take a 2 finger images and template it, then store in 'location'""" + for fingerimg in range(1, 3): + if fingerimg == 1: + print("Place finger on sensor...", end="") + else: + print("Place same finger again...", end="") + + while True: + i = finger.get_image() + if i == adafruit_fingerprint.OK: + print("Image taken") + break + if i == adafruit_fingerprint.NOFINGER: + print(".", end="") + elif i == adafruit_fingerprint.IMAGEFAIL: + print("Imaging error") + return False + else: + print("Other error") + return False + + print("Templating...", end="") + i = finger.image_2_tz(fingerimg) + if i == adafruit_fingerprint.OK: + print("Templated") + else: + if i == adafruit_fingerprint.IMAGEMESS: + print("Image too messy") + elif i == adafruit_fingerprint.FEATUREFAIL: + print("Could not identify features") + elif i == adafruit_fingerprint.INVALIDIMAGE: + print("Image invalid") + else: + print("Other error") + return False + + if fingerimg == 1: + print("Remove finger") + time.sleep(1) + while i != adafruit_fingerprint.NOFINGER: + i = finger.get_image() + + print("Creating model...", end="") + i = finger.create_model() + if i == adafruit_fingerprint.OK: + print("Created") + else: + if i == adafruit_fingerprint.ENROLLMISMATCH: + print("Prints did not match") + else: + print("Other error") + return False + + print("Storing model #%d..." % location, end="") + i = finger.store_model(location) + if i == adafruit_fingerprint.OK: + print("Stored") + else: + if i == adafruit_fingerprint.BADLOCATION: + print("Bad storage location") + elif i == adafruit_fingerprint.FLASHERR: + print("Flash storage error") + else: + print("Other error") + return False + + return True + + +################################################## + + +def get_num(): + """Use input() to get a valid number from 1 to 127. Retry till success!""" + i = 0 + while (i > 127) or (i < 1): + try: + i = int(input("Enter ID # from 1-127: ")) + except ValueError: + pass + return i + + +while True: + print("----------------") + if finger.read_templates() != adafruit_fingerprint.OK: + raise RuntimeError("Failed to read templates") + print("Fingerprint templates:", finger.templates) + print("e) enroll print") + print("f) find print") + print("d) delete print") + print("v) view print") + print("p) preview and find print") + print("----------------") + c = input("> ") + + if c == "e": + enroll_finger(get_num()) + if c == "f": + if get_fingerprint(): + print("Detected #", finger.finger_id, "with confidence", finger.confidence) + else: + print("Finger not found") + if c == "d": + if finger.delete_model(get_num()) == adafruit_fingerprint.OK: + print("Deleted!") + else: + print("Failed to delete") + if c == "v": + get_fingerprint_photo() + if c == "p": + if get_fingerprint_preview(): + print("Detected #", finger.finger_id, "with confidence", finger.confidence) + else: + print("Finger not found") From 859b5ac5a957571d788790c9955a7431cd31d84b Mon Sep 17 00:00:00 2001 From: Jim McKeown Date: Fri, 28 Apr 2023 12:24:20 +0700 Subject: [PATCH 02/12] Update fingerprint_picturetest.py --- examples/fingerprint_picturetest.py | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/examples/fingerprint_picturetest.py b/examples/fingerprint_picturetest.py index 3c0bbd3..c2ebe1f 100644 --- a/examples/fingerprint_picturetest.py +++ b/examples/fingerprint_picturetest.py @@ -1,14 +1,16 @@ # SPDX-FileCopyrightText: 2021 ladyada for Adafruit Industries # SPDX-License-Identifier: MIT +# Added 'View Print' and 'Preview and Find Print' functions to +# example code fingerprint_simpletest.py + import time -import board -import busio -from digitalio import DigitalInOut, Direction -import adafruit_fingerprint +# import board +# import busio +# from digitalio import DigitalInOut, Direction import numpy as np from matplotlib import pyplot as plt - +import adafruit_fingerprint #led = DigitalInOut(board.D13) #led.direction = Direction.OUTPUT @@ -17,6 +19,7 @@ #uart = busio.UART(board.TX, board.RX, baudrate=57600) # If using with a computer such as Linux/RaspberryPi, Mac, Windows with USB/serial converter: +# Edit ttyACM0 to your USB/serial port import serial uart = serial.Serial("/dev/ttyACM0", baudrate=57600, timeout=1) @@ -103,7 +106,7 @@ def get_fingerprint_photo(): imgArray = np.reshape(imgArray, (288, 256)) plt.title("Fingerprint Image") plt.imshow(imgArray) - plt.show() + plt.show(block = False) def get_fingerprint_preview(): """Get a finger print image, show it, template it, and see if it matches!""" @@ -119,7 +122,7 @@ def get_fingerprint_preview(): imgArray = np.reshape(imgArray, (288, 256)) plt.title("Fingerprint Image") plt.imshow(imgArray) - plt.show() + plt.show(block = False) print("Templating...") if finger.image_2_tz(1) != adafruit_fingerprint.OK: return False From 55dd65e835a47cd0cad7ca13a3cf6b17c1bf3b1c Mon Sep 17 00:00:00 2001 From: Jim McKeown Date: Fri, 28 Apr 2023 12:41:47 +0700 Subject: [PATCH 03/12] fixed import order error Fixed import order error. pyplot changed to non-blocking to run properly from the command line. --- examples/fingerprint_picturetest.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/fingerprint_picturetest.py b/examples/fingerprint_picturetest.py index c2ebe1f..d10151e 100644 --- a/examples/fingerprint_picturetest.py +++ b/examples/fingerprint_picturetest.py @@ -10,6 +10,7 @@ # from digitalio import DigitalInOut, Direction import numpy as np from matplotlib import pyplot as plt +import serial import adafruit_fingerprint #led = DigitalInOut(board.D13) @@ -20,7 +21,6 @@ # If using with a computer such as Linux/RaspberryPi, Mac, Windows with USB/serial converter: # Edit ttyACM0 to your USB/serial port -import serial uart = serial.Serial("/dev/ttyACM0", baudrate=57600, timeout=1) # If using with Linux/Raspberry Pi and hardware UART: From 48fc1fc6483e14467a087e0bcd0a15a3e38346c5 Mon Sep 17 00:00:00 2001 From: Jim McKeown Date: Fri, 28 Apr 2023 13:06:23 +0700 Subject: [PATCH 04/12] black reformatted --- examples/fingerprint_picturetest.py | 34 ++++++++++++++++------------- 1 file changed, 19 insertions(+), 15 deletions(-) diff --git a/examples/fingerprint_picturetest.py b/examples/fingerprint_picturetest.py index d10151e..abb6dd9 100644 --- a/examples/fingerprint_picturetest.py +++ b/examples/fingerprint_picturetest.py @@ -1,10 +1,11 @@ # SPDX-FileCopyrightText: 2021 ladyada for Adafruit Industries # SPDX-License-Identifier: MIT -# Added 'View Print' and 'Preview and Find Print' functions to +# Added 'View Print' and 'Preview and Find Print' functions to # example code fingerprint_simpletest.py import time + # import board # import busio # from digitalio import DigitalInOut, Direction @@ -13,11 +14,11 @@ import serial import adafruit_fingerprint -#led = DigitalInOut(board.D13) -#led.direction = Direction.OUTPUT +# led = DigitalInOut(board.D13) +# led.direction = Direction.OUTPUT # This has not been tested: -#uart = busio.UART(board.TX, board.RX, baudrate=57600) +# uart = busio.UART(board.TX, board.RX, baudrate=57600) # If using with a computer such as Linux/RaspberryPi, Mac, Windows with USB/serial converter: # Edit ttyACM0 to your USB/serial port @@ -92,44 +93,47 @@ def get_fingerprint_detail(): print("Other error") return False + def get_fingerprint_photo(): """Get and show fingerprint image""" print("Waiting for image...") while finger.get_image() != adafruit_fingerprint.OK: pass print("Got image...Transferring image data...") - imgList = finger.get_fpdata('image', 2) - imgArray = np.zeros(73728,np.uint8) + imgList = finger.get_fpdata("image", 2) + imgArray = np.zeros(73728, np.uint8) for i, val in enumerate(imgList): - imgArray[(i * 2)] = (val & 240) + imgArray[(i * 2)] = val & 240 imgArray[(i * 2) + 1] = (val & 15) * 16 imgArray = np.reshape(imgArray, (288, 256)) plt.title("Fingerprint Image") plt.imshow(imgArray) - plt.show(block = False) - + plt.show(block=False) + + def get_fingerprint_preview(): """Get a finger print image, show it, template it, and see if it matches!""" print("Waiting for image...") while finger.get_image() != adafruit_fingerprint.OK: pass print("Got image...Transferring image data...") - imgList = finger.get_fpdata('image', 2) - imgArray = np.zeros(73728,np.uint8) + imgList = finger.get_fpdata("image", 2) + imgArray = np.zeros(73728, np.uint8) for i, val in enumerate(imgList): - imgArray[(i * 2)] = (val & 240) + imgArray[(i * 2)] = val & 240 imgArray[(i * 2) + 1] = (val & 15) * 16 imgArray = np.reshape(imgArray, (288, 256)) plt.title("Fingerprint Image") plt.imshow(imgArray) - plt.show(block = False) + plt.show(block=False) print("Templating...") if finger.image_2_tz(1) != adafruit_fingerprint.OK: return False print("Searching...") if finger.finger_search() != adafruit_fingerprint.OK: return False - return True + return True + # pylint: disable=too-many-statements def enroll_finger(location): @@ -247,4 +251,4 @@ def get_num(): if get_fingerprint_preview(): print("Detected #", finger.finger_id, "with confidence", finger.confidence) else: - print("Finger not found") + print("Finger not found") From bdb112828d018efb21d28317c4630e579601755f Mon Sep 17 00:00:00 2001 From: Jim McKeown Date: Sat, 29 Apr 2023 07:23:27 +0700 Subject: [PATCH 05/12] Update fingerprint_picturetest.py --- examples/fingerprint_picturetest.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/examples/fingerprint_picturetest.py b/examples/fingerprint_picturetest.py index abb6dd9..96f8d64 100644 --- a/examples/fingerprint_picturetest.py +++ b/examples/fingerprint_picturetest.py @@ -1,8 +1,7 @@ -# SPDX-FileCopyrightText: 2021 ladyada for Adafruit Industries +# SPDX-FileCopyrightText: 2023 Jim McKeown # SPDX-License-Identifier: MIT -# Added 'View Print' and 'Preview and Find Print' functions to -# example code fingerprint_simpletest.py +"""Added 'View Print' and 'Preview and Find Print' to fingerprint_simpletest.py""" import time From c6996ed8e933bb3255cbba5ed50cbb221ff420ba Mon Sep 17 00:00:00 2001 From: Jim McKeown Date: Sat, 29 Apr 2023 08:15:19 +0700 Subject: [PATCH 06/12] Update optional_requirements.txt --- optional_requirements.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/optional_requirements.txt b/optional_requirements.txt index d4e27c4..78fd9ca 100644 --- a/optional_requirements.txt +++ b/optional_requirements.txt @@ -1,3 +1,7 @@ # SPDX-FileCopyrightText: 2022 Alec Delaney, for Adafruit Industries # # SPDX-License-Identifier: Unlicense + +numpy +pyplot from matplotlib +serial From b76f8d6c05235527b9a5a7b84eee5e3af60ac094 Mon Sep 17 00:00:00 2001 From: Jim McKeown Date: Sat, 29 Apr 2023 08:19:56 +0700 Subject: [PATCH 07/12] Update optional_requirements.txt --- optional_requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/optional_requirements.txt b/optional_requirements.txt index 78fd9ca..a8b48bb 100644 --- a/optional_requirements.txt +++ b/optional_requirements.txt @@ -3,5 +3,5 @@ # SPDX-License-Identifier: Unlicense numpy -pyplot from matplotlib +matplotlib serial From 6d0d17bae7bd56813f9ba248c0b3dc74171c3112 Mon Sep 17 00:00:00 2001 From: Jim McKeown Date: Sat, 29 Apr 2023 08:41:50 +0700 Subject: [PATCH 08/12] Update fingerprint_picturetest.py --- examples/fingerprint_picturetest.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/fingerprint_picturetest.py b/examples/fingerprint_picturetest.py index 96f8d64..6639618 100644 --- a/examples/fingerprint_picturetest.py +++ b/examples/fingerprint_picturetest.py @@ -2,7 +2,7 @@ # SPDX-License-Identifier: MIT """Added 'View Print' and 'Preview and Find Print' to fingerprint_simpletest.py""" - +"""This example only works on single board computers with the use of Blinka""" import time # import board From a13159e0a848b416d879e016064d7108ef63b353 Mon Sep 17 00:00:00 2001 From: Jim McKeown Date: Sat, 29 Apr 2023 08:47:17 +0700 Subject: [PATCH 09/12] Update fingerprint_picturetest.py --- examples/fingerprint_picturetest.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/fingerprint_picturetest.py b/examples/fingerprint_picturetest.py index 6639618..de02609 100644 --- a/examples/fingerprint_picturetest.py +++ b/examples/fingerprint_picturetest.py @@ -1,10 +1,7 @@ # SPDX-FileCopyrightText: 2023 Jim McKeown # SPDX-License-Identifier: MIT -"""Added 'View Print' and 'Preview and Find Print' to fingerprint_simpletest.py""" -"""This example only works on single board computers with the use of Blinka""" import time - # import board # import busio # from digitalio import DigitalInOut, Direction @@ -13,6 +10,9 @@ import serial import adafruit_fingerprint +"""Added 'View Print' and 'Preview and Find Print' to fingerprint_simpletest.py""" +"""This example only works on single board computers with the use of Blinka""" + # led = DigitalInOut(board.D13) # led.direction = Direction.OUTPUT From 11c5754502a5c98f7dbe8ef81e250c126b79abb6 Mon Sep 17 00:00:00 2001 From: Jim McKeown Date: Sat, 29 Apr 2023 09:06:01 +0700 Subject: [PATCH 10/12] Update fingerprint_picturetest.py --- examples/fingerprint_picturetest.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/examples/fingerprint_picturetest.py b/examples/fingerprint_picturetest.py index de02609..fb17b2d 100644 --- a/examples/fingerprint_picturetest.py +++ b/examples/fingerprint_picturetest.py @@ -2,9 +2,6 @@ # SPDX-License-Identifier: MIT import time -# import board -# import busio -# from digitalio import DigitalInOut, Direction import numpy as np from matplotlib import pyplot as plt import serial From 601fd8a8b6c111e6c67c6babbd5defb9294a7445 Mon Sep 17 00:00:00 2001 From: Jim McKeown Date: Thu, 4 May 2023 16:18:01 +0700 Subject: [PATCH 11/12] Update optional_requirements.txt --- optional_requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/optional_requirements.txt b/optional_requirements.txt index a8b48bb..7efc06e 100644 --- a/optional_requirements.txt +++ b/optional_requirements.txt @@ -4,4 +4,4 @@ numpy matplotlib -serial +pyserial From b881b1338c471df68f0959f6aaf22200461fcfaa Mon Sep 17 00:00:00 2001 From: Jim McKeown Date: Thu, 4 May 2023 16:45:25 +0700 Subject: [PATCH 12/12] Update fingerprint_picturetest.py --- examples/fingerprint_picturetest.py | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/examples/fingerprint_picturetest.py b/examples/fingerprint_picturetest.py index fb17b2d..c733c79 100644 --- a/examples/fingerprint_picturetest.py +++ b/examples/fingerprint_picturetest.py @@ -1,15 +1,28 @@ # SPDX-FileCopyrightText: 2023 Jim McKeown # SPDX-License-Identifier: MIT +""" +This example shows the basic functionality to: +Show the devices fingerprint slots that have fingerprints enrolled. +Enroll a fingerprint in an existing or new fingerprint slot. +Try to find a fingerprint in the existing list of enrolled fingerprints. +Delete an enrolled fingerprint. +View the image of a fingerprint. +Preview the image of a fingerprint and then try to find the fingerprint +in the existing list of enrolled fingerprints. + +Please note that this example only works on single board computers +with the use of Blinka. + +This example is based on fingerprint_simpletest.py +""" + import time import numpy as np from matplotlib import pyplot as plt import serial import adafruit_fingerprint -"""Added 'View Print' and 'Preview and Find Print' to fingerprint_simpletest.py""" -"""This example only works on single board computers with the use of Blinka""" - # led = DigitalInOut(board.D13) # led.direction = Direction.OUTPUT