Commit 41b25f28 authored by Daniel Drake's avatar Daniel Drake

Add mindtct from NBIS; implement enroll for image devices

mindtct is mostly as-is for now, with just a couple of bits ripped out.
parent be67f85c
......@@ -6,14 +6,46 @@ AES4000_SRC = drivers/aes4000.c
DRIVER_SRC = $(UPEKTS_SRC) $(URU4000_SRC) $(AES4000_SRC)
libfprint_la_CFLAGS = -fvisibility=hidden $(LIBUSB_CFLAGS) $(GLIB_CFLAGS) $(AM_CFLAGS)
NBIS_SRC = \
nbis/mindtct/binar.c \
nbis/mindtct/block.c \
nbis/mindtct/chaincod.c \
nbis/mindtct/contour.c \
nbis/mindtct/detect.c \
nbis/mindtct/dft.c \
nbis/mindtct/free.c \
nbis/mindtct/getmin.c \
nbis/mindtct/globals.c \
nbis/mindtct/imgutil.c \
nbis/mindtct/init.c \
nbis/mindtct/isempty.c \
nbis/mindtct/line.c \
nbis/mindtct/link.c \
nbis/mindtct/log.c \
nbis/mindtct/loop.c \
nbis/mindtct/maps.c \
nbis/mindtct/matchpat.c \
nbis/mindtct/minutia.c \
nbis/mindtct/morph.c \
nbis/mindtct/mytime.c \
nbis/mindtct/quality.c \
nbis/mindtct/remove.c \
nbis/mindtct/results.c \
nbis/mindtct/ridges.c \
nbis/mindtct/shape.c \
nbis/mindtct/sort.c \
nbis/mindtct/util.c \
nbis/mindtct/xytreps.c
libfprint_la_CFLAGS = -fvisibility=hidden -Inbis/include $(LIBUSB_CFLAGS) $(GLIB_CFLAGS) $(AM_CFLAGS)
libfprint_la_LDFLAGS = -version-info @lt_major@:@lt_revision@:@lt_age@
libfprint_la_LIBADD = $(LIBUSB_LIBS) $(GLIB_LIBS)
libfprint_la_LIBADD = -lm $(LIBUSB_LIBS) $(GLIB_LIBS)
libfprint_la_SOURCES = \
core.c \
data.c \
img.c \
imgdev.c \
$(DRIVER_SRC)
$(DRIVER_SRC) \
$(NBIS_SRC)
......@@ -178,6 +178,8 @@ struct fp_img *fpi_img_new(size_t length);
struct fp_img *fpi_img_new_for_imgdev(struct fp_img_dev *dev);
struct fp_img *fpi_img_resize(struct fp_img *img, size_t newsize);
gboolean fpi_img_is_sane(struct fp_img *img);
int fpi_img_detect_minutiae(struct fp_img_dev *imgdev, struct fp_img *img,
struct fp_print_data **ret);
#define bswap16(x) (((x & 0xff) << 8) | (x >> 8))
#if __BYTE_ORDER == __LITTLE_ENDIAN
......
......@@ -25,6 +25,8 @@
#include <glib.h>
#include "fp_internal.h"
#include "nbis/include/bozorth.h"
#include "nbis/include/lfs.h"
struct fp_img *fpi_img_new(size_t length)
{
......@@ -172,3 +174,106 @@ API_EXPORTED void fp_img_standardize(struct fp_img *img)
img->flags &= ~FP_IMG_COLORS_INVERTED;
}
}
static int sort_x_y(const void *a, const void *b)
{
struct minutiae_struct *af = (struct minutiae_struct *) a;
struct minutiae_struct *bf = (struct minutiae_struct *) b;
if (af->col[0] < bf->col[0])
return -1;
if (af->col[0] > bf->col[0])
return 1;
if (af->col[1] < bf->col[1])
return -1;
if (af->col[1] > bf->col[1])
return 1;
return 0;
}
/* Based on write_minutiae_XYTQ and bz_load */
static void minutiae_to_xyt(MINUTIAE *minutiae, int bwidth,
int bheight, unsigned char *buf)
{
int i;
MINUTIA *minutia;
struct minutiae_struct c[MAX_FILE_MINUTIAE];
struct xyt_struct *xyt = (struct xyt_struct *) buf;
/* FIXME: only considers first 150 minutiae (MAX_FILE_MINUTIAE) */
/* nist does weird stuff with 150 vs 1000 limits */
int nmin = min(minutiae->num, MAX_FILE_MINUTIAE);
for (i = 0; i < nmin; i++){
minutia = minutiae->list[i];
lfs2nist_minutia_XYT(&c[i].col[0], &c[i].col[1], &c[i].col[2],
minutia, bwidth, bheight);
c[i].col[3] = sround(minutia->reliability * 100.0);
if (c[i].col[2] > 180)
c[i].col[2] -= 360;
}
qsort((void *) &c, (size_t) nmin, sizeof(struct minutiae_struct),
sort_x_y);
for (i = 0; i < nmin; i++) {
xyt->xcol[i] = c[i].col[0];
xyt->ycol[i] = c[i].col[1];
xyt->thetacol[i] = c[i].col[2];
}
xyt->nrows = nmin;
}
int fpi_img_detect_minutiae(struct fp_img_dev *imgdev, struct fp_img *img,
struct fp_print_data **ret)
{
MINUTIAE *minutiae;
int r;
int *direction_map, *low_contrast_map, *low_flow_map;
int *high_curve_map, *quality_map;
int map_w, map_h;
unsigned char *bdata;
int bw, bh, bd;
struct fp_print_data *print;
GTimer *timer;
/* 25.4 mm per inch */
timer = g_timer_new();
r = get_minutiae(&minutiae, &quality_map, &direction_map,
&low_contrast_map, &low_flow_map, &high_curve_map,
&map_w, &map_h, &bdata, &bw, &bh, &bd,
img->data, img->width, img->height, 8,
DEFAULT_PPI / (double)25.4, &lfsparms_V2);
g_timer_stop(timer);
fp_dbg("minutiae scan completed in %f secs", g_timer_elapsed(timer, NULL));
g_timer_destroy(timer);
if (r) {
fp_err("get minutiae failed, code %d", r);
return r;
}
fp_dbg("detected %d minutiae", minutiae->num);
r = minutiae->num;
/* FIXME: space is wasted if we dont hit the max minutiae count. would
* be good to make this dynamic. */
print = fpi_print_data_new(imgdev->dev, sizeof(struct xyt_struct));
minutiae_to_xyt(minutiae, bw, bh, print->buffer);
/* FIXME: the print buffer at this point is endian-specific, and will
* only work when loaded onto machines with identical endianness. not good!
* data format should be platform-independant. */
*ret = print;
free_minutiae(minutiae);
free(quality_map);
free(direction_map);
free(low_contrast_map);
free(low_flow_map);
free(high_curve_map);
free(bdata);
return r;
}
......@@ -138,10 +138,43 @@ API_EXPORTED int fp_imgdev_capture(struct fp_img_dev *imgdev,
return r;
}
#define MIN_ACCEPTABLE_MINUTIAE 5
int img_dev_enroll(struct fp_dev *dev, gboolean initial, int stage,
struct fp_print_data **ret)
{
struct fp_img *img;
struct fp_img_dev *imgdev = dev->priv;
struct fp_print_data *print;
int r;
/* FIXME: convert to 3-stage enroll mechanism, where we scan 3 prints,
* use NFIQ to pick the best one, and discard the others */
r = fp_imgdev_capture(imgdev, 0, &img);
if (r)
return r;
fp_img_standardize(img);
r = fpi_img_detect_minutiae(imgdev, img, &print);
fp_img_free(img);
if (r < 0)
return r;
if (r < MIN_ACCEPTABLE_MINUTIAE) {
fp_dbg("not enough minutiae, %d/%d", r, MIN_ACCEPTABLE_MINUTIAE);
fp_print_data_free(print);
return FP_ENROLL_RETRY;
}
*ret = print;
return FP_ENROLL_COMPLETE;
}
void fpi_img_driver_setup(struct fp_img_driver *idriver)
{
idriver->driver.type = DRIVER_IMAGING;
idriver->driver.init = img_dev_init;
idriver->driver.exit = img_dev_exit;
idriver->driver.enroll = img_dev_enroll;
}
/*******************************************************************************
License:
This software was developed at the National Institute of Standards and
Technology (NIST) by employees of the Federal Government in the course
of their official duties. Pursuant to title 17 Section 105 of the
United States Code, this software is not subject to copyright protection
and is in the public domain. NIST assumes no responsibility whatsoever for
its use by other parties, and makes no guarantees, expressed or implied,
about its quality, reliability, or any other characteristic.
Disclaimer:
This software was developed to promote biometric standards and biometric
technology testing for the Federal Government in accordance with the USA
PATRIOT Act and the Enhanced Border Security and Visa Entry Reform Act.
Specific hardware and software products identified in this software were used
in order to perform the software development. In no case does such
identification imply recommendation or endorsement by the National Institute
of Standards and Technology, nor does it imply that the products and equipment
identified are necessarily the best available for the purpose.
*******************************************************************************/
#ifndef _BOZORTH_H
#define _BOZORTH_H
/* The max number of points in any Probe or Gallery XYT is set to 200; */
/* a pointwise comparison table therefore has a maximum number of: */
/* (200^2)/2 = 20000 comparisons. */
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h> /* Needed for type pid_t */
#include <errno.h>
/* If not defined in sys/param.h */
#ifndef MAX
#define MAX(a,b) (((a)>(b))?(a):(b))
#endif
/**************************************************************************/
/* Math-Related Macros, Definitions & Prototypes */
/**************************************************************************/
#include <math.h>
/* This macro adjusts angles to the range (-180,180] */
#define IANGLE180(deg) ( ( (deg) > 180 ) ? ( (deg) - 360 ) : ( (deg) <= -180 ? ( (deg) + 360 ) : (deg) ) )
#define SENSE(a,b) ( (a) < (b) ? (-1) : ( ( (a) == (b) ) ? 0 : 1 ) )
#define SENSE_NEG_POS(a,b) ( (a) < (b) ? (-1) : 1 )
#define SQUARED(n) ( (n) * (n) )
#ifdef ROUND_USING_LIBRARY
/* These functions should be declared in math.h:
extern float roundf( float );
extern double round( double );
*/
#define ROUND(f) (roundf(f))
#else
#define ROUND(f) ( ( (f) < 0.0F ) ? ( (int) ( (f) - 0.5F ) ) : ( (int) ( (f) + 0.5F ) ) )
#endif
/* PI is used in: bozorth3.c, comp.c */
#ifdef M_PI
#define PI M_PI
#define PI_SINGLE ( (float) PI )
#else
#define PI 3.14159
#define PI_SINGLE 3.14159F
#endif
/* Provide prototype for atanf() */
extern float atanf( float );
/**************************************************************************/
/* Array Length Definitions */
/**************************************************************************/
#include <bz_array.h>
/**************************************************************************/
/**************************************************************************/
/* GENERAL DEFINITIONS */
/**************************************************************************/
#define FPNULL ((FILE *) NULL)
#define CNULL ((char *) NULL)
#define PROGRAM "bozorth3"
#define MAX_LINE_LENGTH 1024
#define SCOREFILE_EXTENSION ".scr"
#define MAX_FILELIST_LENGTH 10000
#define DEFAULT_BOZORTH_MINUTIAE 150
#define MAX_BOZORTH_MINUTIAE 200
#define MIN_BOZORTH_MINUTIAE 0
#define MIN_COMPUTABLE_BOZORTH_MINUTIAE 10
#define DEFAULT_MAX_MATCH_SCORE 400
#define ZERO_MATCH_SCORE 0
#define DEFAULT_SCORE_LINE_FORMAT "s"
#define DM 125
#define FD 5625
#define FDD 500
#define TK 0.05F
#define TXS 121
#define CTXS 121801
#define MSTR 3
#define MMSTR 8
#define WWIM 10
#define QQ_SIZE 4000
#define QQ_OVERFLOW_SCORE QQ_SIZE
/**************************************************************************/
/**************************************************************************/
/* MACROS DEFINITIONS */
/**************************************************************************/
#define INT_SET(dst,count,value) { \
int * int_set_dst = (dst); \
int int_set_count = (count); \
int int_set_value = (value); \
while ( int_set_count-- > 0 ) \
*int_set_dst++ = int_set_value; \
}
/* The code that calls it assumed dst gets bumped, so don't assign to a local variable */
#define INT_COPY(dst,src,count) { \
int * int_copy_src = (src); \
int int_copy_count = (count); \
while ( int_copy_count-- > 0 ) \
*dst++ = *int_copy_src++; \
}
/**************************************************************************/
/**************************************************************************/
/* STRUCTURES & TYPEDEFS */
/**************************************************************************/
/**************************************************************************/
/* In BZ_SORT.C - supports stdlib qsort() and customized quicksort */
/**************************************************************************/
/* Used by call to stdlib qsort() */
struct minutiae_struct {
int col[4];
};
/* Used by custom quicksort */
#define BZ_STACKSIZE 1000
struct cell {
int index; /* pointer to an array of pointers to index arrays */
int item; /* pointer to an item array */
};
/**************************************************************************/
/* In BZ_IO : Supports the loading and manipulation of XYT data */
/**************************************************************************/
#define MAX_FILE_MINUTIAE 1000 /* bz_load() */
struct xyt_struct {
int nrows;
int xcol[ MAX_BOZORTH_MINUTIAE ];
int ycol[ MAX_BOZORTH_MINUTIAE ];
int thetacol[ MAX_BOZORTH_MINUTIAE ];
};
#define XYT_NULL ( (struct xyt_struct *) NULL ) /* bz_load() */
/**************************************************************************/
/**************************************************************************/
/* GLOBAL VARIABLES */
/**************************************************************************/
/**************************************************************************/
/* In: SRC/BIN/BOZORTH3/BOZORTH3.C */
/**************************************************************************/
/* Globals supporting command line options */
extern int m1_xyt;
extern int max_minutiae;
extern int min_computable_minutiae;
extern int verbose_main;
extern int verbose_load;
extern int verbose_bozorth;
extern int verbose_threshold;
/* Global supporting error reporting */
extern FILE *errorfp;
/**************************************************************************/
/* In: BZ_GBLS.C */
/**************************************************************************/
/* Global arrays supporting "core" bozorth algorithm */
extern int colp[ COLP_SIZE_1 ][ COLP_SIZE_2 ];
extern int scols[ SCOLS_SIZE_1 ][ COLS_SIZE_2 ];
extern int fcols[ FCOLS_SIZE_1 ][ COLS_SIZE_2 ];
extern int * scolpt[ SCOLPT_SIZE ];
extern int * fcolpt[ FCOLPT_SIZE ];
extern int sc[ SC_SIZE ];
extern int yl[ YL_SIZE_1 ][ YL_SIZE_2 ];
/* Global arrays supporting "core" bozorth algorithm continued: */
/* Globals used significantly by sift() */
extern int rq[ RQ_SIZE ];
extern int tq[ TQ_SIZE ];
extern int zz[ ZZ_SIZE ];
extern int rx[ RX_SIZE ];
extern int mm[ MM_SIZE ];
extern int nn[ NN_SIZE ];
extern int qq[ QQ_SIZE ];
extern int rk[ RK_SIZE ];
extern int cp[ CP_SIZE ];
extern int rp[ RP_SIZE ];
extern int rf[RF_SIZE_1][RF_SIZE_2];
extern int cf[CF_SIZE_1][CF_SIZE_2];
extern int y[20000];
/**************************************************************************/
/**************************************************************************/
/* ROUTINE PROTOTYPES */
/**************************************************************************/
/* In: BZ_DRVRS.C */
extern int bozorth_probe_init( struct xyt_struct *);
extern int bozorth_gallery_init( struct xyt_struct *);
extern int bozorth_to_gallery(int, struct xyt_struct *, struct xyt_struct *);
extern int bozorth_main(struct xyt_struct *, struct xyt_struct *);
/* In: BOZORTH3.C */
extern void bz_comp(int, int [], int [], int [], int *, int [][COLS_SIZE_2],
int *[]);
extern void bz_find(int *, int *[]);
extern int bz_match(int, int);
extern int bz_match_score(int, struct xyt_struct *, struct xyt_struct *);
extern void bz_sift(int *, int, int *, int, int, int, int *, int *);
/* In: BZ_ALLOC.C */
extern char *malloc_or_exit(int, const char *);
extern char *malloc_or_return_error(int, const char *);
/* In: BZ_IO.C */
extern int parse_line_range(const char *, int *, int *);
extern void set_progname(int, char *, pid_t);
extern void set_probe_filename(char *);
extern void set_gallery_filename(char *);
extern char *get_progname(void);
extern char *get_probe_filename(void);
extern char *get_gallery_filename(void);
extern char *get_next_file(char *, FILE *, FILE *, int *, int *, char *,
int, char **, int *, int *, int, int);
extern char *get_score_filename(const char *, const char *);
extern char *get_score_line(const char *, const char *, int, int, const char *);
extern struct xyt_struct *bz_load(const char *);
extern int fd_readable(int);
/* In: BZ_SORT.C */
extern int sort_quality_decreasing(const void *, const void *);
extern int sort_order_decreasing(int [], int, int []);
#endif /* !_BOZORTH_H */
/*******************************************************************************
License:
This software was developed at the National Institute of Standards and
Technology (NIST) by employees of the Federal Government in the course
of their official duties. Pursuant to title 17 Section 105 of the
United States Code, this software is not subject to copyright protection
and is in the public domain. NIST assumes no responsibility whatsoever for
its use by other parties, and makes no guarantees, expressed or implied,
about its quality, reliability, or any other characteristic.
Disclaimer:
This software was developed to promote biometric standards and biometric
technology testing for the Federal Government in accordance with the USA
PATRIOT Act and the Enhanced Border Security and Visa Entry Reform Act.
Specific hardware and software products identified in this software were used
in order to perform the software development. In no case does such
identification imply recommendation or endorsement by the National Institute
of Standards and Technology, nor does it imply that the products and equipment
identified are necessarily the best available for the purpose.
*******************************************************************************/
#ifndef _BZ_ARRAY_H
#define _BZ_ARRAY_H
#define STATIC static
/* #define BAD_BOUNDS 1 */
#define COLP_SIZE_1 20000
#define COLP_SIZE_2 5
#define COLS_SIZE_2 6
#define SCOLS_SIZE_1 20000
#define FCOLS_SIZE_1 20000
#define SCOLPT_SIZE 20000
#define FCOLPT_SIZE 20000
#define SC_SIZE 20000
#define RQ_SIZE 20000
#define TQ_SIZE 20000
#define ZZ_SIZE 20000
#define RX_SIZE 100
#define MM_SIZE 100
#define NN_SIZE 20
#define RK_SIZE 20000
#define RR_SIZE 100
#define AVN_SIZE 5
#define AVV_SIZE_1 2000
#define AVV_SIZE_2 5
#define CT_SIZE 2000
#define GCT_SIZE 2000
#define CTT_SIZE 2000
#ifdef BAD_BOUNDS
#define CTP_SIZE_1 2000
#define CTP_SIZE_2 1000
#else
#define CTP_SIZE_1 2000
#define CTP_SIZE_2 2500
#endif
/*
rp[x] == ctp[][x] :: sct[x][]
*/
#define RF_SIZE_1 100
#define RF_SIZE_2 10
#define CF_SIZE_1 100
#define CF_SIZE_2 10
#define Y_SIZE 20000
#define YL_SIZE_1 2
#define YL_SIZE_2 2000
#define YY_SIZE_1 1000
#define YY_SIZE_2 2
#define YY_SIZE_3 2000
#ifdef BAD_BOUNDS
#define SCT_SIZE_1 1000
#define SCT_SIZE_2 1000
#else
#define SCT_SIZE_1 2500
#define SCT_SIZE_2 1000
#endif
#define CP_SIZE 20000
#define RP_SIZE 20000
#endif /* !_BZ_ARRAY_H */
/*******************************************************************************
License:
This software was developed at the National Institute of Standards and
Technology (NIST) by employees of the Federal Government in the course
of their official duties. Pursuant to title 17 Section 105 of the
United States Code, this software is not subject to copyright protection
and is in the public domain. NIST assumes no responsibility whatsoever for
its use by other parties, and makes no guarantees, expressed or implied,
about its quality, reliability, or any other characteristic.
Disclaimer:
This software was developed to promote biometric standards and biometric
technology testing for the Federal Government in accordance with the USA
PATRIOT Act and the Enhanced Border Security and Visa Entry Reform Act.
Specific hardware and software products identified in this software were used
in order to perform the software development. In no case does such
identification imply recommendation or endorsement by the National Institute
of Standards and Technology, nor does it imply that the products and equipment
identified are necessarily the best available for the purpose.
*******************************************************************************/
#ifndef _DEFS_H
#define _DEFS_H
/*********************************************************************/
/* General Purpose Defines */
/*********************************************************************/
#ifndef True
#define True 1
#define False 0
#endif
#ifndef TRUE
#define TRUE True
#define FALSE False
#endif
#define Yes True
#define No False
#define Empty NULL
#ifndef None
#define None -1
#endif
#ifndef FOUND
#define FOUND 1
#endif
#define NOT_FOUND_NEG -1
#define EOL EOF
#ifndef DEG2RAD
#define DEG2RAD (double)(57.29578)
#endif
#define max(a, b) ((a) > (b) ? (a) : (b))
#define min(a, b) ((a) < (b) ? (a) : (b))
#define sround(x) ((int) (((x)<0) ? (x)-0.5 : (x)+0.5))
#define sround_uint(x) ((unsigned int) (((x)<0) ? (x)-0.5 : (x)+0.5))
#define xor(a, b) (!(a && b) && (a || b))
#define align_to_16(_v_) ((((_v_)+15)>>4)<<4)
#define align_to_32(_v_) ((((_v_)+31)>>5)<<5)
#ifndef CHUNKS
#define CHUNKS 100
#endif
#endif /* !_DEFS_H */
This diff is collapsed.
/*******************************************************************************
License:
This software was developed at the National Institute of Standards and
Technology (NIST) by employees of the Federal Government in the course
of their official duties. Pursuant to title 17 Section 105 of the
United States Code, this software is not subject to copyright protection
and is in the public domain. NIST assumes no responsibility whatsoever for
its use by other parties, and makes no guarantees, expressed or implied,
about its quality, reliability, or any other characteristic.
Disclaimer:
This software was developed to promote biometric standards and biometric
technology testing for the Federal Government in accordance with the USA
PATRIOT Act and the Enhanced Border Security and Visa Entry Reform Act.
Specific hardware and software products identified in this software were used
in order to perform the software development. In no case does such
identification imply recommendation or endorsement by the National Institute
of Standards and Technology, nor does it imply that the products and equipment
identified are necessarily the best available for the purpose.
*******************************************************************************/
#ifndef _LOG_H
#define _LOG_H
/* Definitions and references to support log report files. */
/* UPDATED: 03/16/2005 by MDG */
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#ifdef LOG_REPORT
/* Uncomment the following line to enable logging. */
#define LOG_FILE "log.txt"
#endif
extern FILE *logfp;
extern int avrdir;
extern float dir_strength;
extern int nvalid;
extern int open_logfile(void);
extern int close_logfile(void);
extern void print2log(char *, ...);
#endif
/*******************************************************************************
License:
This software was developed at the National Institute of Standards and
Technology (NIST) by employees of the Federal Government in the course
of their official duties. Pursuant to title 17 Section 105 of the
United States Code, this software is not subject to copyright protection
and is in the public domain. NIST assumes no responsibility whatsoever for
its use by other parties, and makes no guarantees, expressed or implied,
about its quality, reliability, or any other characteristic.
Disclaimer:
This software was developed to promote biometric standards and biometric