diff --git a/TODO b/TODO index 07f0019..66723a7 100644 --- a/TODO +++ b/TODO @@ -1,6 +1,5 @@ LIBRARY ======= -identification test suite against NFIQ compliance set make library optionally asynchronous and maybe thread-safe nbis cleanups diff --git a/libfprint/core.c b/libfprint/core.c index 7db625a..fc78922 100644 --- a/libfprint/core.c +++ b/libfprint/core.c @@ -81,10 +81,6 @@ * * \section identification Identification * - * libfprint supports enrollment and verification as described above. Although - * libfprint does not yet support identification (it is planned), it is worth - * introducing the concept to give you a complete picture. - * * Identification is the process of comparing a freshly scanned fingerprint * to a collection of previously enrolled fingerprints. For example, * imagine there are 100 people in an organisation, and they all have enrolled diff --git a/libfprint/fp_internal.h b/libfprint/fp_internal.h index 7581c38..e182a58 100644 --- a/libfprint/fp_internal.h +++ b/libfprint/fp_internal.h @@ -225,6 +225,8 @@ int fpi_img_to_print_data(struct fp_img_dev *imgdev, struct fp_img *img, struct fp_print_data **ret); int fpi_img_compare_print_data(struct fp_print_data *enrolled_print, struct fp_print_data *new_print); +int fpi_img_compare_print_data_to_gallery(struct fp_print_data *print, + struct fp_print_data **gallery, int match_threshold, int *match_offset); #endif diff --git a/libfprint/img.c b/libfprint/img.c index c8df4b2..80fd6e4 100644 --- a/libfprint/img.c +++ b/libfprint/img.c @@ -364,6 +364,25 @@ int fpi_img_compare_print_data(struct fp_print_data *enrolled_print, return r; } +int fpi_img_compare_print_data_to_gallery(struct fp_print_data *print, + struct fp_print_data **gallery, int match_threshold, int *match_offset) +{ + struct xyt_struct *pstruct = (struct xyt_struct *) print->data; + struct fp_print_data *gallery_print; + int probe_len = bozorth_probe_init(pstruct); + size_t i = 0; + + while (gallery_print = gallery[i++]) { + struct xyt_struct *gstruct = (struct xyt_struct *) gallery_print->data; + int r = bozorth_to_gallery(probe_len, pstruct, gstruct); + if (r >= match_threshold) { + *match_offset = i - 1; + return FP_VERIFY_MATCH; + } + } + return FP_VERIFY_NO_MATCH; +} + /** \ingroup img * Get a binarized form of a standardized scanned image. This is where the * fingerprint image has been "enhanced" and is a set of pure black ridges diff --git a/libfprint/imgdev.c b/libfprint/imgdev.c index 8ba6bb8..8deb23c 100644 --- a/libfprint/imgdev.c +++ b/libfprint/imgdev.c @@ -305,6 +305,46 @@ static int img_dev_verify(struct fp_dev *dev, return FP_VERIFY_NO_MATCH; } +static int img_dev_identify(struct fp_dev *dev, + struct fp_print_data **print_gallery, size_t *match_offset, + struct fp_img **_img) +{ + struct fp_img_dev *imgdev = dev->priv; + struct fp_img_driver *imgdrv = fpi_driver_to_img_driver(dev->drv); + struct fp_img *img = NULL; + struct fp_print_data *print; + int match_score = imgdrv->bz3_threshold; + int r; + + r = fpi_imgdev_capture(imgdev, 0, &img); + + /* If we got an image, standardize it and return it even if the scan + * quality was too low for processing. */ + if (img) + fp_img_standardize(img); + if (_img) + *_img = img; + if (r) + return r; + + r = fpi_img_to_print_data(imgdev, img, &print); + if (r < 0) + return r; + if (img->minutiae->num < MIN_ACCEPTABLE_MINUTIAE) { + fp_dbg("not enough minutiae, %d/%d", r, MIN_ACCEPTABLE_MINUTIAE); + fp_print_data_free(print); + return FP_VERIFY_RETRY; + } + + if (match_score == 0) + match_score = BOZORTH3_DEFAULT_THRESHOLD; + + r = fpi_img_compare_print_data_to_gallery(print, print_gallery, + match_score, match_offset); + fp_print_data_free(print); + return r; +} + void fpi_img_driver_setup(struct fp_img_driver *idriver) { idriver->driver.type = DRIVER_IMAGING; @@ -312,5 +352,6 @@ void fpi_img_driver_setup(struct fp_img_driver *idriver) idriver->driver.exit = img_dev_exit; idriver->driver.enroll = img_dev_enroll; idriver->driver.verify = img_dev_verify; + idriver->driver.identify = img_dev_identify; }