nbis: Update to NBIS 5.0.0
This updates NBIS to its latest 5.0.0 version, dated 04/03/2015, from a 1.x version, dated 2007. Original sources are available at: https://www.nist.gov/itl/iad/image-group/products-and-services/image-group-open-source-server-nigos#Releases And full change log at: https://www.nist.gov/sites/default/files/documents/2016/12/14/changelog.txt
This commit is contained in:
parent
770444af55
commit
9fb789dc78
41 changed files with 4165 additions and 4964 deletions
|
@ -30,14 +30,17 @@ nbis_sources = [
|
||||||
'nbis/bozorth3/bz_sort.c',
|
'nbis/bozorth3/bz_sort.c',
|
||||||
'nbis/mindtct/binar.c',
|
'nbis/mindtct/binar.c',
|
||||||
'nbis/mindtct/block.c',
|
'nbis/mindtct/block.c',
|
||||||
|
'nbis/mindtct/chaincod.c',
|
||||||
'nbis/mindtct/contour.c',
|
'nbis/mindtct/contour.c',
|
||||||
'nbis/mindtct/detect.c',
|
'nbis/mindtct/detect.c',
|
||||||
'nbis/mindtct/dft.c',
|
'nbis/mindtct/dft.c',
|
||||||
'nbis/mindtct/free.c',
|
'nbis/mindtct/free.c',
|
||||||
|
'nbis/mindtct/getmin.c',
|
||||||
'nbis/mindtct/globals.c',
|
'nbis/mindtct/globals.c',
|
||||||
'nbis/mindtct/imgutil.c',
|
'nbis/mindtct/imgutil.c',
|
||||||
'nbis/mindtct/init.c',
|
'nbis/mindtct/init.c',
|
||||||
'nbis/mindtct/line.c',
|
'nbis/mindtct/line.c',
|
||||||
|
'nbis/mindtct/link.c',
|
||||||
'nbis/mindtct/log.c',
|
'nbis/mindtct/log.c',
|
||||||
'nbis/mindtct/loop.c',
|
'nbis/mindtct/loop.c',
|
||||||
'nbis/mindtct/maps.c',
|
'nbis/mindtct/maps.c',
|
||||||
|
@ -50,6 +53,7 @@ nbis_sources = [
|
||||||
'nbis/mindtct/shape.c',
|
'nbis/mindtct/shape.c',
|
||||||
'nbis/mindtct/sort.c',
|
'nbis/mindtct/sort.c',
|
||||||
'nbis/mindtct/util.c',
|
'nbis/mindtct/util.c',
|
||||||
|
'nbis/mindtct/xytreps.c',
|
||||||
]
|
]
|
||||||
|
|
||||||
aeslib = false
|
aeslib = false
|
||||||
|
|
|
@ -1,51 +1,43 @@
|
||||||
/******************************************************************************
|
|
||||||
|
|
||||||
This file is part of the Export Control subset of the United States NIST
|
|
||||||
Biometric Image Software (NBIS) distribution:
|
|
||||||
http://fingerprint.nist.gov/NBIS/index.html
|
|
||||||
|
|
||||||
It is our understanding that this falls within ECCN 3D980, which covers
|
|
||||||
software associated with the development, production or use of certain
|
|
||||||
equipment controlled in accordance with U.S. concerns about crime control
|
|
||||||
practices in specific countries.
|
|
||||||
|
|
||||||
Therefore, this file should not be exported, or made available on fileservers,
|
|
||||||
except as allowed by U.S. export control laws.
|
|
||||||
|
|
||||||
Do not remove this notice.
|
|
||||||
|
|
||||||
******************************************************************************/
|
|
||||||
|
|
||||||
/* NOTE: Despite the above notice (which I have not removed), this file is
|
|
||||||
* being legally distributed within libfprint; the U.S. Export Administration
|
|
||||||
* Regulations do not place export restrictions upon distribution of
|
|
||||||
* "publicly available technology and software", as stated in EAR section
|
|
||||||
* 734.3(b)(3)(i). libfprint qualifies as publicly available technology as per
|
|
||||||
* the definition in section 734.7(a)(1).
|
|
||||||
*
|
|
||||||
* For further information, see https://fprint.freedesktop.org/us-export-control.html
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
|
|
||||||
License:
|
License:
|
||||||
This software was developed at the National Institute of Standards and
|
This software and/or related materials was developed at the National Institute
|
||||||
Technology (NIST) by employees of the Federal Government in the course
|
of Standards and Technology (NIST) by employees of the Federal Government
|
||||||
of their official duties. Pursuant to title 17 Section 105 of the
|
in the course of their official duties. Pursuant to title 17 Section 105
|
||||||
United States Code, this software is not subject to copyright protection
|
of the United States Code, this software is not subject to copyright
|
||||||
and is in the public domain. NIST assumes no responsibility whatsoever for
|
protection and is in the public domain.
|
||||||
its use by other parties, and makes no guarantees, expressed or implied,
|
|
||||||
about its quality, reliability, or any other characteristic.
|
|
||||||
|
|
||||||
Disclaimer:
|
This software and/or related materials have been determined to be not subject
|
||||||
This software was developed to promote biometric standards and biometric
|
to the EAR (see Part 734.3 of the EAR for exact details) because it is
|
||||||
technology testing for the Federal Government in accordance with the USA
|
a publicly available technology and software, and is freely distributed
|
||||||
PATRIOT Act and the Enhanced Border Security and Visa Entry Reform Act.
|
to any interested party with no licensing requirements. Therefore, it is
|
||||||
Specific hardware and software products identified in this software were used
|
permissible to distribute this software as a free download from the internet.
|
||||||
in order to perform the software development. In no case does such
|
|
||||||
identification imply recommendation or endorsement by the National Institute
|
Disclaimer:
|
||||||
of Standards and Technology, nor does it imply that the products and equipment
|
This software and/or related materials was developed to promote biometric
|
||||||
identified are necessarily the best available for the purpose.
|
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.
|
||||||
|
|
||||||
|
This software and/or related materials are provided "AS-IS" without warranty
|
||||||
|
of any kind including NO WARRANTY OF PERFORMANCE, MERCHANTABILITY,
|
||||||
|
NO WARRANTY OF NON-INFRINGEMENT OF ANY 3RD PARTY INTELLECTUAL PROPERTY
|
||||||
|
or FITNESS FOR A PARTICULAR PURPOSE or for any purpose whatsoever, for the
|
||||||
|
licensed product, however used. In no event shall NIST be liable for any
|
||||||
|
damages and/or costs, including but not limited to incidental or consequential
|
||||||
|
damages of any kind, including economic damage or injury to property and lost
|
||||||
|
profits, regardless of whether NIST shall be advised, have reason to know,
|
||||||
|
or in fact shall know of the possibility.
|
||||||
|
|
||||||
|
By using this software, you agree to bear all risk relating to quality,
|
||||||
|
use and performance of the software and/or related materials. You agree
|
||||||
|
to hold the Government harmless from any claim arising from your use
|
||||||
|
of the software.
|
||||||
|
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
|
|
||||||
|
@ -89,9 +81,6 @@ identified are necessarily the best available for the purpose.
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <bozorth.h>
|
#include <bozorth.h>
|
||||||
|
|
||||||
static const int verbose_bozorth = 0;
|
|
||||||
static const int m1_xyt = 0;
|
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
void bz_comp(
|
void bz_comp(
|
||||||
int npoints, /* INPUT: # of points */
|
int npoints, /* INPUT: # of points */
|
||||||
|
@ -160,7 +149,7 @@ for ( k = 0; k < npoints - 1; k++ ) {
|
||||||
else {
|
else {
|
||||||
double dz;
|
double dz;
|
||||||
|
|
||||||
if ( m1_xyt )
|
if ( 0 )
|
||||||
dz = ( 180.0F / PI_SINGLE ) * atanf( (float) -dy / (float) dx );
|
dz = ( 180.0F / PI_SINGLE ) * atanf( (float) -dy / (float) dx );
|
||||||
else
|
else
|
||||||
dz = ( 180.0F / PI_SINGLE ) * atanf( (float) dy / (float) dx );
|
dz = ( 180.0F / PI_SINGLE ) * atanf( (float) dy / (float) dx );
|
||||||
|
@ -261,7 +250,7 @@ for ( k = 0; k < npoints - 1; k++ ) {
|
||||||
|
|
||||||
if ( table_index == 19999 ) {
|
if ( table_index == 19999 ) {
|
||||||
#ifndef NOVERBOSE
|
#ifndef NOVERBOSE
|
||||||
if ( verbose_bozorth )
|
if ( 0 )
|
||||||
printf( "bz_comp(): breaking loop to avoid table overflow\n" );
|
printf( "bz_comp(): breaking loop to avoid table overflow\n" );
|
||||||
#endif
|
#endif
|
||||||
goto COMP_END;
|
goto COMP_END;
|
||||||
|
@ -392,7 +381,7 @@ static int * rtp[ ROT_SIZE_1 ];
|
||||||
/* extern int * scolpt[ SCOLPT_SIZE ]; INPUT */
|
/* extern int * scolpt[ SCOLPT_SIZE ]; INPUT */
|
||||||
/* extern int * fcolpt[ FCOLPT_SIZE ]; INPUT */
|
/* extern int * fcolpt[ FCOLPT_SIZE ]; INPUT */
|
||||||
/* extern int colp[ COLP_SIZE_1 ][ COLP_SIZE_2 ]; OUTPUT */
|
/* extern int colp[ COLP_SIZE_1 ][ COLP_SIZE_2 ]; OUTPUT */
|
||||||
/* extern int verbose_bozorth; */
|
/* extern int 0; */
|
||||||
/* extern FILE * stderr; */
|
/* extern FILE * stderr; */
|
||||||
/* extern char * get_progname( void ); */
|
/* extern char * get_progname( void ); */
|
||||||
/* extern char * get_probe_filename( void ); */
|
/* extern char * get_probe_filename( void ); */
|
||||||
|
@ -401,6 +390,7 @@ static int * rtp[ ROT_SIZE_1 ];
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
st = 1;
|
st = 1;
|
||||||
edge_pair_index = 0;
|
edge_pair_index = 0;
|
||||||
rotptr = &rot[0][0];
|
rotptr = &rot[0][0];
|
||||||
|
@ -570,7 +560,7 @@ for ( k = 1; k < probe_ptrlist_len; k++ ) {
|
||||||
|
|
||||||
if ( edge_pair_index == 19999 ) {
|
if ( edge_pair_index == 19999 ) {
|
||||||
#ifndef NOVERBOSE
|
#ifndef NOVERBOSE
|
||||||
if ( verbose_bozorth )
|
if ( 0 )
|
||||||
fprintf( stderr, "%s: bz_match(): WARNING: list is full, breaking loop early [p=%s; g=%s]\n",
|
fprintf( stderr, "%s: bz_match(): WARNING: list is full, breaking loop early [p=%s; g=%s]\n",
|
||||||
get_progname(), get_probe_filename(), get_gallery_filename() );
|
get_progname(), get_probe_filename(), get_gallery_filename() );
|
||||||
#endif
|
#endif
|
||||||
|
@ -652,13 +642,13 @@ int avv[ AVV_SIZE_1 ][ AVV_SIZE_2 ];
|
||||||
if ( pstruct->nrows < MIN_COMPUTABLE_BOZORTH_MINUTIAE ) {
|
if ( pstruct->nrows < MIN_COMPUTABLE_BOZORTH_MINUTIAE ) {
|
||||||
#ifndef NOVERBOSE
|
#ifndef NOVERBOSE
|
||||||
if ( gstruct->nrows < MIN_COMPUTABLE_BOZORTH_MINUTIAE ) {
|
if ( gstruct->nrows < MIN_COMPUTABLE_BOZORTH_MINUTIAE ) {
|
||||||
if ( verbose_bozorth )
|
if ( 0 )
|
||||||
fprintf( stderr, "%s: bz_match_score(): both probe and gallery file have too few minutiae (%d,%d) to compute a real Bozorth match score; min. is %d [p=%s; g=%s]\n",
|
fprintf( stderr, "%s: bz_match_score(): both probe and gallery file have too few minutiae (%d,%d) to compute a real Bozorth match score; min. is %d [p=%s; g=%s]\n",
|
||||||
get_progname(),
|
get_progname(),
|
||||||
pstruct->nrows, gstruct->nrows, MIN_COMPUTABLE_BOZORTH_MINUTIAE,
|
pstruct->nrows, gstruct->nrows, MIN_COMPUTABLE_BOZORTH_MINUTIAE,
|
||||||
get_probe_filename(), get_gallery_filename() );
|
get_probe_filename(), get_gallery_filename() );
|
||||||
} else {
|
} else {
|
||||||
if ( verbose_bozorth )
|
if ( 0 )
|
||||||
fprintf( stderr, "%s: bz_match_score(): probe file has too few minutiae (%d) to compute a real Bozorth match score; min. is %d [p=%s; g=%s]\n",
|
fprintf( stderr, "%s: bz_match_score(): probe file has too few minutiae (%d) to compute a real Bozorth match score; min. is %d [p=%s; g=%s]\n",
|
||||||
get_progname(),
|
get_progname(),
|
||||||
pstruct->nrows, MIN_COMPUTABLE_BOZORTH_MINUTIAE,
|
pstruct->nrows, MIN_COMPUTABLE_BOZORTH_MINUTIAE,
|
||||||
|
@ -672,7 +662,7 @@ if ( pstruct->nrows < MIN_COMPUTABLE_BOZORTH_MINUTIAE ) {
|
||||||
|
|
||||||
if ( gstruct->nrows < MIN_COMPUTABLE_BOZORTH_MINUTIAE ) {
|
if ( gstruct->nrows < MIN_COMPUTABLE_BOZORTH_MINUTIAE ) {
|
||||||
#ifndef NOVERBOSE
|
#ifndef NOVERBOSE
|
||||||
if ( verbose_bozorth )
|
if ( 0 )
|
||||||
fprintf( stderr, "%s: bz_match_score(): gallery file has too few minutiae (%d) to compute a real Bozorth match score; min. is %d [p=%s; g=%s]\n",
|
fprintf( stderr, "%s: bz_match_score(): gallery file has too few minutiae (%d) to compute a real Bozorth match score; min. is %d [p=%s; g=%s]\n",
|
||||||
get_progname(),
|
get_progname(),
|
||||||
gstruct->nrows, MIN_COMPUTABLE_BOZORTH_MINUTIAE,
|
gstruct->nrows, MIN_COMPUTABLE_BOZORTH_MINUTIAE,
|
||||||
|
@ -765,7 +755,7 @@ for ( k = 0; k < np - 1; k++ ) {
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef NOVERBOSE
|
#ifndef NOVERBOSE
|
||||||
if ( verbose_bozorth )
|
if ( 0 )
|
||||||
printf( "x1 %d %d %d %d %d %d\n", kx, colp[kx][0], colp[kx][1], colp[kx][2], colp[kx][3], colp[kx][4] );
|
printf( "x1 %d %d %d %d %d %d\n", kx, colp[kx][0], colp[kx][1], colp[kx][2], colp[kx][3], colp[kx][4] );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -1167,7 +1157,7 @@ for ( k = 0; k < np - 1; k++ ) {
|
||||||
|
|
||||||
if ( ll ) {
|
if ( ll ) {
|
||||||
|
|
||||||
if ( m1_xyt )
|
if ( 0 )
|
||||||
fi = ( 180.0F / PI_SINGLE ) * atanf( (float) -jj / (float) ll );
|
fi = ( 180.0F / PI_SINGLE ) * atanf( (float) -jj / (float) ll );
|
||||||
else
|
else
|
||||||
fi = ( 180.0F / PI_SINGLE ) * atanf( (float) jj / (float) ll );
|
fi = ( 180.0F / PI_SINGLE ) * atanf( (float) jj / (float) ll );
|
||||||
|
@ -1187,7 +1177,7 @@ for ( k = 0; k < np - 1; k++ ) {
|
||||||
jj += 360;
|
jj += 360;
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
if ( m1_xyt ) {
|
if ( 0 ) {
|
||||||
if ( jj > 0 )
|
if ( jj > 0 )
|
||||||
jj = -90;
|
jj = -90;
|
||||||
else
|
else
|
||||||
|
@ -1204,7 +1194,7 @@ for ( k = 0; k < np - 1; k++ ) {
|
||||||
|
|
||||||
if ( kk ) {
|
if ( kk ) {
|
||||||
|
|
||||||
if ( m1_xyt )
|
if ( 0 )
|
||||||
fi = ( 180.0F / PI_SINGLE ) * atanf( (float) -j / (float) kk );
|
fi = ( 180.0F / PI_SINGLE ) * atanf( (float) -j / (float) kk );
|
||||||
else
|
else
|
||||||
fi = ( 180.0F / PI_SINGLE ) * atanf( (float) j / (float) kk );
|
fi = ( 180.0F / PI_SINGLE ) * atanf( (float) j / (float) kk );
|
||||||
|
@ -1224,7 +1214,7 @@ for ( k = 0; k < np - 1; k++ ) {
|
||||||
j += 360;
|
j += 360;
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
if ( m1_xyt ) {
|
if ( 0 ) {
|
||||||
if ( j > 0 )
|
if ( j > 0 )
|
||||||
j = -90;
|
j = -90;
|
||||||
else
|
else
|
||||||
|
@ -1611,7 +1601,7 @@ if ( n ) {
|
||||||
notfound = 1;
|
notfound = 1;
|
||||||
|
|
||||||
#ifndef NOVERBOSE
|
#ifndef NOVERBOSE
|
||||||
if ( verbose_bozorth ) {
|
if ( 0 ) {
|
||||||
int * llptr = lptr;
|
int * llptr = lptr;
|
||||||
printf( "bz_sift(): n: looking for l=%d in [", l );
|
printf( "bz_sift(): n: looking for l=%d in [", l );
|
||||||
for ( i = 0; i < lim; i++ ) {
|
for ( i = 0; i < lim; i++ ) {
|
||||||
|
@ -1657,7 +1647,7 @@ if ( t ) {
|
||||||
notfound = 1;
|
notfound = 1;
|
||||||
|
|
||||||
#ifndef NOVERBOSE
|
#ifndef NOVERBOSE
|
||||||
if ( verbose_bozorth ) {
|
if ( 0 ) {
|
||||||
int * llptr = lptr;
|
int * llptr = lptr;
|
||||||
printf( "bz_sift(): t: looking for kz=%d in [", kz );
|
printf( "bz_sift(): t: looking for kz=%d in [", kz );
|
||||||
for ( i = 0; i < lim; i++ ) {
|
for ( i = 0; i < lim; i++ ) {
|
||||||
|
|
|
@ -1,51 +1,43 @@
|
||||||
/******************************************************************************
|
|
||||||
|
|
||||||
This file is part of the Export Control subset of the United States NIST
|
|
||||||
Biometric Image Software (NBIS) distribution:
|
|
||||||
http://fingerprint.nist.gov/NBIS/index.html
|
|
||||||
|
|
||||||
It is our understanding that this falls within ECCN 3D980, which covers
|
|
||||||
software associated with the development, production or use of certain
|
|
||||||
equipment controlled in accordance with U.S. concerns about crime control
|
|
||||||
practices in specific countries.
|
|
||||||
|
|
||||||
Therefore, this file should not be exported, or made available on fileservers,
|
|
||||||
except as allowed by U.S. export control laws.
|
|
||||||
|
|
||||||
Do not remove this notice.
|
|
||||||
|
|
||||||
******************************************************************************/
|
|
||||||
|
|
||||||
/* NOTE: Despite the above notice (which I have not removed), this file is
|
|
||||||
* being legally distributed within libfprint; the U.S. Export Administration
|
|
||||||
* Regulations do not place export restrictions upon distribution of
|
|
||||||
* "publicly available technology and software", as stated in EAR section
|
|
||||||
* 734.3(b)(3)(i). libfprint qualifies as publicly available technology as per
|
|
||||||
* the definition in section 734.7(a)(1).
|
|
||||||
*
|
|
||||||
* For further information, see https://fprint.freedesktop.org/us-export-control.html
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
|
|
||||||
License:
|
License:
|
||||||
This software was developed at the National Institute of Standards and
|
This software and/or related materials was developed at the National Institute
|
||||||
Technology (NIST) by employees of the Federal Government in the course
|
of Standards and Technology (NIST) by employees of the Federal Government
|
||||||
of their official duties. Pursuant to title 17 Section 105 of the
|
in the course of their official duties. Pursuant to title 17 Section 105
|
||||||
United States Code, this software is not subject to copyright protection
|
of the United States Code, this software is not subject to copyright
|
||||||
and is in the public domain. NIST assumes no responsibility whatsoever for
|
protection and is in the public domain.
|
||||||
its use by other parties, and makes no guarantees, expressed or implied,
|
|
||||||
about its quality, reliability, or any other characteristic.
|
|
||||||
|
|
||||||
Disclaimer:
|
This software and/or related materials have been determined to be not subject
|
||||||
This software was developed to promote biometric standards and biometric
|
to the EAR (see Part 734.3 of the EAR for exact details) because it is
|
||||||
technology testing for the Federal Government in accordance with the USA
|
a publicly available technology and software, and is freely distributed
|
||||||
PATRIOT Act and the Enhanced Border Security and Visa Entry Reform Act.
|
to any interested party with no licensing requirements. Therefore, it is
|
||||||
Specific hardware and software products identified in this software were used
|
permissible to distribute this software as a free download from the internet.
|
||||||
in order to perform the software development. In no case does such
|
|
||||||
identification imply recommendation or endorsement by the National Institute
|
Disclaimer:
|
||||||
of Standards and Technology, nor does it imply that the products and equipment
|
This software and/or related materials was developed to promote biometric
|
||||||
identified are necessarily the best available for the purpose.
|
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.
|
||||||
|
|
||||||
|
This software and/or related materials are provided "AS-IS" without warranty
|
||||||
|
of any kind including NO WARRANTY OF PERFORMANCE, MERCHANTABILITY,
|
||||||
|
NO WARRANTY OF NON-INFRINGEMENT OF ANY 3RD PARTY INTELLECTUAL PROPERTY
|
||||||
|
or FITNESS FOR A PARTICULAR PURPOSE or for any purpose whatsoever, for the
|
||||||
|
licensed product, however used. In no event shall NIST be liable for any
|
||||||
|
damages and/or costs, including but not limited to incidental or consequential
|
||||||
|
damages of any kind, including economic damage or injury to property and lost
|
||||||
|
profits, regardless of whether NIST shall be advised, have reason to know,
|
||||||
|
or in fact shall know of the possibility.
|
||||||
|
|
||||||
|
By using this software, you agree to bear all risk relating to quality,
|
||||||
|
use and performance of the software and/or related materials. You agree
|
||||||
|
to hold the Government harmless from any claim arising from your use
|
||||||
|
of the software.
|
||||||
|
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
|
|
||||||
|
@ -77,43 +69,6 @@ identified are necessarily the best available for the purpose.
|
||||||
|
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
char * malloc_or_exit( int nbytes, const char * what )
|
|
||||||
{
|
|
||||||
char * p;
|
|
||||||
|
|
||||||
/* These are now externally defined in bozorth.h */
|
|
||||||
/* extern FILE * stderr; */
|
|
||||||
/* extern char * get_progname( void ); */
|
|
||||||
|
|
||||||
|
|
||||||
p = malloc( (size_t) nbytes );
|
|
||||||
if ( p == CNULL ) {
|
|
||||||
fprintf( stderr, "%s: ERROR: malloc() of %d bytes for %s failed: %s\n",
|
|
||||||
get_progname(),
|
|
||||||
nbytes,
|
|
||||||
what,
|
|
||||||
strerror( errno )
|
|
||||||
);
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
return p;
|
|
||||||
}
|
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
/* returns CNULL on error */
|
/* returns CNULL on error */
|
||||||
char * malloc_or_return_error( int nbytes, const char * what )
|
|
||||||
{
|
|
||||||
char * p;
|
|
||||||
|
|
||||||
p = malloc( (size_t) nbytes );
|
|
||||||
if ( p == CNULL ) {
|
|
||||||
fprintf( stderr, "%s: ERROR: malloc() of %d bytes for %s failed: %s\n",
|
|
||||||
get_progname(),
|
|
||||||
nbytes,
|
|
||||||
what,
|
|
||||||
strerror( errno )
|
|
||||||
);
|
|
||||||
return(CNULL);
|
|
||||||
}
|
|
||||||
return p;
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,51 +1,43 @@
|
||||||
/******************************************************************************
|
|
||||||
|
|
||||||
This file is part of the Export Control subset of the United States NIST
|
|
||||||
Biometric Image Software (NBIS) distribution:
|
|
||||||
http://fingerprint.nist.gov/NBIS/index.html
|
|
||||||
|
|
||||||
It is our understanding that this falls within ECCN 3D980, which covers
|
|
||||||
software associated with the development, production or use of certain
|
|
||||||
equipment controlled in accordance with U.S. concerns about crime control
|
|
||||||
practices in specific countries.
|
|
||||||
|
|
||||||
Therefore, this file should not be exported, or made available on fileservers,
|
|
||||||
except as allowed by U.S. export control laws.
|
|
||||||
|
|
||||||
Do not remove this notice.
|
|
||||||
|
|
||||||
******************************************************************************/
|
|
||||||
|
|
||||||
/* NOTE: Despite the above notice (which I have not removed), this file is
|
|
||||||
* being legally distributed within libfprint; the U.S. Export Administration
|
|
||||||
* Regulations do not place export restrictions upon distribution of
|
|
||||||
* "publicly available technology and software", as stated in EAR section
|
|
||||||
* 734.3(b)(3)(i). libfprint qualifies as publicly available technology as per
|
|
||||||
* the definition in section 734.7(a)(1).
|
|
||||||
*
|
|
||||||
* For further information, see https://fprint.freedesktop.org/us-export-control.html
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
|
|
||||||
License:
|
License:
|
||||||
This software was developed at the National Institute of Standards and
|
This software and/or related materials was developed at the National Institute
|
||||||
Technology (NIST) by employees of the Federal Government in the course
|
of Standards and Technology (NIST) by employees of the Federal Government
|
||||||
of their official duties. Pursuant to title 17 Section 105 of the
|
in the course of their official duties. Pursuant to title 17 Section 105
|
||||||
United States Code, this software is not subject to copyright protection
|
of the United States Code, this software is not subject to copyright
|
||||||
and is in the public domain. NIST assumes no responsibility whatsoever for
|
protection and is in the public domain.
|
||||||
its use by other parties, and makes no guarantees, expressed or implied,
|
|
||||||
about its quality, reliability, or any other characteristic.
|
|
||||||
|
|
||||||
Disclaimer:
|
This software and/or related materials have been determined to be not subject
|
||||||
This software was developed to promote biometric standards and biometric
|
to the EAR (see Part 734.3 of the EAR for exact details) because it is
|
||||||
technology testing for the Federal Government in accordance with the USA
|
a publicly available technology and software, and is freely distributed
|
||||||
PATRIOT Act and the Enhanced Border Security and Visa Entry Reform Act.
|
to any interested party with no licensing requirements. Therefore, it is
|
||||||
Specific hardware and software products identified in this software were used
|
permissible to distribute this software as a free download from the internet.
|
||||||
in order to perform the software development. In no case does such
|
|
||||||
identification imply recommendation or endorsement by the National Institute
|
Disclaimer:
|
||||||
of Standards and Technology, nor does it imply that the products and equipment
|
This software and/or related materials was developed to promote biometric
|
||||||
identified are necessarily the best available for the purpose.
|
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.
|
||||||
|
|
||||||
|
This software and/or related materials are provided "AS-IS" without warranty
|
||||||
|
of any kind including NO WARRANTY OF PERFORMANCE, MERCHANTABILITY,
|
||||||
|
NO WARRANTY OF NON-INFRINGEMENT OF ANY 3RD PARTY INTELLECTUAL PROPERTY
|
||||||
|
or FITNESS FOR A PARTICULAR PURPOSE or for any purpose whatsoever, for the
|
||||||
|
licensed product, however used. In no event shall NIST be liable for any
|
||||||
|
damages and/or costs, including but not limited to incidental or consequential
|
||||||
|
damages of any kind, including economic damage or injury to property and lost
|
||||||
|
profits, regardless of whether NIST shall be advised, have reason to know,
|
||||||
|
or in fact shall know of the possibility.
|
||||||
|
|
||||||
|
By using this software, you agree to bear all risk relating to quality,
|
||||||
|
use and performance of the software and/or related materials. You agree
|
||||||
|
to hold the Government harmless from any claim arising from your use
|
||||||
|
of the software.
|
||||||
|
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
|
|
||||||
|
@ -177,47 +169,3 @@ return bz_match_score( np, pstruct, gstruct );
|
||||||
|
|
||||||
/**************************************************************************/
|
/**************************************************************************/
|
||||||
|
|
||||||
int bozorth_main(
|
|
||||||
struct xyt_struct * pstruct,
|
|
||||||
struct xyt_struct * gstruct
|
|
||||||
)
|
|
||||||
{
|
|
||||||
int ms;
|
|
||||||
int np;
|
|
||||||
int probe_len;
|
|
||||||
int gallery_len;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
|
||||||
printf( "PROBE_INIT() called\n" );
|
|
||||||
#endif
|
|
||||||
probe_len = bozorth_probe_init( pstruct );
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
|
||||||
printf( "GALLERY_INIT() called\n" );
|
|
||||||
#endif
|
|
||||||
gallery_len = bozorth_gallery_init( gstruct );
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
|
||||||
printf( "BZ_MATCH() called\n" );
|
|
||||||
#endif
|
|
||||||
np = bz_match( probe_len, gallery_len );
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
|
||||||
printf( "BZ_MATCH() returned %d edge pairs\n", np );
|
|
||||||
printf( "COMPUTE() called\n" );
|
|
||||||
#endif
|
|
||||||
ms = bz_match_score( np, pstruct, gstruct );
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
|
||||||
printf( "COMPUTE() returned %d\n", ms );
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
return ms;
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,51 +1,43 @@
|
||||||
/******************************************************************************
|
|
||||||
|
|
||||||
This file is part of the Export Control subset of the United States NIST
|
|
||||||
Biometric Image Software (NBIS) distribution:
|
|
||||||
http://fingerprint.nist.gov/NBIS/index.html
|
|
||||||
|
|
||||||
It is our understanding that this falls within ECCN 3D980, which covers
|
|
||||||
software associated with the development, production or use of certain
|
|
||||||
equipment controlled in accordance with U.S. concerns about crime control
|
|
||||||
practices in specific countries.
|
|
||||||
|
|
||||||
Therefore, this file should not be exported, or made available on fileservers,
|
|
||||||
except as allowed by U.S. export control laws.
|
|
||||||
|
|
||||||
Do not remove this notice.
|
|
||||||
|
|
||||||
******************************************************************************/
|
|
||||||
|
|
||||||
/* NOTE: Despite the above notice (which I have not removed), this file is
|
|
||||||
* being legally distributed within libfprint; the U.S. Export Administration
|
|
||||||
* Regulations do not place export restrictions upon distribution of
|
|
||||||
* "publicly available technology and software", as stated in EAR section
|
|
||||||
* 734.3(b)(3)(i). libfprint qualifies as publicly available technology as per
|
|
||||||
* the definition in section 734.7(a)(1).
|
|
||||||
*
|
|
||||||
* For further information, see https://fprint.freedesktop.org/us-export-control.html
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
|
|
||||||
License:
|
License:
|
||||||
This software was developed at the National Institute of Standards and
|
This software and/or related materials was developed at the National Institute
|
||||||
Technology (NIST) by employees of the Federal Government in the course
|
of Standards and Technology (NIST) by employees of the Federal Government
|
||||||
of their official duties. Pursuant to title 17 Section 105 of the
|
in the course of their official duties. Pursuant to title 17 Section 105
|
||||||
United States Code, this software is not subject to copyright protection
|
of the United States Code, this software is not subject to copyright
|
||||||
and is in the public domain. NIST assumes no responsibility whatsoever for
|
protection and is in the public domain.
|
||||||
its use by other parties, and makes no guarantees, expressed or implied,
|
|
||||||
about its quality, reliability, or any other characteristic.
|
|
||||||
|
|
||||||
Disclaimer:
|
This software and/or related materials have been determined to be not subject
|
||||||
This software was developed to promote biometric standards and biometric
|
to the EAR (see Part 734.3 of the EAR for exact details) because it is
|
||||||
technology testing for the Federal Government in accordance with the USA
|
a publicly available technology and software, and is freely distributed
|
||||||
PATRIOT Act and the Enhanced Border Security and Visa Entry Reform Act.
|
to any interested party with no licensing requirements. Therefore, it is
|
||||||
Specific hardware and software products identified in this software were used
|
permissible to distribute this software as a free download from the internet.
|
||||||
in order to perform the software development. In no case does such
|
|
||||||
identification imply recommendation or endorsement by the National Institute
|
Disclaimer:
|
||||||
of Standards and Technology, nor does it imply that the products and equipment
|
This software and/or related materials was developed to promote biometric
|
||||||
identified are necessarily the best available for the purpose.
|
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.
|
||||||
|
|
||||||
|
This software and/or related materials are provided "AS-IS" without warranty
|
||||||
|
of any kind including NO WARRANTY OF PERFORMANCE, MERCHANTABILITY,
|
||||||
|
NO WARRANTY OF NON-INFRINGEMENT OF ANY 3RD PARTY INTELLECTUAL PROPERTY
|
||||||
|
or FITNESS FOR A PARTICULAR PURPOSE or for any purpose whatsoever, for the
|
||||||
|
licensed product, however used. In no event shall NIST be liable for any
|
||||||
|
damages and/or costs, including but not limited to incidental or consequential
|
||||||
|
damages of any kind, including economic damage or injury to property and lost
|
||||||
|
profits, regardless of whether NIST shall be advised, have reason to know,
|
||||||
|
or in fact shall know of the possibility.
|
||||||
|
|
||||||
|
By using this software, you agree to bear all risk relating to quality,
|
||||||
|
use and performance of the software and/or related materials. You agree
|
||||||
|
to hold the Government harmless from any claim arising from your use
|
||||||
|
of the software.
|
||||||
|
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
|
|
||||||
|
@ -91,23 +83,45 @@ int yl[ YL_SIZE_1 ][ YL_SIZE_2 ];
|
||||||
/**************************************************************************/
|
/**************************************************************************/
|
||||||
/* Globals used significantly by sift() */
|
/* Globals used significantly by sift() */
|
||||||
/**************************************************************************/
|
/**************************************************************************/
|
||||||
int rq[ RQ_SIZE ] = {};
|
#ifdef TARGET_OS
|
||||||
int tq[ TQ_SIZE ] = {};
|
int rq[ RQ_SIZE ];
|
||||||
int zz[ ZZ_SIZE ] = {};
|
int tq[ TQ_SIZE ];
|
||||||
|
int zz[ ZZ_SIZE ];
|
||||||
|
|
||||||
int rx[ RX_SIZE ] = {};
|
int rx[ RX_SIZE ];
|
||||||
int mm[ MM_SIZE ] = {};
|
int mm[ MM_SIZE ];
|
||||||
int nn[ NN_SIZE ] = {};
|
int nn[ NN_SIZE ];
|
||||||
|
|
||||||
int qq[ QQ_SIZE ] = {};
|
int qq[ QQ_SIZE ];
|
||||||
|
|
||||||
int rk[ RK_SIZE ] = {};
|
int rk[ RK_SIZE ];
|
||||||
|
|
||||||
int cp[ CP_SIZE ] = {};
|
int cp[ CP_SIZE ];
|
||||||
int rp[ RP_SIZE ] = {};
|
int rp[ RP_SIZE ];
|
||||||
|
|
||||||
int rf[RF_SIZE_1][RF_SIZE_2] = {};
|
int rf[RF_SIZE_1][RF_SIZE_2];
|
||||||
int cf[CF_SIZE_1][CF_SIZE_2] = {};
|
int cf[CF_SIZE_1][CF_SIZE_2];
|
||||||
|
|
||||||
int y[20000] = {};
|
int y[20000];
|
||||||
|
#else
|
||||||
|
int rq[ RQ_SIZE ] = {};
|
||||||
|
int tq[ TQ_SIZE ] = {};
|
||||||
|
int zz[ ZZ_SIZE ] = {};
|
||||||
|
|
||||||
|
int rx[ RX_SIZE ] = {};
|
||||||
|
int mm[ MM_SIZE ] = {};
|
||||||
|
int nn[ NN_SIZE ] = {};
|
||||||
|
|
||||||
|
int qq[ QQ_SIZE ] = {};
|
||||||
|
|
||||||
|
int rk[ RK_SIZE ] = {};
|
||||||
|
|
||||||
|
int cp[ CP_SIZE ] = {};
|
||||||
|
int rp[ RP_SIZE ] = {};
|
||||||
|
|
||||||
|
int rf[RF_SIZE_1][RF_SIZE_2] = {};
|
||||||
|
int cf[CF_SIZE_1][CF_SIZE_2] = {};
|
||||||
|
|
||||||
|
int y[20000] = {};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -1,51 +1,43 @@
|
||||||
/******************************************************************************
|
|
||||||
|
|
||||||
This file is part of the Export Control subset of the United States NIST
|
|
||||||
Biometric Image Software (NBIS) distribution:
|
|
||||||
http://fingerprint.nist.gov/NBIS/index.html
|
|
||||||
|
|
||||||
It is our understanding that this falls within ECCN 3D980, which covers
|
|
||||||
software associated with the development, production or use of certain
|
|
||||||
equipment controlled in accordance with U.S. concerns about crime control
|
|
||||||
practices in specific countries.
|
|
||||||
|
|
||||||
Therefore, this file should not be exported, or made available on fileservers,
|
|
||||||
except as allowed by U.S. export control laws.
|
|
||||||
|
|
||||||
Do not remove this notice.
|
|
||||||
|
|
||||||
******************************************************************************/
|
|
||||||
|
|
||||||
/* NOTE: Despite the above notice (which I have not removed), this file is
|
|
||||||
* being legally distributed within libfprint; the U.S. Export Administration
|
|
||||||
* Regulations do not place export restrictions upon distribution of
|
|
||||||
* "publicly available technology and software", as stated in EAR section
|
|
||||||
* 734.3(b)(3)(i). libfprint qualifies as publicly available technology as per
|
|
||||||
* the definition in section 734.7(a)(1).
|
|
||||||
*
|
|
||||||
* For further information, see https://fprint.freedesktop.org/us-export-control.html
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
|
|
||||||
License:
|
License:
|
||||||
This software was developed at the National Institute of Standards and
|
This software and/or related materials was developed at the National Institute
|
||||||
Technology (NIST) by employees of the Federal Government in the course
|
of Standards and Technology (NIST) by employees of the Federal Government
|
||||||
of their official duties. Pursuant to title 17 Section 105 of the
|
in the course of their official duties. Pursuant to title 17 Section 105
|
||||||
United States Code, this software is not subject to copyright protection
|
of the United States Code, this software is not subject to copyright
|
||||||
and is in the public domain. NIST assumes no responsibility whatsoever for
|
protection and is in the public domain.
|
||||||
its use by other parties, and makes no guarantees, expressed or implied,
|
|
||||||
about its quality, reliability, or any other characteristic.
|
|
||||||
|
|
||||||
Disclaimer:
|
This software and/or related materials have been determined to be not subject
|
||||||
This software was developed to promote biometric standards and biometric
|
to the EAR (see Part 734.3 of the EAR for exact details) because it is
|
||||||
technology testing for the Federal Government in accordance with the USA
|
a publicly available technology and software, and is freely distributed
|
||||||
PATRIOT Act and the Enhanced Border Security and Visa Entry Reform Act.
|
to any interested party with no licensing requirements. Therefore, it is
|
||||||
Specific hardware and software products identified in this software were used
|
permissible to distribute this software as a free download from the internet.
|
||||||
in order to perform the software development. In no case does such
|
|
||||||
identification imply recommendation or endorsement by the National Institute
|
Disclaimer:
|
||||||
of Standards and Technology, nor does it imply that the products and equipment
|
This software and/or related materials was developed to promote biometric
|
||||||
identified are necessarily the best available for the purpose.
|
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.
|
||||||
|
|
||||||
|
This software and/or related materials are provided "AS-IS" without warranty
|
||||||
|
of any kind including NO WARRANTY OF PERFORMANCE, MERCHANTABILITY,
|
||||||
|
NO WARRANTY OF NON-INFRINGEMENT OF ANY 3RD PARTY INTELLECTUAL PROPERTY
|
||||||
|
or FITNESS FOR A PARTICULAR PURPOSE or for any purpose whatsoever, for the
|
||||||
|
licensed product, however used. In no event shall NIST be liable for any
|
||||||
|
damages and/or costs, including but not limited to incidental or consequential
|
||||||
|
damages of any kind, including economic damage or injury to property and lost
|
||||||
|
profits, regardless of whether NIST shall be advised, have reason to know,
|
||||||
|
or in fact shall know of the possibility.
|
||||||
|
|
||||||
|
By using this software, you agree to bear all risk relating to quality,
|
||||||
|
use and performance of the software and/or related materials. You agree
|
||||||
|
to hold the Government harmless from any claim arising from your use
|
||||||
|
of the software.
|
||||||
|
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
|
|
||||||
|
@ -57,6 +49,9 @@ identified are necessarily the best available for the purpose.
|
||||||
MODIFICATIONS: Michael D. Garris (NIST)
|
MODIFICATIONS: Michael D. Garris (NIST)
|
||||||
Stan Janet (NIST)
|
Stan Janet (NIST)
|
||||||
DATE: 09/21/2004
|
DATE: 09/21/2004
|
||||||
|
UPDATED: 01/11/2012 by Kenneth Ko
|
||||||
|
UPDATED: 03/08/2012 by Kenneth Ko
|
||||||
|
UPDATED: 07/10/2014 by Kenneth Ko
|
||||||
|
|
||||||
Contains routines responsible for supporting command line
|
Contains routines responsible for supporting command line
|
||||||
processing, file and data input to, and output from the
|
processing, file and data input to, and output from the
|
||||||
|
@ -100,50 +95,7 @@ identified are necessarily the best available for the purpose.
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
#include <bozorth.h>
|
#include <bozorth.h>
|
||||||
|
|
||||||
static const int verbose_load = 0;
|
|
||||||
static const int verbose_main = 0;
|
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
int parse_line_range( const char * sb, int * begin, int * end )
|
|
||||||
{
|
|
||||||
int ib, ie;
|
|
||||||
char * se;
|
|
||||||
|
|
||||||
|
|
||||||
if ( ! isdigit(*sb) )
|
|
||||||
return -1;
|
|
||||||
ib = atoi( sb );
|
|
||||||
|
|
||||||
se = strchr( sb, '-' );
|
|
||||||
if ( se != (char *) NULL ) {
|
|
||||||
se++;
|
|
||||||
if ( ! isdigit(*se) )
|
|
||||||
return -2;
|
|
||||||
ie = atoi( se );
|
|
||||||
} else {
|
|
||||||
ie = ib;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( ib <= 0 ) {
|
|
||||||
if ( ie <= 0 ) {
|
|
||||||
return -3;
|
|
||||||
} else {
|
|
||||||
return -4;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( ie <= 0 ) {
|
|
||||||
return -5;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( ib > ie )
|
|
||||||
return -6;
|
|
||||||
|
|
||||||
*begin = ib;
|
|
||||||
*end = ie;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
|
|
||||||
|
@ -153,25 +105,10 @@ static char * pfile;
|
||||||
static char * gfile;
|
static char * gfile;
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
void set_progname( int use_pid, char * basename, pid_t pid )
|
|
||||||
{
|
|
||||||
if ( use_pid )
|
|
||||||
sprintf( program_buffer, "%s pid %ld", basename, (long) pid );
|
|
||||||
else
|
|
||||||
sprintf( program_buffer, "%s", basename );
|
|
||||||
}
|
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
void set_probe_filename( char * filename )
|
|
||||||
{
|
|
||||||
pfile = filename;
|
|
||||||
}
|
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
void set_gallery_filename( char * filename )
|
|
||||||
{
|
|
||||||
gfile = filename;
|
|
||||||
}
|
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
char * get_progname( void )
|
char * get_progname( void )
|
||||||
|
@ -192,171 +129,15 @@ return gfile;
|
||||||
}
|
}
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
char * get_next_file(
|
|
||||||
char * fixed_file,
|
|
||||||
FILE * list_fp,
|
|
||||||
FILE * mates_fp,
|
|
||||||
int * done_now,
|
|
||||||
int * done_afterwards,
|
|
||||||
char * line,
|
|
||||||
int argc,
|
|
||||||
char ** argv,
|
|
||||||
int * optind,
|
|
||||||
|
|
||||||
int * lineno,
|
|
||||||
int begin,
|
|
||||||
int end
|
|
||||||
)
|
|
||||||
{
|
|
||||||
char * p;
|
|
||||||
FILE * fp;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if ( fixed_file != (char *) NULL ) {
|
|
||||||
if ( verbose_main )
|
|
||||||
fprintf( stderr, "returning fixed filename: %s\n", fixed_file );
|
|
||||||
return fixed_file;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
fp = list_fp;
|
|
||||||
if ( fp == (FILE *) NULL )
|
|
||||||
fp = mates_fp;
|
|
||||||
if ( fp != (FILE *) NULL ) {
|
|
||||||
while (1) {
|
|
||||||
if ( fgets( line, MAX_LINE_LENGTH, fp ) == (char *) NULL ) {
|
|
||||||
*done_now = 1;
|
|
||||||
if ( verbose_main )
|
|
||||||
fprintf( stderr, "returning NULL -- reached EOF\n" );
|
|
||||||
return (char *) NULL;
|
|
||||||
}
|
|
||||||
++*lineno;
|
|
||||||
|
|
||||||
if ( begin <= 0 ) /* no line number range was specified */
|
|
||||||
break;
|
|
||||||
if ( *lineno > end ) {
|
|
||||||
*done_now = 1;
|
|
||||||
if ( verbose_main )
|
|
||||||
fprintf( stderr, "returning NULL -- current line (%d) > end line (%d)\n",
|
|
||||||
*lineno, end );
|
|
||||||
return (char *) NULL;
|
|
||||||
}
|
|
||||||
if ( *lineno >= begin ) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
/* Otherwise ( *lineno < begin ) so read another line */
|
|
||||||
}
|
|
||||||
|
|
||||||
p = strchr( line, '\n' );
|
|
||||||
if ( p == (char *) NULL ) {
|
|
||||||
*done_now = 1;
|
|
||||||
if ( verbose_main )
|
|
||||||
fprintf( stderr, "returning NULL -- missing newline character\n" );
|
|
||||||
return (char *) NULL;
|
|
||||||
}
|
|
||||||
*p = '\0';
|
|
||||||
|
|
||||||
p = line;
|
|
||||||
if ( verbose_main )
|
|
||||||
fprintf( stderr, "returning filename from next line: %s\n", p );
|
|
||||||
return p;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
p = argv[*optind];
|
|
||||||
++*optind;
|
|
||||||
if ( *optind >= argc )
|
|
||||||
*done_afterwards = 1;
|
|
||||||
if ( verbose_main )
|
|
||||||
fprintf( stderr, "returning next argv: %s [done_afterwards=%d]\n", p, *done_afterwards );
|
|
||||||
return p;
|
|
||||||
}
|
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
/* returns CNULL on error */
|
/* returns CNULL on error */
|
||||||
char * get_score_filename( const char * outdir, const char * listfile )
|
|
||||||
{
|
|
||||||
const char * basename;
|
|
||||||
int baselen;
|
|
||||||
int dirlen;
|
|
||||||
int extlen;
|
|
||||||
char * outfile;
|
|
||||||
|
|
||||||
/* These are now exteranlly defined in bozorth.h */
|
|
||||||
/* extern FILE * stderr; */
|
|
||||||
/* extern char * get_progname( void ); */
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
basename = strrchr( listfile, '/' );
|
|
||||||
if ( basename == CNULL ) {
|
|
||||||
basename = listfile;
|
|
||||||
} else {
|
|
||||||
++basename;
|
|
||||||
}
|
|
||||||
baselen = strlen( basename );
|
|
||||||
if ( baselen == 0 ) {
|
|
||||||
fprintf( stderr, "%s: ERROR: couldn't find basename of %s\n", get_progname(), listfile );
|
|
||||||
return(CNULL);
|
|
||||||
}
|
|
||||||
dirlen = strlen( outdir );
|
|
||||||
if ( dirlen == 0 ) {
|
|
||||||
fprintf( stderr, "%s: ERROR: illegal output directory %s\n", get_progname(), outdir );
|
|
||||||
return(CNULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
extlen = strlen( SCOREFILE_EXTENSION );
|
|
||||||
outfile = malloc_or_return_error( dirlen + baselen + extlen + 2, "output filename" );
|
|
||||||
if ( outfile == CNULL)
|
|
||||||
return(CNULL);
|
|
||||||
|
|
||||||
sprintf( outfile, "%s/%s%s", outdir, basename, SCOREFILE_EXTENSION );
|
|
||||||
|
|
||||||
return outfile;
|
|
||||||
}
|
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
char * get_score_line(
|
|
||||||
const char * probe_file,
|
|
||||||
const char * gallery_file,
|
|
||||||
int n,
|
|
||||||
int static_flag,
|
|
||||||
const char * fmt
|
|
||||||
)
|
|
||||||
{
|
|
||||||
int nchars;
|
|
||||||
char * bufptr;
|
|
||||||
static char linebuf[1024];
|
|
||||||
|
|
||||||
nchars = 0;
|
|
||||||
bufptr = &linebuf[0];
|
|
||||||
while ( *fmt ) {
|
|
||||||
if ( nchars++ > 0 )
|
|
||||||
*bufptr++ = ' ';
|
|
||||||
switch ( *fmt++ ) {
|
|
||||||
case 's':
|
|
||||||
sprintf( bufptr, "%d", n );
|
|
||||||
break;
|
|
||||||
case 'p':
|
|
||||||
sprintf( bufptr, "%s", probe_file );
|
|
||||||
break;
|
|
||||||
case 'g':
|
|
||||||
sprintf( bufptr, "%s", gallery_file );
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return (char *) NULL;
|
|
||||||
}
|
|
||||||
bufptr = strchr( bufptr, '\0' );
|
|
||||||
}
|
|
||||||
*bufptr++ = '\n';
|
|
||||||
*bufptr = '\0';
|
|
||||||
|
|
||||||
return static_flag ? &linebuf[0] : strdup( linebuf );
|
|
||||||
}
|
|
||||||
|
|
||||||
/************************************************************************
|
/************************************************************************
|
||||||
Load a 3-4 column (X,Y,T[,Q]) set of minutiae from the specified file.
|
Load a 3-4 column (X,Y,T[,Q]) set of minutiae from the specified file
|
||||||
|
and return a XYT sturcture.
|
||||||
Row 3's value is an angle which is normalized to the interval (-180,180].
|
Row 3's value is an angle which is normalized to the interval (-180,180].
|
||||||
A maximum of MAX_BOZORTH_MINUTIAE minutiae can be returned -- fewer if
|
A maximum of MAX_BOZORTH_MINUTIAE minutiae can be returned -- fewer if
|
||||||
"DEFAULT_BOZORTH_MINUTIAE" is smaller. If the file contains more minutiae than are
|
"DEFAULT_BOZORTH_MINUTIAE" is smaller. If the file contains more minutiae than are
|
||||||
|
@ -364,241 +145,14 @@ to be returned, the highest-quality minutiae are returned.
|
||||||
*************************************************************************/
|
*************************************************************************/
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
struct xyt_struct * bz_load( const char * xyt_file )
|
|
||||||
{
|
|
||||||
int nminutiae;
|
|
||||||
int j;
|
|
||||||
int m;
|
|
||||||
int nargs_expected;
|
|
||||||
FILE * fp;
|
|
||||||
struct xyt_struct * s;
|
|
||||||
int * xptr;
|
|
||||||
int * yptr;
|
|
||||||
int * tptr;
|
|
||||||
int * qptr;
|
|
||||||
struct minutiae_struct c[MAX_FILE_MINUTIAE];
|
|
||||||
int xvals_lng[MAX_FILE_MINUTIAE], /* Temporary lists to store all the minutaie from a file */
|
|
||||||
yvals_lng[MAX_FILE_MINUTIAE],
|
|
||||||
tvals_lng[MAX_FILE_MINUTIAE],
|
|
||||||
qvals_lng[MAX_FILE_MINUTIAE];
|
|
||||||
int order[MAX_FILE_MINUTIAE]; /* The ranked order, after sort, for each index */
|
|
||||||
int xvals[MAX_BOZORTH_MINUTIAE], /* Temporary lists to hold input coordinates */
|
|
||||||
yvals[MAX_BOZORTH_MINUTIAE],
|
|
||||||
tvals[MAX_BOZORTH_MINUTIAE],
|
|
||||||
qvals[MAX_BOZORTH_MINUTIAE];
|
|
||||||
char xyt_line[ MAX_LINE_LENGTH ];
|
|
||||||
|
|
||||||
/* This is now externally defined in bozorth.h */
|
/************************************************************************
|
||||||
/* extern FILE * stderr; */
|
Load a XYTQ structure and return a XYT struct.
|
||||||
|
Row 3's value is an angle which is normalized to the interval (-180,180].
|
||||||
|
A maximum of MAX_BOZORTH_MINUTIAE minutiae can be returned -- fewer if
|
||||||
|
"DEFAULT_BOZORTH_MINUTIAE" is smaller. If the file contains more minutiae than are
|
||||||
#define C1 0
|
to be returned, the highest-quality minutiae are returned.
|
||||||
#define C2 1
|
*************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
fp = fopen( xyt_file, "r" );
|
|
||||||
if ( fp == (FILE *) NULL ) {
|
|
||||||
fprintf( stderr, "%s: ERROR: fopen() of minutiae file \"%s\" failed: %s\n",
|
|
||||||
get_progname(), xyt_file, strerror(errno) );
|
|
||||||
return XYT_NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
nminutiae = 0;
|
|
||||||
nargs_expected = 0;
|
|
||||||
while ( fgets( xyt_line, sizeof xyt_line, fp ) != CNULL ) {
|
|
||||||
|
|
||||||
m = sscanf( xyt_line, "%d %d %d %d",
|
|
||||||
&xvals_lng[nminutiae],
|
|
||||||
&yvals_lng[nminutiae],
|
|
||||||
&tvals_lng[nminutiae],
|
|
||||||
&qvals_lng[nminutiae] );
|
|
||||||
if ( nminutiae == 0 ) {
|
|
||||||
if ( m != 3 && m != 4 ) {
|
|
||||||
fprintf( stderr, "%s: ERROR: sscanf() failed on line %u in minutiae file \"%s\"\n",
|
|
||||||
get_progname(), nminutiae+1, xyt_file );
|
|
||||||
return XYT_NULL;
|
|
||||||
}
|
|
||||||
nargs_expected = m;
|
|
||||||
} else {
|
|
||||||
if ( m != nargs_expected ) {
|
|
||||||
fprintf( stderr, "%s: ERROR: inconsistent argument count on line %u of minutiae file \"%s\"\n",
|
|
||||||
get_progname(), nminutiae+1, xyt_file );
|
|
||||||
return XYT_NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ( m == 3 )
|
|
||||||
qvals_lng[nminutiae] = 1;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if ( tvals_lng[nminutiae] > 180 )
|
|
||||||
tvals_lng[nminutiae] -= 360;
|
|
||||||
|
|
||||||
/*
|
|
||||||
if ( C1 ) {
|
|
||||||
c[nminutiae].col[0] = xvals_lng[nminutiae];
|
|
||||||
c[nminutiae].col[1] = yvals_lng[nminutiae];
|
|
||||||
c[nminutiae].col[2] = tvals_lng[nminutiae];
|
|
||||||
c[nminutiae].col[3] = qvals_lng[nminutiae];
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
++nminutiae;
|
|
||||||
if ( nminutiae == MAX_FILE_MINUTIAE )
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( fclose(fp) != 0 ) {
|
|
||||||
fprintf( stderr, "%s: ERROR: fclose() of minutiae file \"%s\" failed: %s\n",
|
|
||||||
get_progname(), xyt_file, strerror(errno) );
|
|
||||||
return XYT_NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if ( nminutiae > DEFAULT_BOZORTH_MINUTIAE ) {
|
|
||||||
if ( verbose_load )
|
|
||||||
fprintf( stderr, "%s: WARNING: bz_load(): trimming minutiae to the %d of highest quality\n",
|
|
||||||
get_progname(), DEFAULT_BOZORTH_MINUTIAE );
|
|
||||||
|
|
||||||
if ( verbose_load )
|
|
||||||
fprintf( stderr, "Before quality sort:\n" );
|
|
||||||
if ( sort_order_decreasing( qvals_lng, nminutiae, order )) {
|
|
||||||
fprintf( stderr, "%s: ERROR: sort failed and returned on error\n", get_progname());
|
|
||||||
return XYT_NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
for ( j = 0; j < nminutiae; j++ ) {
|
|
||||||
|
|
||||||
if ( verbose_load )
|
|
||||||
fprintf( stderr, " %3d: %3d %3d %3d ---> order = %3d\n",
|
|
||||||
j, xvals_lng[j], yvals_lng[j], qvals_lng[j], order[j] );
|
|
||||||
|
|
||||||
if ( j == 0 )
|
|
||||||
continue;
|
|
||||||
if ( qvals_lng[order[j]] > qvals_lng[order[j-1]] ) {
|
|
||||||
fprintf( stderr, "%s: ERROR: sort failed: j=%d; qvals_lng[%d] > qvals_lng[%d]\n",
|
|
||||||
get_progname(), j, order[j], order[j-1] );
|
|
||||||
return XYT_NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if ( verbose_load )
|
|
||||||
fprintf( stderr, "\nAfter quality sort:\n" );
|
|
||||||
for ( j = 0; j < DEFAULT_BOZORTH_MINUTIAE; j++ ) {
|
|
||||||
xvals[j] = xvals_lng[order[j]];
|
|
||||||
yvals[j] = yvals_lng[order[j]];
|
|
||||||
tvals[j] = tvals_lng[order[j]];
|
|
||||||
qvals[j] = qvals_lng[order[j]];
|
|
||||||
if ( verbose_load )
|
|
||||||
fprintf( stderr, " %3d: %3d %3d %3d\n", j, xvals[j], yvals[j], qvals[j] );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if ( C1 ) {
|
|
||||||
if ( verbose_load )
|
|
||||||
fprintf( stderr, "\nAfter qsort():\n" );
|
|
||||||
qsort( (void *) &c, (size_t) nminutiae, sizeof(struct minutiae_struct), sort_quality_decreasing );
|
|
||||||
for ( j = 0; j < nminutiae; j++ ) {
|
|
||||||
|
|
||||||
if ( verbose_load )
|
|
||||||
fprintf( stderr, "Q %3d: %3d %3d %3d\n",
|
|
||||||
j, c[j].col[0], c[j].col[1], c[j].col[3] );
|
|
||||||
|
|
||||||
if ( j > 0 && c[j].col[3] > c[j-1].col[3] ) {
|
|
||||||
fprintf( stderr, "%s: ERROR: sort failed: c[%d].col[3] > c[%d].col[3]\n",
|
|
||||||
get_progname(), j, j-1 );
|
|
||||||
return XYT_NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( verbose_load )
|
|
||||||
fprintf( stderr, "\n" );
|
|
||||||
|
|
||||||
xptr = xvals;
|
|
||||||
yptr = yvals;
|
|
||||||
tptr = tvals;
|
|
||||||
qptr = qvals;
|
|
||||||
|
|
||||||
nminutiae = DEFAULT_BOZORTH_MINUTIAE;
|
|
||||||
} else{
|
|
||||||
xptr = xvals_lng;
|
|
||||||
yptr = yvals_lng;
|
|
||||||
tptr = tvals_lng;
|
|
||||||
qptr = qvals_lng;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
for ( j=0; j < nminutiae; j++ ) {
|
|
||||||
c[j].col[0] = xptr[j];
|
|
||||||
c[j].col[1] = yptr[j];
|
|
||||||
c[j].col[2] = tptr[j];
|
|
||||||
c[j].col[3] = qptr[j];
|
|
||||||
}
|
|
||||||
qsort( (void *) &c, (size_t) nminutiae, sizeof(struct minutiae_struct), sort_x_y );
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if ( verbose_load ) {
|
|
||||||
fprintf( stderr, "\nSorted on increasing x, then increasing y\n" );
|
|
||||||
for ( j = 0; j < nminutiae; j++ ) {
|
|
||||||
fprintf( stderr, "%d : %3d, %3d, %3d, %3d\n", j, c[j].col[0], c[j].col[1], c[j].col[2], c[j].col[3] );
|
|
||||||
if ( j > 0 ) {
|
|
||||||
if ( c[j].col[0] < c[j-1].col[0] ) {
|
|
||||||
fprintf( stderr, "%s: ERROR: sort failed: c[%d].col[0]=%d > c[%d].col[0]=%d\n",
|
|
||||||
get_progname(),
|
|
||||||
j, c[j].col[0], j-1, c[j-1].col[0]
|
|
||||||
);
|
|
||||||
return XYT_NULL;
|
|
||||||
}
|
|
||||||
if ( c[j].col[0] == c[j-1].col[0] && c[j].col[1] < c[j-1].col[1] ) {
|
|
||||||
fprintf( stderr, "%s: ERROR: sort failed: c[%d].col[0]=%d == c[%d].col[0]=%d; c[%d].col[0]=%d == c[%d].col[0]=%d\n",
|
|
||||||
get_progname(),
|
|
||||||
j, c[j].col[0], j-1, c[j-1].col[0],
|
|
||||||
j, c[j].col[1], j-1, c[j-1].col[1]
|
|
||||||
);
|
|
||||||
return XYT_NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
s = (struct xyt_struct *) malloc( sizeof( struct xyt_struct ) );
|
|
||||||
if ( s == XYT_NULL ) {
|
|
||||||
fprintf( stderr, "%s: ERROR: malloc() failure while loading minutiae file \"%s\" failed: %s\n",
|
|
||||||
get_progname(),
|
|
||||||
xyt_file,
|
|
||||||
strerror(errno)
|
|
||||||
);
|
|
||||||
return XYT_NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
for ( j = 0; j < nminutiae; j++ ) {
|
|
||||||
s->xcol[j] = c[j].col[0];
|
|
||||||
s->ycol[j] = c[j].col[1];
|
|
||||||
s->thetacol[j] = c[j].col[2];
|
|
||||||
}
|
|
||||||
s->nrows = nminutiae;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if ( verbose_load )
|
|
||||||
fprintf( stderr, "Loaded %s\n", xyt_file );
|
|
||||||
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
#ifdef PARALLEL_SEARCH
|
#ifdef PARALLEL_SEARCH
|
||||||
|
@ -617,13 +171,13 @@ tv.tv_usec = 0;
|
||||||
retval = select( fd+1, &rfds, NULL, NULL, &tv );
|
retval = select( fd+1, &rfds, NULL, NULL, &tv );
|
||||||
|
|
||||||
if ( retval < 0 ) {
|
if ( retval < 0 ) {
|
||||||
perror( "select() failed" );
|
perror( "select() failed" );
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( FD_ISSET( fd, &rfds ) ) {
|
if ( FD_ISSET( fd, &rfds ) ) {
|
||||||
/*fprintf( stderr, "data is available now.\n" );*/
|
/*fprintf( stderr, "data is available now.\n" );*/
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* fprintf( stderr, "no data is available\n" ); */
|
/* fprintf( stderr, "no data is available\n" ); */
|
||||||
|
|
|
@ -1,51 +1,43 @@
|
||||||
/******************************************************************************
|
|
||||||
|
|
||||||
This file is part of the Export Control subset of the United States NIST
|
|
||||||
Biometric Image Software (NBIS) distribution:
|
|
||||||
http://fingerprint.nist.gov/NBIS/index.html
|
|
||||||
|
|
||||||
It is our understanding that this falls within ECCN 3D980, which covers
|
|
||||||
software associated with the development, production or use of certain
|
|
||||||
equipment controlled in accordance with U.S. concerns about crime control
|
|
||||||
practices in specific countries.
|
|
||||||
|
|
||||||
Therefore, this file should not be exported, or made available on fileservers,
|
|
||||||
except as allowed by U.S. export control laws.
|
|
||||||
|
|
||||||
Do not remove this notice.
|
|
||||||
|
|
||||||
******************************************************************************/
|
|
||||||
|
|
||||||
/* NOTE: Despite the above notice (which I have not removed), this file is
|
|
||||||
* being legally distributed within libfprint; the U.S. Export Administration
|
|
||||||
* Regulations do not place export restrictions upon distribution of
|
|
||||||
* "publicly available technology and software", as stated in EAR section
|
|
||||||
* 734.3(b)(3)(i). libfprint qualifies as publicly available technology as per
|
|
||||||
* the definition in section 734.7(a)(1).
|
|
||||||
*
|
|
||||||
* For further information, see https://fprint.freedesktop.org/us-export-control.html
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
|
|
||||||
License:
|
License:
|
||||||
This software was developed at the National Institute of Standards and
|
This software and/or related materials was developed at the National Institute
|
||||||
Technology (NIST) by employees of the Federal Government in the course
|
of Standards and Technology (NIST) by employees of the Federal Government
|
||||||
of their official duties. Pursuant to title 17 Section 105 of the
|
in the course of their official duties. Pursuant to title 17 Section 105
|
||||||
United States Code, this software is not subject to copyright protection
|
of the United States Code, this software is not subject to copyright
|
||||||
and is in the public domain. NIST assumes no responsibility whatsoever for
|
protection and is in the public domain.
|
||||||
its use by other parties, and makes no guarantees, expressed or implied,
|
|
||||||
about its quality, reliability, or any other characteristic.
|
|
||||||
|
|
||||||
Disclaimer:
|
This software and/or related materials have been determined to be not subject
|
||||||
This software was developed to promote biometric standards and biometric
|
to the EAR (see Part 734.3 of the EAR for exact details) because it is
|
||||||
technology testing for the Federal Government in accordance with the USA
|
a publicly available technology and software, and is freely distributed
|
||||||
PATRIOT Act and the Enhanced Border Security and Visa Entry Reform Act.
|
to any interested party with no licensing requirements. Therefore, it is
|
||||||
Specific hardware and software products identified in this software were used
|
permissible to distribute this software as a free download from the internet.
|
||||||
in order to perform the software development. In no case does such
|
|
||||||
identification imply recommendation or endorsement by the National Institute
|
Disclaimer:
|
||||||
of Standards and Technology, nor does it imply that the products and equipment
|
This software and/or related materials was developed to promote biometric
|
||||||
identified are necessarily the best available for the purpose.
|
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.
|
||||||
|
|
||||||
|
This software and/or related materials are provided "AS-IS" without warranty
|
||||||
|
of any kind including NO WARRANTY OF PERFORMANCE, MERCHANTABILITY,
|
||||||
|
NO WARRANTY OF NON-INFRINGEMENT OF ANY 3RD PARTY INTELLECTUAL PROPERTY
|
||||||
|
or FITNESS FOR A PARTICULAR PURPOSE or for any purpose whatsoever, for the
|
||||||
|
licensed product, however used. In no event shall NIST be liable for any
|
||||||
|
damages and/or costs, including but not limited to incidental or consequential
|
||||||
|
damages of any kind, including economic damage or injury to property and lost
|
||||||
|
profits, regardless of whether NIST shall be advised, have reason to know,
|
||||||
|
or in fact shall know of the possibility.
|
||||||
|
|
||||||
|
By using this software, you agree to bear all risk relating to quality,
|
||||||
|
use and performance of the software and/or related materials. You agree
|
||||||
|
to hold the Government harmless from any claim arising from your use
|
||||||
|
of the software.
|
||||||
|
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
|
|
||||||
|
@ -78,23 +70,10 @@ identified are necessarily the best available for the purpose.
|
||||||
#include <bozorth.h>
|
#include <bozorth.h>
|
||||||
|
|
||||||
/* These are now externally defined in bozorth.h */
|
/* These are now externally defined in bozorth.h */
|
||||||
|
/* extern FILE * stderr; */
|
||||||
/* extern char * get_progname( void ); */
|
/* extern char * get_progname( void ); */
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
int sort_quality_decreasing( const void * a, const void * b )
|
|
||||||
{
|
|
||||||
struct minutiae_struct * af;
|
|
||||||
struct minutiae_struct * bf;
|
|
||||||
|
|
||||||
af = (struct minutiae_struct *) a;
|
|
||||||
bf = (struct minutiae_struct *) b;
|
|
||||||
|
|
||||||
if ( af->col[3] > bf->col[3] )
|
|
||||||
return -1;
|
|
||||||
if ( af->col[3] < bf->col[3] )
|
|
||||||
return 1;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
int sort_x_y( const void * a, const void * b )
|
int sort_x_y( const void * a, const void * b )
|
||||||
|
@ -124,67 +103,18 @@ qsort_decreasing() - quicksort an array of integers in decreasing
|
||||||
and Ted Zwiesler, 1986]
|
and Ted Zwiesler, 1986]
|
||||||
********************************************************/
|
********************************************************/
|
||||||
/* Used by custom quicksort code below */
|
/* Used by custom quicksort code below */
|
||||||
static int stack[BZ_STACKSIZE];
|
|
||||||
static int * stack_pointer = stack;
|
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
/* return values: 0 == successful, 1 == error */
|
/* return values: 0 == successful, 1 == error */
|
||||||
static int popstack( int *popval )
|
|
||||||
{
|
|
||||||
if ( --stack_pointer < stack ) {
|
|
||||||
fprintf( stderr, "%s: ERROR: popstack(): stack underflow\n", get_progname() );
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
*popval = *stack_pointer;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
/* return values: 0 == successful, 1 == error */
|
/* return values: 0 == successful, 1 == error */
|
||||||
static int pushstack( int position )
|
|
||||||
{
|
|
||||||
*stack_pointer++ = position;
|
|
||||||
if ( stack_pointer > ( stack + BZ_STACKSIZE ) ) {
|
|
||||||
fprintf( stderr, "%s: ERROR: pushstack(): stack overflow\n", get_progname() );
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
/*******************************************************************
|
/*******************************************************************
|
||||||
select_pivot()
|
select_pivot()
|
||||||
selects a pivot from a list being sorted using the Singleton Method.
|
selects a pivot from a list being sorted using the Singleton Method.
|
||||||
*******************************************************************/
|
*******************************************************************/
|
||||||
static int select_pivot( struct cell v[], int left, int right )
|
|
||||||
{
|
|
||||||
int midpoint;
|
|
||||||
|
|
||||||
|
|
||||||
midpoint = ( left + right ) / 2;
|
|
||||||
if ( v[left].index <= v[midpoint].index ) {
|
|
||||||
if ( v[midpoint].index <= v[right].index ) {
|
|
||||||
return midpoint;
|
|
||||||
} else {
|
|
||||||
if ( v[right].index > v[left].index ) {
|
|
||||||
return right;
|
|
||||||
} else {
|
|
||||||
return left;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if ( v[left].index < v[right].index ) {
|
|
||||||
return left;
|
|
||||||
} else {
|
|
||||||
if ( v[right].index < v[midpoint].index ) {
|
|
||||||
return midpoint;
|
|
||||||
} else {
|
|
||||||
return right;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
/********************************************************
|
/********************************************************
|
||||||
|
@ -192,41 +122,6 @@ partition_dec()
|
||||||
Inputs a pivot element making comparisons and swaps with other elements in a list,
|
Inputs a pivot element making comparisons and swaps with other elements in a list,
|
||||||
until pivot resides at its correct position in the list.
|
until pivot resides at its correct position in the list.
|
||||||
********************************************************/
|
********************************************************/
|
||||||
static void partition_dec( struct cell v[], int *llen, int *rlen, int *ll, int *lr, int *rl, int *rr, int p, int l, int r )
|
|
||||||
{
|
|
||||||
#define iswap(a,b) { int itmp = (a); a = (b); b = itmp; }
|
|
||||||
|
|
||||||
*ll = l;
|
|
||||||
*rr = r;
|
|
||||||
while ( 1 ) {
|
|
||||||
if ( l < p ) {
|
|
||||||
if ( v[l].index < v[p].index ) {
|
|
||||||
iswap( v[l].index, v[p].index )
|
|
||||||
iswap( v[l].item, v[p].item )
|
|
||||||
p = l;
|
|
||||||
} else {
|
|
||||||
l++;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if ( r > p ) {
|
|
||||||
if ( v[r].index > v[p].index ) {
|
|
||||||
iswap( v[r].index, v[p].index )
|
|
||||||
iswap( v[r].item, v[p].item )
|
|
||||||
p = r;
|
|
||||||
l++;
|
|
||||||
} else {
|
|
||||||
r--;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
*lr = p - 1;
|
|
||||||
*rl = p + 1;
|
|
||||||
*llen = *lr - *ll + 1;
|
|
||||||
*rlen = *rr - *rl + 1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
/********************************************************
|
/********************************************************
|
||||||
|
@ -236,80 +131,6 @@ sorted, a left subscript pointing to where the sort is to begin in the index ar
|
||||||
subscript where to end. This module invokes a decreasing quick-sort sorting the index array from l to r.
|
subscript where to end. This module invokes a decreasing quick-sort sorting the index array from l to r.
|
||||||
********************************************************/
|
********************************************************/
|
||||||
/* return values: 0 == successful, 1 == error */
|
/* return values: 0 == successful, 1 == error */
|
||||||
static int qsort_decreasing( struct cell v[], int left, int right )
|
|
||||||
{
|
|
||||||
int pivot;
|
|
||||||
int llen, rlen;
|
|
||||||
int lleft, lright, rleft, rright;
|
|
||||||
|
|
||||||
|
|
||||||
if ( pushstack( left ))
|
|
||||||
return 1;
|
|
||||||
if ( pushstack( right ))
|
|
||||||
return 2;
|
|
||||||
while ( stack_pointer != stack ) {
|
|
||||||
if (popstack(&right))
|
|
||||||
return 3;
|
|
||||||
if (popstack(&left ))
|
|
||||||
return 4;
|
|
||||||
if ( right - left > 0 ) {
|
|
||||||
pivot = select_pivot( v, left, right );
|
|
||||||
partition_dec( v, &llen, &rlen, &lleft, &lright, &rleft, &rright, pivot, left, right );
|
|
||||||
if ( llen > rlen ) {
|
|
||||||
if ( pushstack( lleft ))
|
|
||||||
return 5;
|
|
||||||
if ( pushstack( lright ))
|
|
||||||
return 6;
|
|
||||||
if ( pushstack( rleft ))
|
|
||||||
return 7;
|
|
||||||
if ( pushstack( rright ))
|
|
||||||
return 8;
|
|
||||||
} else{
|
|
||||||
if ( pushstack( rleft ))
|
|
||||||
return 9;
|
|
||||||
if ( pushstack( rright ))
|
|
||||||
return 10;
|
|
||||||
if ( pushstack( lleft ))
|
|
||||||
return 11;
|
|
||||||
if ( pushstack( lright ))
|
|
||||||
return 12;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
/* return values: 0 == successful, 1 == error */
|
/* return values: 0 == successful, 1 == error */
|
||||||
int sort_order_decreasing(
|
|
||||||
int values[], /* INPUT: the unsorted values themselves */
|
|
||||||
int num, /* INPUT: the number of values */
|
|
||||||
int order[] /* OUTPUT: the order for each of the values if sorted */
|
|
||||||
)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
struct cell * cells;
|
|
||||||
|
|
||||||
|
|
||||||
cells = (struct cell *) malloc( num * sizeof(struct cell) );
|
|
||||||
if ( cells == (struct cell *) NULL ){
|
|
||||||
fprintf( stderr, "%s: ERROR: malloc(): struct cell\n", get_progname() );
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
for( i = 0; i < num; i++ ) {
|
|
||||||
cells[i].index = values[i];
|
|
||||||
cells[i].item = i;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( qsort_decreasing( cells, 0, num-1 ) < 0)
|
|
||||||
return 2;
|
|
||||||
|
|
||||||
for( i = 0; i < num; i++ ) {
|
|
||||||
order[i] = cells[i].item;
|
|
||||||
}
|
|
||||||
|
|
||||||
free( (void *) cells );
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,23 +1,43 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
|
|
||||||
License:
|
License:
|
||||||
This software was developed at the National Institute of Standards and
|
This software and/or related materials was developed at the National Institute
|
||||||
Technology (NIST) by employees of the Federal Government in the course
|
of Standards and Technology (NIST) by employees of the Federal Government
|
||||||
of their official duties. Pursuant to title 17 Section 105 of the
|
in the course of their official duties. Pursuant to title 17 Section 105
|
||||||
United States Code, this software is not subject to copyright protection
|
of the United States Code, this software is not subject to copyright
|
||||||
and is in the public domain. NIST assumes no responsibility whatsoever for
|
protection and is in the public domain.
|
||||||
its use by other parties, and makes no guarantees, expressed or implied,
|
|
||||||
about its quality, reliability, or any other characteristic.
|
|
||||||
|
|
||||||
Disclaimer:
|
This software and/or related materials have been determined to be not subject
|
||||||
This software was developed to promote biometric standards and biometric
|
to the EAR (see Part 734.3 of the EAR for exact details) because it is
|
||||||
technology testing for the Federal Government in accordance with the USA
|
a publicly available technology and software, and is freely distributed
|
||||||
PATRIOT Act and the Enhanced Border Security and Visa Entry Reform Act.
|
to any interested party with no licensing requirements. Therefore, it is
|
||||||
Specific hardware and software products identified in this software were used
|
permissible to distribute this software as a free download from the internet.
|
||||||
in order to perform the software development. In no case does such
|
|
||||||
identification imply recommendation or endorsement by the National Institute
|
Disclaimer:
|
||||||
of Standards and Technology, nor does it imply that the products and equipment
|
This software and/or related materials was developed to promote biometric
|
||||||
identified are necessarily the best available for the purpose.
|
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.
|
||||||
|
|
||||||
|
This software and/or related materials are provided "AS-IS" without warranty
|
||||||
|
of any kind including NO WARRANTY OF PERFORMANCE, MERCHANTABILITY,
|
||||||
|
NO WARRANTY OF NON-INFRINGEMENT OF ANY 3RD PARTY INTELLECTUAL PROPERTY
|
||||||
|
or FITNESS FOR A PARTICULAR PURPOSE or for any purpose whatsoever, for the
|
||||||
|
licensed product, however used. In no event shall NIST be liable for any
|
||||||
|
damages and/or costs, including but not limited to incidental or consequential
|
||||||
|
damages of any kind, including economic damage or injury to property and lost
|
||||||
|
profits, regardless of whether NIST shall be advised, have reason to know,
|
||||||
|
or in fact shall know of the possibility.
|
||||||
|
|
||||||
|
By using this software, you agree to bear all risk relating to quality,
|
||||||
|
use and performance of the software and/or related materials. You agree
|
||||||
|
to hold the Government harmless from any claim arising from your use
|
||||||
|
of the software.
|
||||||
|
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
|
|
||||||
|
@ -163,7 +183,7 @@ struct cell {
|
||||||
};
|
};
|
||||||
|
|
||||||
/**************************************************************************/
|
/**************************************************************************/
|
||||||
/* In BZ_IO : Supports the loading and manipulation of XYT data */
|
/* In BZ_IO : Supports the loading and manipulation of XYT and XYTQ data */
|
||||||
/**************************************************************************/
|
/**************************************************************************/
|
||||||
#define MAX_FILE_MINUTIAE 1000 /* bz_load() */
|
#define MAX_FILE_MINUTIAE 1000 /* bz_load() */
|
||||||
|
|
||||||
|
@ -174,7 +194,17 @@ struct xyt_struct {
|
||||||
int thetacol[ MAX_BOZORTH_MINUTIAE ];
|
int thetacol[ MAX_BOZORTH_MINUTIAE ];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct xytq_struct {
|
||||||
|
int nrows;
|
||||||
|
int xcol[ MAX_FILE_MINUTIAE ];
|
||||||
|
int ycol[ MAX_FILE_MINUTIAE ];
|
||||||
|
int thetacol[ MAX_FILE_MINUTIAE ];
|
||||||
|
int qualitycol[ MAX_FILE_MINUTIAE ];
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
#define XYT_NULL ( (struct xyt_struct *) NULL ) /* bz_load() */
|
#define XYT_NULL ( (struct xyt_struct *) NULL ) /* bz_load() */
|
||||||
|
#define XYTQ_NULL ( (struct xytq_struct *) NULL ) /* bz_load() */
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************/
|
/**************************************************************************/
|
||||||
|
@ -187,6 +217,8 @@ struct xyt_struct {
|
||||||
/**************************************************************************/
|
/**************************************************************************/
|
||||||
/* Globals supporting command line options */
|
/* Globals supporting command line options */
|
||||||
extern int verbose_threshold;
|
extern int verbose_threshold;
|
||||||
|
/* Global supporting error reporting */
|
||||||
|
extern FILE *stderr;
|
||||||
|
|
||||||
/**************************************************************************/
|
/**************************************************************************/
|
||||||
/* In: BZ_GBLS.C */
|
/* In: BZ_GBLS.C */
|
||||||
|
@ -247,6 +279,7 @@ extern char *get_next_file(char *, FILE *, FILE *, int *, int *, char *,
|
||||||
extern char *get_score_filename(const char *, const char *);
|
extern char *get_score_filename(const char *, const char *);
|
||||||
extern char *get_score_line(const char *, const char *, int, int, const char *);
|
extern char *get_score_line(const char *, const char *, int, int, const char *);
|
||||||
extern struct xyt_struct *bz_load(const char *);
|
extern struct xyt_struct *bz_load(const char *);
|
||||||
|
extern struct xyt_struct *bz_prune(struct xytq_struct *, int);
|
||||||
extern int fd_readable(int);
|
extern int fd_readable(int);
|
||||||
/* In: BZ_SORT.C */
|
/* In: BZ_SORT.C */
|
||||||
extern int sort_quality_decreasing(const void *, const void *);
|
extern int sort_quality_decreasing(const void *, const void *);
|
||||||
|
|
|
@ -1,23 +1,43 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
|
|
||||||
License:
|
License:
|
||||||
This software was developed at the National Institute of Standards and
|
This software and/or related materials was developed at the National Institute
|
||||||
Technology (NIST) by employees of the Federal Government in the course
|
of Standards and Technology (NIST) by employees of the Federal Government
|
||||||
of their official duties. Pursuant to title 17 Section 105 of the
|
in the course of their official duties. Pursuant to title 17 Section 105
|
||||||
United States Code, this software is not subject to copyright protection
|
of the United States Code, this software is not subject to copyright
|
||||||
and is in the public domain. NIST assumes no responsibility whatsoever for
|
protection and is in the public domain.
|
||||||
its use by other parties, and makes no guarantees, expressed or implied,
|
|
||||||
about its quality, reliability, or any other characteristic.
|
|
||||||
|
|
||||||
Disclaimer:
|
This software and/or related materials have been determined to be not subject
|
||||||
This software was developed to promote biometric standards and biometric
|
to the EAR (see Part 734.3 of the EAR for exact details) because it is
|
||||||
technology testing for the Federal Government in accordance with the USA
|
a publicly available technology and software, and is freely distributed
|
||||||
PATRIOT Act and the Enhanced Border Security and Visa Entry Reform Act.
|
to any interested party with no licensing requirements. Therefore, it is
|
||||||
Specific hardware and software products identified in this software were used
|
permissible to distribute this software as a free download from the internet.
|
||||||
in order to perform the software development. In no case does such
|
|
||||||
identification imply recommendation or endorsement by the National Institute
|
Disclaimer:
|
||||||
of Standards and Technology, nor does it imply that the products and equipment
|
This software and/or related materials was developed to promote biometric
|
||||||
identified are necessarily the best available for the purpose.
|
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.
|
||||||
|
|
||||||
|
This software and/or related materials are provided "AS-IS" without warranty
|
||||||
|
of any kind including NO WARRANTY OF PERFORMANCE, MERCHANTABILITY,
|
||||||
|
NO WARRANTY OF NON-INFRINGEMENT OF ANY 3RD PARTY INTELLECTUAL PROPERTY
|
||||||
|
or FITNESS FOR A PARTICULAR PURPOSE or for any purpose whatsoever, for the
|
||||||
|
licensed product, however used. In no event shall NIST be liable for any
|
||||||
|
damages and/or costs, including but not limited to incidental or consequential
|
||||||
|
damages of any kind, including economic damage or injury to property and lost
|
||||||
|
profits, regardless of whether NIST shall be advised, have reason to know,
|
||||||
|
or in fact shall know of the possibility.
|
||||||
|
|
||||||
|
By using this software, you agree to bear all risk relating to quality,
|
||||||
|
use and performance of the software and/or related materials. You agree
|
||||||
|
to hold the Government harmless from any claim arising from your use
|
||||||
|
of the software.
|
||||||
|
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
|
|
||||||
|
|
|
@ -1,23 +1,43 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
|
|
||||||
License:
|
License:
|
||||||
This software was developed at the National Institute of Standards and
|
This software and/or related materials was developed at the National Institute
|
||||||
Technology (NIST) by employees of the Federal Government in the course
|
of Standards and Technology (NIST) by employees of the Federal Government
|
||||||
of their official duties. Pursuant to title 17 Section 105 of the
|
in the course of their official duties. Pursuant to title 17 Section 105
|
||||||
United States Code, this software is not subject to copyright protection
|
of the United States Code, this software is not subject to copyright
|
||||||
and is in the public domain. NIST assumes no responsibility whatsoever for
|
protection and is in the public domain.
|
||||||
its use by other parties, and makes no guarantees, expressed or implied,
|
|
||||||
about its quality, reliability, or any other characteristic.
|
|
||||||
|
|
||||||
Disclaimer:
|
This software and/or related materials have been determined to be not subject
|
||||||
This software was developed to promote biometric standards and biometric
|
to the EAR (see Part 734.3 of the EAR for exact details) because it is
|
||||||
technology testing for the Federal Government in accordance with the USA
|
a publicly available technology and software, and is freely distributed
|
||||||
PATRIOT Act and the Enhanced Border Security and Visa Entry Reform Act.
|
to any interested party with no licensing requirements. Therefore, it is
|
||||||
Specific hardware and software products identified in this software were used
|
permissible to distribute this software as a free download from the internet.
|
||||||
in order to perform the software development. In no case does such
|
|
||||||
identification imply recommendation or endorsement by the National Institute
|
Disclaimer:
|
||||||
of Standards and Technology, nor does it imply that the products and equipment
|
This software and/or related materials was developed to promote biometric
|
||||||
identified are necessarily the best available for the purpose.
|
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.
|
||||||
|
|
||||||
|
This software and/or related materials are provided "AS-IS" without warranty
|
||||||
|
of any kind including NO WARRANTY OF PERFORMANCE, MERCHANTABILITY,
|
||||||
|
NO WARRANTY OF NON-INFRINGEMENT OF ANY 3RD PARTY INTELLECTUAL PROPERTY
|
||||||
|
or FITNESS FOR A PARTICULAR PURPOSE or for any purpose whatsoever, for the
|
||||||
|
licensed product, however used. In no event shall NIST be liable for any
|
||||||
|
damages and/or costs, including but not limited to incidental or consequential
|
||||||
|
damages of any kind, including economic damage or injury to property and lost
|
||||||
|
profits, regardless of whether NIST shall be advised, have reason to know,
|
||||||
|
or in fact shall know of the possibility.
|
||||||
|
|
||||||
|
By using this software, you agree to bear all risk relating to quality,
|
||||||
|
use and performance of the software and/or related materials. You agree
|
||||||
|
to hold the Government harmless from any claim arising from your use
|
||||||
|
of the software.
|
||||||
|
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
|
|
||||||
|
@ -53,7 +73,6 @@ identified are necessarily the best available for the purpose.
|
||||||
#define min(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(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 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_16(_v_) ((((_v_)+15)>>4)<<4)
|
||||||
#define align_to_32(_v_) ((((_v_)+31)>>5)<<5)
|
#define align_to_32(_v_) ((((_v_)+31)>>5)<<5)
|
||||||
#ifndef CHUNKS
|
#ifndef CHUNKS
|
||||||
|
|
|
@ -1,23 +1,43 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
|
|
||||||
License:
|
License:
|
||||||
This software was developed at the National Institute of Standards and
|
This software and/or related materials was developed at the National Institute
|
||||||
Technology (NIST) by employees of the Federal Government in the course
|
of Standards and Technology (NIST) by employees of the Federal Government
|
||||||
of their official duties. Pursuant to title 17 Section 105 of the
|
in the course of their official duties. Pursuant to title 17 Section 105
|
||||||
United States Code, this software is not subject to copyright protection
|
of the United States Code, this software is not subject to copyright
|
||||||
and is in the public domain. NIST assumes no responsibility whatsoever for
|
protection and is in the public domain.
|
||||||
its use by other parties, and makes no guarantees, expressed or implied,
|
|
||||||
about its quality, reliability, or any other characteristic.
|
|
||||||
|
|
||||||
Disclaimer:
|
This software and/or related materials have been determined to be not subject
|
||||||
This software was developed to promote biometric standards and biometric
|
to the EAR (see Part 734.3 of the EAR for exact details) because it is
|
||||||
technology testing for the Federal Government in accordance with the USA
|
a publicly available technology and software, and is freely distributed
|
||||||
PATRIOT Act and the Enhanced Border Security and Visa Entry Reform Act.
|
to any interested party with no licensing requirements. Therefore, it is
|
||||||
Specific hardware and software products identified in this software were used
|
permissible to distribute this software as a free download from the internet.
|
||||||
in order to perform the software development. In no case does such
|
|
||||||
identification imply recommendation or endorsement by the National Institute
|
Disclaimer:
|
||||||
of Standards and Technology, nor does it imply that the products and equipment
|
This software and/or related materials was developed to promote biometric
|
||||||
identified are necessarily the best available for the purpose.
|
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.
|
||||||
|
|
||||||
|
This software and/or related materials are provided "AS-IS" without warranty
|
||||||
|
of any kind including NO WARRANTY OF PERFORMANCE, MERCHANTABILITY,
|
||||||
|
NO WARRANTY OF NON-INFRINGEMENT OF ANY 3RD PARTY INTELLECTUAL PROPERTY
|
||||||
|
or FITNESS FOR A PARTICULAR PURPOSE or for any purpose whatsoever, for the
|
||||||
|
licensed product, however used. In no event shall NIST be liable for any
|
||||||
|
damages and/or costs, including but not limited to incidental or consequential
|
||||||
|
damages of any kind, including economic damage or injury to property and lost
|
||||||
|
profits, regardless of whether NIST shall be advised, have reason to know,
|
||||||
|
or in fact shall know of the possibility.
|
||||||
|
|
||||||
|
By using this software, you agree to bear all risk relating to quality,
|
||||||
|
use and performance of the software and/or related materials. You agree
|
||||||
|
to hold the Government harmless from any claim arising from your use
|
||||||
|
of the software.
|
||||||
|
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
|
|
||||||
|
@ -33,6 +53,9 @@ identified are necessarily the best available for the purpose.
|
||||||
Comments added to guide changes to blocksize
|
Comments added to guide changes to blocksize
|
||||||
or number of detected directions.
|
or number of detected directions.
|
||||||
UPDATED: 03/11/2005 by MDG
|
UPDATED: 03/11/2005 by MDG
|
||||||
|
UPDATED: 01/31/2008 by Kenneth Ko
|
||||||
|
UPDATED: 09/04/2008 by Kenneth Ko
|
||||||
|
UPDATED: 01/11/2012 by Kenneth Ko
|
||||||
|
|
||||||
FILE: LFS.H
|
FILE: LFS.H
|
||||||
|
|
||||||
|
@ -160,7 +183,7 @@ typedef struct shape{
|
||||||
|
|
||||||
/* Parameters used by LFS for setting thresholds and */
|
/* Parameters used by LFS for setting thresholds and */
|
||||||
/* defining testing criterion. */
|
/* defining testing criterion. */
|
||||||
typedef struct lfsparms{
|
typedef struct g_lfsparms{
|
||||||
/* Image Controls */
|
/* Image Controls */
|
||||||
int pad_value;
|
int pad_value;
|
||||||
int join_line_radius;
|
int join_line_radius;
|
||||||
|
@ -236,8 +259,6 @@ typedef struct lfsparms{
|
||||||
int pores_steps_bwd;
|
int pores_steps_bwd;
|
||||||
double pores_min_dist2;
|
double pores_min_dist2;
|
||||||
double pores_max_ratio;
|
double pores_max_ratio;
|
||||||
int remove_perimeter_pts;
|
|
||||||
int min_pp_distance;
|
|
||||||
|
|
||||||
/* Ridge Counting Controls */
|
/* Ridge Counting Controls */
|
||||||
int max_nbrs;
|
int max_nbrs;
|
||||||
|
@ -382,7 +403,7 @@ typedef struct lfsparms{
|
||||||
/* Thresholds and factors used by HO39. Renamed */
|
/* Thresholds and factors used by HO39. Renamed */
|
||||||
/* here to give more meaning. */
|
/* here to give more meaning. */
|
||||||
/* HO39 Name=Value */
|
/* HO39 Name=Value */
|
||||||
/* Minimum DFT power allowable in any one direction. */
|
/* Minimum DFT power allowable in any one direction. */
|
||||||
#define POWMAX_MIN 100000.0 /* thrhf=1e5f */
|
#define POWMAX_MIN 100000.0 /* thrhf=1e5f */
|
||||||
|
|
||||||
/* Minimum normalized power allowable in any one */
|
/* Minimum normalized power allowable in any one */
|
||||||
|
@ -587,9 +608,6 @@ typedef struct lfsparms{
|
||||||
/* contour points to be considered a pore. */
|
/* contour points to be considered a pore. */
|
||||||
#define PORES_MAX_RATIO 2.25
|
#define PORES_MAX_RATIO 2.25
|
||||||
|
|
||||||
/* Points which are closer than this distance to scan perimeter will be removed */
|
|
||||||
#define PERIMETER_PTS_DISTANCE 10
|
|
||||||
|
|
||||||
|
|
||||||
/***** RIDGE COUNTING CONSTANTS *****/
|
/***** RIDGE COUNTING CONSTANTS *****/
|
||||||
|
|
||||||
|
@ -689,15 +707,24 @@ typedef struct lfsparms{
|
||||||
/*************************************************************************/
|
/*************************************************************************/
|
||||||
|
|
||||||
/* binar.c */
|
/* binar.c */
|
||||||
|
extern int binarize(unsigned char **, int *, int *,
|
||||||
|
unsigned char *, const int, const int,
|
||||||
|
int *, const int, const int,
|
||||||
|
const ROTGRIDS *, const LFSPARMS *);
|
||||||
extern int binarize_V2(unsigned char **, int *, int *,
|
extern int binarize_V2(unsigned char **, int *, int *,
|
||||||
unsigned char *, const int, const int,
|
unsigned char *, const int, const int,
|
||||||
int *, const int, const int,
|
int *, const int, const int,
|
||||||
const ROTGRIDS *, const LFSPARMS *);
|
const ROTGRIDS *, const LFSPARMS *);
|
||||||
|
extern int binarize_image(unsigned char **, int *, int *,
|
||||||
|
unsigned char *, const int, const int,
|
||||||
|
const int *, const int, const int, const int,
|
||||||
|
const ROTGRIDS *, const int);
|
||||||
extern int binarize_image_V2(unsigned char **, int *, int *,
|
extern int binarize_image_V2(unsigned char **, int *, int *,
|
||||||
unsigned char *, const int, const int,
|
unsigned char *, const int, const int,
|
||||||
const int *, const int, const int,
|
const int *, const int, const int,
|
||||||
const int, const ROTGRIDS *);
|
const int, const ROTGRIDS *);
|
||||||
extern int dirbinarize(const unsigned char *, const int, const ROTGRIDS *);
|
extern int dirbinarize(const unsigned char *, const int, const ROTGRIDS *);
|
||||||
|
extern int isobinarize(unsigned char *, const int, const int, const int);
|
||||||
|
|
||||||
/* block.c */
|
/* block.c */
|
||||||
extern int block_offsets(int **, int *, int *, const int, const int,
|
extern int block_offsets(int **, int *, int *, const int, const int,
|
||||||
|
@ -709,9 +736,12 @@ extern int find_valid_block(int *, int *, int *, int *, int *,
|
||||||
const int, const int);
|
const int, const int);
|
||||||
extern void set_margin_blocks(int *, const int, const int, const int);
|
extern void set_margin_blocks(int *, const int, const int, const int);
|
||||||
|
|
||||||
|
/* chaincod.c */
|
||||||
|
extern int chain_code_loop(int **, int *, const int *, const int *, const int);
|
||||||
|
extern int is_chain_clockwise(const int *, const int, const int);
|
||||||
|
|
||||||
/* contour.c */
|
/* contour.c */
|
||||||
int allocate_contour(int **ocontour_x, int **ocontour_y,
|
extern int allocate_contour(int **, int **, int **, int **, const int);
|
||||||
int **ocontour_ex, int **ocontour_ey, const int ncontour);
|
|
||||||
extern void free_contour(int *, int *, int *, int *);
|
extern void free_contour(int *, int *, int *, int *);
|
||||||
extern int get_high_curvature_contour(int **, int **, int **, int **, int *,
|
extern int get_high_curvature_contour(int **, int **, int **, int **, int *,
|
||||||
const int, const int, const int, const int, const int,
|
const int, const int, const int, const int, const int,
|
||||||
|
@ -726,6 +756,11 @@ extern int trace_contour(int **, int **, int **, int **, int *,
|
||||||
extern int search_contour(const int, const int, const int,
|
extern int search_contour(const int, const int, const int,
|
||||||
const int, const int, const int, const int, const int,
|
const int, const int, const int, const int, const int,
|
||||||
unsigned char *, const int, const int);
|
unsigned char *, const int, const int);
|
||||||
|
extern int next_contour_pixel(int *, int *, int *, int *,
|
||||||
|
const int, const int, const int, const int, const int,
|
||||||
|
unsigned char *, const int, const int);
|
||||||
|
extern int start_scan_nbr(const int, const int, const int, const int);
|
||||||
|
extern int next_scan_nbr(const int, const int);
|
||||||
extern int min_contour_theta(int *, double *, const int, const int *,
|
extern int min_contour_theta(int *, double *, const int, const int *,
|
||||||
const int *, const int);
|
const int *, const int);
|
||||||
extern void contour_limits(int *, int *, int *, int *, const int *,
|
extern void contour_limits(int *, int *, int *, int *, const int *,
|
||||||
|
@ -734,18 +769,29 @@ extern void fix_edge_pixel_pair(int *, int *, int *, int *,
|
||||||
unsigned char *, const int, const int);
|
unsigned char *, const int, const int);
|
||||||
|
|
||||||
/* detect.c */
|
/* detect.c */
|
||||||
extern int get_minutiae(MINUTIAE **, int **, int **, int **,
|
extern int lfs_detect_minutiae( MINUTIAE **,
|
||||||
int **, int **, int *, int *,
|
int **, int **, int *, int *,
|
||||||
unsigned char **, int *, int *, int *,
|
unsigned char **, int *, int *,
|
||||||
unsigned char *, const int, const int,
|
unsigned char *, const int, const int,
|
||||||
const int, const double, const LFSPARMS *);
|
const LFSPARMS *);
|
||||||
|
|
||||||
|
extern int lfs_detect_minutiae_V2(MINUTIAE **,
|
||||||
|
int **, int **, int **, int **, int *, int *,
|
||||||
|
unsigned char **, int *, int *,
|
||||||
|
unsigned char *, const int, const int,
|
||||||
|
const LFSPARMS *);
|
||||||
|
|
||||||
/* dft.c */
|
/* dft.c */
|
||||||
extern int dft_dir_powers(double **, unsigned char *, const int,
|
extern int dft_dir_powers(double **, unsigned char *, const int,
|
||||||
const int, const int, const DFTWAVES *,
|
const int, const int, const DFTWAVES *,
|
||||||
const ROTGRIDS *);
|
const ROTGRIDS *);
|
||||||
|
extern void sum_rot_block_rows(int *, const unsigned char *, const int *,
|
||||||
|
const int);
|
||||||
|
extern void dft_power(double *, const int *, const DFTWAVE *, const int);
|
||||||
extern int dft_power_stats(int *, double *, int *, double *, double **,
|
extern int dft_power_stats(int *, double *, int *, double *, double **,
|
||||||
const int, const int, const int);
|
const int, const int, const int);
|
||||||
|
extern void get_max_norm(double *, int *, double *, const double *, const int);
|
||||||
|
extern int sort_dft_waves(int *, const double *, const double *, const int);
|
||||||
|
|
||||||
/* free.c */
|
/* free.c */
|
||||||
extern void free_dir2rad(DIR2RAD *);
|
extern void free_dir2rad(DIR2RAD *);
|
||||||
|
@ -753,6 +799,13 @@ extern void free_dftwaves(DFTWAVES *);
|
||||||
extern void free_rotgrids(ROTGRIDS *);
|
extern void free_rotgrids(ROTGRIDS *);
|
||||||
extern void free_dir_powers(double **, const int);
|
extern void free_dir_powers(double **, const int);
|
||||||
|
|
||||||
|
/* getmin.c */
|
||||||
|
extern int get_minutiae(MINUTIAE **, int **, int **, int **,
|
||||||
|
int **, int **, int *, int *,
|
||||||
|
unsigned char **, int *, int *, int *,
|
||||||
|
unsigned char *, const int, const int,
|
||||||
|
const int, const double, const LFSPARMS *);
|
||||||
|
|
||||||
/* imgutil.c */
|
/* imgutil.c */
|
||||||
extern void bits_6to8(unsigned char *, const int, const int);
|
extern void bits_6to8(unsigned char *, const int, const int);
|
||||||
extern void bits_8to6(unsigned char *, const int, const int);
|
extern void bits_8to6(unsigned char *, const int, const int);
|
||||||
|
@ -771,15 +824,41 @@ extern int search_in_direction(int *, int *, int *, int *, const int,
|
||||||
/* init.c */
|
/* init.c */
|
||||||
extern int init_dir2rad(DIR2RAD **, const int);
|
extern int init_dir2rad(DIR2RAD **, const int);
|
||||||
extern int init_dftwaves(DFTWAVES **, const double *, const int, const int);
|
extern int init_dftwaves(DFTWAVES **, const double *, const int, const int);
|
||||||
|
extern int get_max_padding(const int, const int, const int, const int);
|
||||||
extern int get_max_padding_V2(const int, const int, const int, const int);
|
extern int get_max_padding_V2(const int, const int, const int, const int);
|
||||||
extern int init_rotgrids(ROTGRIDS **, const int, const int, const int,
|
extern int init_rotgrids(ROTGRIDS **, const int, const int, const int,
|
||||||
const double, const int, const int, const int, const int);
|
const double, const int, const int, const int, const int);
|
||||||
extern int alloc_dir_powers(double ***, const int, const int);
|
extern int alloc_dir_powers(double ***, const int, const int);
|
||||||
extern int alloc_power_stats(int **, double **, int **, double **, const int);
|
extern int alloc_power_stats(int **, double **, int **, double **, const int);
|
||||||
|
|
||||||
|
/* isempty.c */
|
||||||
|
extern int is_image_empty(int *, const int, const int);
|
||||||
|
extern int is_qmap_empty(int *, const int, const int);
|
||||||
|
|
||||||
|
|
||||||
/* line.c */
|
/* line.c */
|
||||||
extern int line_points(int **, int **, int *,
|
extern int line_points(int **, int **, int *,
|
||||||
const int, const int, const int, const int);
|
const int, const int, const int, const int);
|
||||||
|
extern int bresenham_line_points(int **, int **, int *,
|
||||||
|
const int, const int, const int, const int);
|
||||||
|
|
||||||
|
/* link.c */
|
||||||
|
extern int link_minutiae(MINUTIAE *, unsigned char *, const int, const int,
|
||||||
|
int *, const int, const int, const LFSPARMS *);
|
||||||
|
extern int create_link_table(int **, int **, int **, int *, int *, int *,
|
||||||
|
const int, const int, const MINUTIAE *, const int *,
|
||||||
|
int *, const int, const int, unsigned char *,
|
||||||
|
const int, const int, const LFSPARMS *);
|
||||||
|
extern int update_link_table(int *, int *, int *, int *, int *, int *,
|
||||||
|
const int, int *, int *, int *, int *,
|
||||||
|
const int, const int, const int);
|
||||||
|
extern int order_link_table(int *, int *, int *, const int, const int,
|
||||||
|
const int, const int, const MINUTIAE *, const int);
|
||||||
|
extern int process_link_table(const int *, const int *, const int *,
|
||||||
|
const int, const int, const int, const int, MINUTIAE *,
|
||||||
|
int *, unsigned char *, const int, const int,
|
||||||
|
const LFSPARMS *);
|
||||||
|
extern double link_score(const double, const double, const LFSPARMS *);
|
||||||
|
|
||||||
/* loop.c */
|
/* loop.c */
|
||||||
extern int get_loop_list(int **, MINUTIAE *, const int, unsigned char *,
|
extern int get_loop_list(int **, MINUTIAE *, const int, unsigned char *,
|
||||||
|
@ -799,8 +878,16 @@ extern int process_loop_V2(MINUTIAE *, const int *, const int *,
|
||||||
const int *, const int *, const int,
|
const int *, const int *, const int,
|
||||||
unsigned char *, const int, const int,
|
unsigned char *, const int, const int,
|
||||||
int *, const LFSPARMS *);
|
int *, const LFSPARMS *);
|
||||||
|
extern void get_loop_aspect(int *, int *, double *, int *, int *, double *,
|
||||||
|
const int *, const int *, const int);
|
||||||
extern int fill_loop(const int *, const int *, const int,
|
extern int fill_loop(const int *, const int *, const int,
|
||||||
unsigned char *, const int, const int);
|
unsigned char *, const int, const int);
|
||||||
|
extern void fill_partial_row(const int, const int, const int, const int,
|
||||||
|
unsigned char *, const int, const int);
|
||||||
|
extern void flood_loop(const int *, const int *, const int,
|
||||||
|
unsigned char *, const int, const int);
|
||||||
|
extern void flood_fill4(const int, const int, const int,
|
||||||
|
unsigned char *, const int, const int);
|
||||||
|
|
||||||
/* maps.c */
|
/* maps.c */
|
||||||
extern int gen_image_maps(int **, int **, int **, int **, int *, int *,
|
extern int gen_image_maps(int **, int **, int **, int **, int *, int *,
|
||||||
|
@ -820,6 +907,10 @@ extern void smooth_direction_map(int *, int *, const int, const int,
|
||||||
const DIR2RAD *, const LFSPARMS *);
|
const DIR2RAD *, const LFSPARMS *);
|
||||||
extern int gen_high_curve_map(int **, int *, const int, const int,
|
extern int gen_high_curve_map(int **, int *, const int, const int,
|
||||||
const LFSPARMS *);
|
const LFSPARMS *);
|
||||||
|
extern int gen_imap(int **, int *, int *,
|
||||||
|
unsigned char *, const int, const int,
|
||||||
|
const DIR2RAD *, const DFTWAVES *, const ROTGRIDS *,
|
||||||
|
const LFSPARMS *);
|
||||||
extern int gen_initial_imap(int **, int *, const int, const int,
|
extern int gen_initial_imap(int **, int *, const int, const int,
|
||||||
unsigned char *, const int, const int,
|
unsigned char *, const int, const int,
|
||||||
const DFTWAVES *, const ROTGRIDS *, const LFSPARMS *);
|
const DFTWAVES *, const ROTGRIDS *, const LFSPARMS *);
|
||||||
|
@ -850,6 +941,7 @@ extern void average_8nbr_dir(int *, double *, int *, int *, const int,
|
||||||
extern int num_valid_8nbrs(int *, const int, const int, const int, const int);
|
extern int num_valid_8nbrs(int *, const int, const int, const int, const int);
|
||||||
extern void smooth_imap(int *, const int, const int, const DIR2RAD *,
|
extern void smooth_imap(int *, const int, const int, const DIR2RAD *,
|
||||||
const LFSPARMS *);
|
const LFSPARMS *);
|
||||||
|
extern int gen_nmap(int **, int *, const int, const int, const LFSPARMS *);
|
||||||
extern int vorticity(int *, const int, const int, const int, const int,
|
extern int vorticity(int *, const int, const int, const int, const int,
|
||||||
const int);
|
const int);
|
||||||
extern void accum_nbr_vorticity(int *, const int, const int, const int);
|
extern void accum_nbr_vorticity(int *, const int, const int, const int);
|
||||||
|
@ -868,6 +960,9 @@ extern void skip_repeated_vertical_pair(int *, const int,
|
||||||
/* minutia.c */
|
/* minutia.c */
|
||||||
extern int alloc_minutiae(MINUTIAE **, const int);
|
extern int alloc_minutiae(MINUTIAE **, const int);
|
||||||
extern int realloc_minutiae(MINUTIAE *, const int);
|
extern int realloc_minutiae(MINUTIAE *, const int);
|
||||||
|
extern int detect_minutiae(MINUTIAE *, unsigned char *, const int, const int,
|
||||||
|
const int *, const int *, const int, const int,
|
||||||
|
const LFSPARMS *);
|
||||||
extern int detect_minutiae_V2(MINUTIAE *,
|
extern int detect_minutiae_V2(MINUTIAE *,
|
||||||
unsigned char *, const int, const int,
|
unsigned char *, const int, const int,
|
||||||
int *, int *, int *, const int, const int,
|
int *, int *, int *, const int, const int,
|
||||||
|
@ -972,8 +1067,6 @@ extern int adjust_high_curvature_minutia_V2(int *, int *, int *,
|
||||||
int *, MINUTIAE *, const LFSPARMS *);
|
int *, MINUTIAE *, const LFSPARMS *);
|
||||||
extern int get_low_curvature_direction(const int, const int, const int,
|
extern int get_low_curvature_direction(const int, const int, const int,
|
||||||
const int);
|
const int);
|
||||||
void lfs2nist_minutia_XYT(int *ox, int *oy, int *ot,
|
|
||||||
const MINUTIA *minutia, const int iw, const int ih);
|
|
||||||
|
|
||||||
/* quality.c */
|
/* quality.c */
|
||||||
extern int gen_quality_map(int **, int *, int *, int *, int *,
|
extern int gen_quality_map(int **, int *, int *, int *, int *,
|
||||||
|
@ -981,6 +1074,12 @@ extern int gen_quality_map(int **, int *, int *, int *, int *,
|
||||||
extern int combined_minutia_quality(MINUTIAE *, int *, const int, const int,
|
extern int combined_minutia_quality(MINUTIAE *, int *, const int, const int,
|
||||||
const int, unsigned char *, const int, const int,
|
const int, unsigned char *, const int, const int,
|
||||||
const int, const double);
|
const int, const double);
|
||||||
|
double grayscale_reliability(MINUTIA *, unsigned char *,
|
||||||
|
const int, const int, const int);
|
||||||
|
extern void get_neighborhood_stats(double *, double *, MINUTIA *,
|
||||||
|
unsigned char *, const int, const int, const int);
|
||||||
|
extern int reliability_fr_quality_map(MINUTIAE *, int *, const int,
|
||||||
|
const int, const int, const int, const int);
|
||||||
|
|
||||||
/* remove.c */
|
/* remove.c */
|
||||||
extern int remove_false_minutia(MINUTIAE *,
|
extern int remove_false_minutia(MINUTIAE *,
|
||||||
|
@ -990,15 +1089,93 @@ extern int remove_false_minutia_V2(MINUTIAE *,
|
||||||
unsigned char *, const int, const int,
|
unsigned char *, const int, const int,
|
||||||
int *, int *, int *, const int, const int,
|
int *, int *, int *, const int, const int,
|
||||||
const LFSPARMS *);
|
const LFSPARMS *);
|
||||||
|
extern int remove_holes(MINUTIAE *, unsigned char *, const int, const int,
|
||||||
|
const LFSPARMS *);
|
||||||
|
extern int remove_hooks(MINUTIAE *,
|
||||||
|
unsigned char *, const int, const int, const LFSPARMS *);
|
||||||
|
extern int remove_hooks_islands_lakes_overlaps(MINUTIAE *, unsigned char *,
|
||||||
|
const int, const int, const LFSPARMS *);
|
||||||
|
extern int remove_islands_and_lakes(MINUTIAE *,
|
||||||
|
unsigned char *, const int, const int, const LFSPARMS *);
|
||||||
|
extern int remove_malformations(MINUTIAE *,
|
||||||
|
unsigned char *, const int, const int,
|
||||||
|
int *, const int, const int, const LFSPARMS *);
|
||||||
|
extern int remove_near_invblock(MINUTIAE *, int *, const int, const int,
|
||||||
|
const LFSPARMS *);
|
||||||
|
extern int remove_near_invblock_V2(MINUTIAE *, int *,
|
||||||
|
const int, const int, const LFSPARMS *);
|
||||||
|
extern int remove_pointing_invblock(MINUTIAE *, int *, const int, const int,
|
||||||
|
const LFSPARMS *);
|
||||||
|
extern int remove_pointing_invblock_V2(MINUTIAE *,
|
||||||
|
int *, const int, const int, const LFSPARMS *);
|
||||||
|
extern int remove_overlaps(MINUTIAE *,
|
||||||
|
unsigned char *, const int, const int, const LFSPARMS *);
|
||||||
|
extern int remove_pores(MINUTIAE *,
|
||||||
|
unsigned char *, const int, const int,
|
||||||
|
int *, const int, const int, const LFSPARMS *);
|
||||||
|
extern int remove_pores_V2(MINUTIAE *,
|
||||||
|
unsigned char *, const int, const int,
|
||||||
|
int *, int *, int *, const int, const int,
|
||||||
|
const LFSPARMS *);
|
||||||
|
extern int remove_or_adjust_side_minutiae(MINUTIAE *, unsigned char *,
|
||||||
|
const int, const int, const LFSPARMS *);
|
||||||
|
extern int remove_or_adjust_side_minutiae_V2(MINUTIAE *,
|
||||||
|
unsigned char *, const int, const int,
|
||||||
|
int *, const int, const int, const LFSPARMS *);
|
||||||
|
|
||||||
|
/* results.c */
|
||||||
|
extern int write_text_results(char *, const int, const int, const int,
|
||||||
|
const MINUTIAE *, int *, int *, int *, int *, int *,
|
||||||
|
const int, const int);
|
||||||
|
extern int write_minutiae_XYTQ(char *ofile, const int,
|
||||||
|
const MINUTIAE *, const int, const int);
|
||||||
|
extern void dump_map(FILE *, int *, const int, const int);
|
||||||
|
extern int drawimap(int *, const int, const int, unsigned char *,
|
||||||
|
const int, const int, const ROTGRIDS *, const int);
|
||||||
|
extern void drawimap2(int *, const int *, const int, const int,
|
||||||
|
unsigned char *, const int, const int,
|
||||||
|
const double, const int, const int);
|
||||||
|
extern void drawblocks(const int *, const int, const int,
|
||||||
|
unsigned char *, const int, const int, const int );
|
||||||
|
extern int drawrotgrid(const ROTGRIDS *, const int, unsigned char *,
|
||||||
|
const int, const int, const int, const int);
|
||||||
|
extern void dump_link_table(FILE *, const int *, const int *, const int *,
|
||||||
|
const int, const int, const int, const MINUTIAE *);
|
||||||
|
extern int draw_direction_map(char *, int *,
|
||||||
|
int *, const int, const int, const int,
|
||||||
|
unsigned char *, const int, const int, const int);
|
||||||
|
extern int draw_TF_map(char *, int *,
|
||||||
|
int *, const int, const int, const int,
|
||||||
|
unsigned char *, const int, const int, const int);
|
||||||
|
|
||||||
/* ridges.c */
|
/* ridges.c */
|
||||||
extern int count_minutiae_ridges(MINUTIAE *,
|
extern int count_minutiae_ridges(MINUTIAE *,
|
||||||
unsigned char *, const int, const int,
|
unsigned char *, const int, const int,
|
||||||
const LFSPARMS *);
|
const LFSPARMS *);
|
||||||
|
extern int count_minutia_ridges(const int, MINUTIAE *,
|
||||||
|
unsigned char *, const int, const int,
|
||||||
|
const LFSPARMS *);
|
||||||
|
extern int find_neighbors(int **, int *, const int, const int, MINUTIAE *);
|
||||||
|
extern int update_nbr_dists(int *, double *, int *, const int,
|
||||||
|
const int, const int, MINUTIAE *);
|
||||||
|
extern int insert_neighbor(const int, const int, const double,
|
||||||
|
int *, double *, int *, const int);
|
||||||
|
extern int sort_neighbors(int *, const int, const int, MINUTIAE *);
|
||||||
|
extern int ridge_count(const int, const int, MINUTIAE *,
|
||||||
|
unsigned char *, const int, const int, const LFSPARMS *);
|
||||||
|
extern int find_transition(int *, const int, const int,
|
||||||
|
const int *, const int *, const int,
|
||||||
|
unsigned char *, const int, const int);
|
||||||
|
extern int validate_ridge_crossing(const int, const int,
|
||||||
|
const int *, const int *, const int,
|
||||||
|
unsigned char *, const int, const int, const int);
|
||||||
|
|
||||||
/* shape.c */
|
/* shape.c */
|
||||||
|
extern int alloc_shape(SHAPE **, const int, const int, const int, const int);
|
||||||
extern void free_shape(SHAPE *);
|
extern void free_shape(SHAPE *);
|
||||||
|
extern void dump_shape(FILE *, const SHAPE *);
|
||||||
extern int shape_from_contour(SHAPE **, const int *, const int *, const int);
|
extern int shape_from_contour(SHAPE **, const int *, const int *, const int);
|
||||||
|
extern void sort_row_on_x(ROW *);
|
||||||
|
|
||||||
/* sort.c */
|
/* sort.c */
|
||||||
extern int sort_indices_int_inc(int **, int *, const int);
|
extern int sort_indices_int_inc(int **, int *, const int);
|
||||||
|
@ -1023,6 +1200,12 @@ extern int line2direction(const int, const int, const int, const int,
|
||||||
const int);
|
const int);
|
||||||
extern int closest_dir_dist(const int, const int, const int);
|
extern int closest_dir_dist(const int, const int, const int);
|
||||||
|
|
||||||
|
/* xytreps.c */
|
||||||
|
extern void lfs2nist_minutia_XYT(int *, int *, int *,
|
||||||
|
const MINUTIA *, const int, const int);
|
||||||
|
extern void lfs2m1_minutia_XYT(int *, int *, int *, const MINUTIA *);
|
||||||
|
extern void lfs2nist_format(MINUTIAE *, int, int);
|
||||||
|
|
||||||
/*************************************************************************/
|
/*************************************************************************/
|
||||||
/* EXTERNAL GLOBAL VARIABLE DEFINITIONS */
|
/* EXTERNAL GLOBAL VARIABLE DEFINITIONS */
|
||||||
/*************************************************************************/
|
/*************************************************************************/
|
||||||
|
|
|
@ -1,26 +1,47 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
|
|
||||||
License:
|
License:
|
||||||
This software was developed at the National Institute of Standards and
|
This software and/or related materials was developed at the National Institute
|
||||||
Technology (NIST) by employees of the Federal Government in the course
|
of Standards and Technology (NIST) by employees of the Federal Government
|
||||||
of their official duties. Pursuant to title 17 Section 105 of the
|
in the course of their official duties. Pursuant to title 17 Section 105
|
||||||
United States Code, this software is not subject to copyright protection
|
of the United States Code, this software is not subject to copyright
|
||||||
and is in the public domain. NIST assumes no responsibility whatsoever for
|
protection and is in the public domain.
|
||||||
its use by other parties, and makes no guarantees, expressed or implied,
|
|
||||||
about its quality, reliability, or any other characteristic.
|
|
||||||
|
|
||||||
Disclaimer:
|
This software and/or related materials have been determined to be not subject
|
||||||
This software was developed to promote biometric standards and biometric
|
to the EAR (see Part 734.3 of the EAR for exact details) because it is
|
||||||
technology testing for the Federal Government in accordance with the USA
|
a publicly available technology and software, and is freely distributed
|
||||||
PATRIOT Act and the Enhanced Border Security and Visa Entry Reform Act.
|
to any interested party with no licensing requirements. Therefore, it is
|
||||||
Specific hardware and software products identified in this software were used
|
permissible to distribute this software as a free download from the internet.
|
||||||
in order to perform the software development. In no case does such
|
|
||||||
identification imply recommendation or endorsement by the National Institute
|
Disclaimer:
|
||||||
of Standards and Technology, nor does it imply that the products and equipment
|
This software and/or related materials was developed to promote biometric
|
||||||
identified are necessarily the best available for the purpose.
|
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.
|
||||||
|
|
||||||
|
This software and/or related materials are provided "AS-IS" without warranty
|
||||||
|
of any kind including NO WARRANTY OF PERFORMANCE, MERCHANTABILITY,
|
||||||
|
NO WARRANTY OF NON-INFRINGEMENT OF ANY 3RD PARTY INTELLECTUAL PROPERTY
|
||||||
|
or FITNESS FOR A PARTICULAR PURPOSE or for any purpose whatsoever, for the
|
||||||
|
licensed product, however used. In no event shall NIST be liable for any
|
||||||
|
damages and/or costs, including but not limited to incidental or consequential
|
||||||
|
damages of any kind, including economic damage or injury to property and lost
|
||||||
|
profits, regardless of whether NIST shall be advised, have reason to know,
|
||||||
|
or in fact shall know of the possibility.
|
||||||
|
|
||||||
|
By using this software, you agree to bear all risk relating to quality,
|
||||||
|
use and performance of the software and/or related materials. You agree
|
||||||
|
to hold the Government harmless from any claim arising from your use
|
||||||
|
of the software.
|
||||||
|
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
#ifndef _LOG_H
|
#ifndef _LOG_H
|
||||||
#define _LOG_H
|
#define _LOG_H
|
||||||
|
|
||||||
|
@ -36,10 +57,6 @@ identified are necessarily the best available for the purpose.
|
||||||
#define LOG_FILE "log.txt"
|
#define LOG_FILE "log.txt"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
extern FILE *g_logfp;
|
|
||||||
extern int g_avrdir;
|
|
||||||
extern float g_dir_strength;
|
|
||||||
extern int g_nvalid;
|
|
||||||
|
|
||||||
extern int open_logfile(void);
|
extern int open_logfile(void);
|
||||||
extern int close_logfile(void);
|
extern int close_logfile(void);
|
||||||
|
|
|
@ -1,26 +1,47 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
|
|
||||||
License:
|
License:
|
||||||
This software was developed at the National Institute of Standards and
|
This software and/or related materials was developed at the National Institute
|
||||||
Technology (NIST) by employees of the Federal Government in the course
|
of Standards and Technology (NIST) by employees of the Federal Government
|
||||||
of their official duties. Pursuant to title 17 Section 105 of the
|
in the course of their official duties. Pursuant to title 17 Section 105
|
||||||
United States Code, this software is not subject to copyright protection
|
of the United States Code, this software is not subject to copyright
|
||||||
and is in the public domain. NIST assumes no responsibility whatsoever for
|
protection and is in the public domain.
|
||||||
its use by other parties, and makes no guarantees, expressed or implied,
|
|
||||||
about its quality, reliability, or any other characteristic.
|
|
||||||
|
|
||||||
Disclaimer:
|
This software and/or related materials have been determined to be not subject
|
||||||
This software was developed to promote biometric standards and biometric
|
to the EAR (see Part 734.3 of the EAR for exact details) because it is
|
||||||
technology testing for the Federal Government in accordance with the USA
|
a publicly available technology and software, and is freely distributed
|
||||||
PATRIOT Act and the Enhanced Border Security and Visa Entry Reform Act.
|
to any interested party with no licensing requirements. Therefore, it is
|
||||||
Specific hardware and software products identified in this software were used
|
permissible to distribute this software as a free download from the internet.
|
||||||
in order to perform the software development. In no case does such
|
|
||||||
identification imply recommendation or endorsement by the National Institute
|
Disclaimer:
|
||||||
of Standards and Technology, nor does it imply that the products and equipment
|
This software and/or related materials was developed to promote biometric
|
||||||
identified are necessarily the best available for the purpose.
|
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.
|
||||||
|
|
||||||
|
This software and/or related materials are provided "AS-IS" without warranty
|
||||||
|
of any kind including NO WARRANTY OF PERFORMANCE, MERCHANTABILITY,
|
||||||
|
NO WARRANTY OF NON-INFRINGEMENT OF ANY 3RD PARTY INTELLECTUAL PROPERTY
|
||||||
|
or FITNESS FOR A PARTICULAR PURPOSE or for any purpose whatsoever, for the
|
||||||
|
licensed product, however used. In no event shall NIST be liable for any
|
||||||
|
damages and/or costs, including but not limited to incidental or consequential
|
||||||
|
damages of any kind, including economic damage or injury to property and lost
|
||||||
|
profits, regardless of whether NIST shall be advised, have reason to know,
|
||||||
|
or in fact shall know of the possibility.
|
||||||
|
|
||||||
|
By using this software, you agree to bear all risk relating to quality,
|
||||||
|
use and performance of the software and/or related materials. You agree
|
||||||
|
to hold the Government harmless from any claim arising from your use
|
||||||
|
of the software.
|
||||||
|
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
#ifndef __MORPH_H__
|
#ifndef __MORPH_H__
|
||||||
#define __MORPH_H__
|
#define __MORPH_H__
|
||||||
|
|
||||||
|
|
106
libfprint/nbis/include/mytime.h
Normal file
106
libfprint/nbis/include/mytime.h
Normal file
|
@ -0,0 +1,106 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
|
||||||
|
License:
|
||||||
|
This software and/or related materials 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.
|
||||||
|
|
||||||
|
This software and/or related materials have been determined to be not subject
|
||||||
|
to the EAR (see Part 734.3 of the EAR for exact details) because it is
|
||||||
|
a publicly available technology and software, and is freely distributed
|
||||||
|
to any interested party with no licensing requirements. Therefore, it is
|
||||||
|
permissible to distribute this software as a free download from the internet.
|
||||||
|
|
||||||
|
Disclaimer:
|
||||||
|
This software and/or related materials 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.
|
||||||
|
|
||||||
|
This software and/or related materials are provided "AS-IS" without warranty
|
||||||
|
of any kind including NO WARRANTY OF PERFORMANCE, MERCHANTABILITY,
|
||||||
|
NO WARRANTY OF NON-INFRINGEMENT OF ANY 3RD PARTY INTELLECTUAL PROPERTY
|
||||||
|
or FITNESS FOR A PARTICULAR PURPOSE or for any purpose whatsoever, for the
|
||||||
|
licensed product, however used. In no event shall NIST be liable for any
|
||||||
|
damages and/or costs, including but not limited to incidental or consequential
|
||||||
|
damages of any kind, including economic damage or injury to property and lost
|
||||||
|
profits, regardless of whether NIST shall be advised, have reason to know,
|
||||||
|
or in fact shall know of the possibility.
|
||||||
|
|
||||||
|
By using this software, you agree to bear all risk relating to quality,
|
||||||
|
use and performance of the software and/or related materials. You agree
|
||||||
|
to hold the Government harmless from any claim arising from your use
|
||||||
|
of the software.
|
||||||
|
|
||||||
|
*******************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef _MYTIME_H
|
||||||
|
#define _MYTIME_H
|
||||||
|
|
||||||
|
/* this file needed to support timer and ticks */
|
||||||
|
/* UPDATED: 03/16/2005 by MDG */
|
||||||
|
|
||||||
|
#ifdef TIMER
|
||||||
|
#include <sys/types.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __MSYS__
|
||||||
|
#include <sys/time.h>
|
||||||
|
#else
|
||||||
|
#include <sys/times.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef TIMER
|
||||||
|
#define set_timer(_timer_); \
|
||||||
|
{ \
|
||||||
|
_timer_ = ticks();
|
||||||
|
#else
|
||||||
|
#define set_timer(_timer_);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef TIMER
|
||||||
|
#define time_accum(_timer_, _var_); \
|
||||||
|
_var_ += (ticks() - _timer_)/(float)ticksPerSec(); \
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
#define time_accum(_timer_, _var_);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef TIMER
|
||||||
|
#define print_time(_fp_, _fmt_, _var_); \
|
||||||
|
fprintf(_fp_, _fmt_, _var_);
|
||||||
|
#else
|
||||||
|
#define print_time(_fp_, _fmt_, _var_);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
extern clock_t ticks(void);
|
||||||
|
extern int ticksPerSec(void);
|
||||||
|
|
||||||
|
extern clock_t total_timer;
|
||||||
|
extern float total_time;
|
||||||
|
|
||||||
|
extern clock_t imap_timer;
|
||||||
|
extern float imap_time;
|
||||||
|
|
||||||
|
extern clock_t bin_timer;
|
||||||
|
extern float bin_time;
|
||||||
|
|
||||||
|
extern clock_t minutia_timer;
|
||||||
|
extern float minutia_time;
|
||||||
|
|
||||||
|
extern clock_t rm_minutia_timer;
|
||||||
|
extern float rm_minutia_time;
|
||||||
|
|
||||||
|
extern clock_t ridge_count_timer;
|
||||||
|
extern float ridge_count_time;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
|
@ -1,26 +1,47 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
|
|
||||||
License:
|
License:
|
||||||
This software was developed at the National Institute of Standards and
|
This software and/or related materials was developed at the National Institute
|
||||||
Technology (NIST) by employees of the Federal Government in the course
|
of Standards and Technology (NIST) by employees of the Federal Government
|
||||||
of their official duties. Pursuant to title 17 Section 105 of the
|
in the course of their official duties. Pursuant to title 17 Section 105
|
||||||
United States Code, this software is not subject to copyright protection
|
of the United States Code, this software is not subject to copyright
|
||||||
and is in the public domain. NIST assumes no responsibility whatsoever for
|
protection and is in the public domain.
|
||||||
its use by other parties, and makes no guarantees, expressed or implied,
|
|
||||||
about its quality, reliability, or any other characteristic.
|
|
||||||
|
|
||||||
Disclaimer:
|
This software and/or related materials have been determined to be not subject
|
||||||
This software was developed to promote biometric standards and biometric
|
to the EAR (see Part 734.3 of the EAR for exact details) because it is
|
||||||
technology testing for the Federal Government in accordance with the USA
|
a publicly available technology and software, and is freely distributed
|
||||||
PATRIOT Act and the Enhanced Border Security and Visa Entry Reform Act.
|
to any interested party with no licensing requirements. Therefore, it is
|
||||||
Specific hardware and software products identified in this software were used
|
permissible to distribute this software as a free download from the internet.
|
||||||
in order to perform the software development. In no case does such
|
|
||||||
identification imply recommendation or endorsement by the National Institute
|
Disclaimer:
|
||||||
of Standards and Technology, nor does it imply that the products and equipment
|
This software and/or related materials was developed to promote biometric
|
||||||
identified are necessarily the best available for the purpose.
|
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.
|
||||||
|
|
||||||
|
This software and/or related materials are provided "AS-IS" without warranty
|
||||||
|
of any kind including NO WARRANTY OF PERFORMANCE, MERCHANTABILITY,
|
||||||
|
NO WARRANTY OF NON-INFRINGEMENT OF ANY 3RD PARTY INTELLECTUAL PROPERTY
|
||||||
|
or FITNESS FOR A PARTICULAR PURPOSE or for any purpose whatsoever, for the
|
||||||
|
licensed product, however used. In no event shall NIST be liable for any
|
||||||
|
damages and/or costs, including but not limited to incidental or consequential
|
||||||
|
damages of any kind, including economic damage or injury to property and lost
|
||||||
|
profits, regardless of whether NIST shall be advised, have reason to know,
|
||||||
|
or in fact shall know of the possibility.
|
||||||
|
|
||||||
|
By using this software, you agree to bear all risk relating to quality,
|
||||||
|
use and performance of the software and/or related materials. You agree
|
||||||
|
to hold the Government harmless from any claim arising from your use
|
||||||
|
of the software.
|
||||||
|
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
#ifndef _SUNRAST_H
|
#ifndef _SUNRAST_H
|
||||||
#define _SUNRAST_H
|
#define _SUNRAST_H
|
||||||
|
|
||||||
|
|
|
@ -1,26 +1,47 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
|
|
||||||
License:
|
License:
|
||||||
This software was developed at the National Institute of Standards and
|
This software and/or related materials was developed at the National Institute
|
||||||
Technology (NIST) by employees of the Federal Government in the course
|
of Standards and Technology (NIST) by employees of the Federal Government
|
||||||
of their official duties. Pursuant to title 17 Section 105 of the
|
in the course of their official duties. Pursuant to title 17 Section 105
|
||||||
United States Code, this software is not subject to copyright protection
|
of the United States Code, this software is not subject to copyright
|
||||||
and is in the public domain. NIST assumes no responsibility whatsoever for
|
protection and is in the public domain.
|
||||||
its use by other parties, and makes no guarantees, expressed or implied,
|
|
||||||
about its quality, reliability, or any other characteristic.
|
|
||||||
|
|
||||||
Disclaimer:
|
This software and/or related materials have been determined to be not subject
|
||||||
This software was developed to promote biometric standards and biometric
|
to the EAR (see Part 734.3 of the EAR for exact details) because it is
|
||||||
technology testing for the Federal Government in accordance with the USA
|
a publicly available technology and software, and is freely distributed
|
||||||
PATRIOT Act and the Enhanced Border Security and Visa Entry Reform Act.
|
to any interested party with no licensing requirements. Therefore, it is
|
||||||
Specific hardware and software products identified in this software were used
|
permissible to distribute this software as a free download from the internet.
|
||||||
in order to perform the software development. In no case does such
|
|
||||||
identification imply recommendation or endorsement by the National Institute
|
Disclaimer:
|
||||||
of Standards and Technology, nor does it imply that the products and equipment
|
This software and/or related materials was developed to promote biometric
|
||||||
identified are necessarily the best available for the purpose.
|
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.
|
||||||
|
|
||||||
|
This software and/or related materials are provided "AS-IS" without warranty
|
||||||
|
of any kind including NO WARRANTY OF PERFORMANCE, MERCHANTABILITY,
|
||||||
|
NO WARRANTY OF NON-INFRINGEMENT OF ANY 3RD PARTY INTELLECTUAL PROPERTY
|
||||||
|
or FITNESS FOR A PARTICULAR PURPOSE or for any purpose whatsoever, for the
|
||||||
|
licensed product, however used. In no event shall NIST be liable for any
|
||||||
|
damages and/or costs, including but not limited to incidental or consequential
|
||||||
|
damages of any kind, including economic damage or injury to property and lost
|
||||||
|
profits, regardless of whether NIST shall be advised, have reason to know,
|
||||||
|
or in fact shall know of the possibility.
|
||||||
|
|
||||||
|
By using this software, you agree to bear all risk relating to quality,
|
||||||
|
use and performance of the software and/or related materials. You agree
|
||||||
|
to hold the Government harmless from any claim arising from your use
|
||||||
|
of the software.
|
||||||
|
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
LIBRARY: LFS - NIST Latent Fingerprint System
|
LIBRARY: LFS - NIST Latent Fingerprint System
|
||||||
|
|
||||||
|
@ -36,16 +57,44 @@ identified are necessarily the best available for the purpose.
|
||||||
|
|
||||||
***********************************************************************
|
***********************************************************************
|
||||||
ROUTINES:
|
ROUTINES:
|
||||||
|
binarize()
|
||||||
binarize_V2()
|
binarize_V2()
|
||||||
|
binarize_image()
|
||||||
binarize_image_V2()
|
binarize_image_V2()
|
||||||
dirbinarize()
|
dirbinarize()
|
||||||
|
isobinarize()
|
||||||
|
|
||||||
***********************************************************************/
|
***********************************************************************/
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
|
||||||
#include <lfs.h>
|
#include <lfs.h>
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
#cat: binarize - Takes a padded grayscale input image and its associated ridge
|
||||||
|
#cat: direction flow NMAP and produces a binarized version of the
|
||||||
|
#cat: image. It then fills horizontal and vertical "holes" in the
|
||||||
|
#cat: binary image results.
|
||||||
|
|
||||||
|
Input:
|
||||||
|
pdata - padded input grayscale image
|
||||||
|
pw - padded width (in pixels) of input image
|
||||||
|
ph - padded height (in pixels) of input image
|
||||||
|
nmap - 2-D vector of IMAP directions and other codes
|
||||||
|
mw - width (in blocks) of the NMAP
|
||||||
|
mh - height (in blocks) of the NMAP
|
||||||
|
dirbingrids - set of rotated grid offsets used for directional
|
||||||
|
binarization
|
||||||
|
lfsparms - parameters and thresholds for controlling LFS
|
||||||
|
Output:
|
||||||
|
optr - points to created (unpadded) binary image
|
||||||
|
ow - width of binary image
|
||||||
|
oh - height of binary image
|
||||||
|
Return Code:
|
||||||
|
Zero - successful completion
|
||||||
|
Negative - system error
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
**************************************************************************
|
**************************************************************************
|
||||||
#cat: binarize_V2 - Takes a padded grayscale input image and its associated
|
#cat: binarize_V2 - Takes a padded grayscale input image and its associated
|
||||||
|
@ -101,6 +150,32 @@ int binarize_V2(unsigned char **odata, int *ow, int *oh,
|
||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
#cat: binarize_image - Takes a grayscale input image and its associated
|
||||||
|
#cat: NMAP and generates a binarized version of the image.
|
||||||
|
|
||||||
|
Input:
|
||||||
|
pdata - padded input grayscale image
|
||||||
|
pw - padded width (in pixels) of input image
|
||||||
|
ph - padded height (in pixels) of input image
|
||||||
|
nmap - 2-D vector of IMAP directions and other codes
|
||||||
|
mw - width (in blocks) of the NMAP
|
||||||
|
mh - height (in blocks) of the NMAP
|
||||||
|
imap_blocksize - dimension (in pixels) of each NMAP block
|
||||||
|
dirbingrids - set of rotated grid offsets used for directional
|
||||||
|
binarization
|
||||||
|
isobin_grid_dim - dimension (in pixels) of grid used for isotropic
|
||||||
|
binarization
|
||||||
|
Output:
|
||||||
|
optr - points to binary image results
|
||||||
|
ow - points to binary image width
|
||||||
|
oh - points to binary image height
|
||||||
|
Return Code:
|
||||||
|
Zero - successful completion
|
||||||
|
Negative - system error
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
**************************************************************************
|
**************************************************************************
|
||||||
#cat: binarize_image_V2 - Takes a grayscale input image and its associated
|
#cat: binarize_image_V2 - Takes a grayscale input image and its associated
|
||||||
|
@ -247,3 +322,27 @@ int dirbinarize(const unsigned char *pptr, const int idir,
|
||||||
return(WHITE_PIXEL);
|
return(WHITE_PIXEL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
#cat: isobinarize - Determines the binary value of a grayscale pixel based
|
||||||
|
#cat: on comparing the grayscale value with a surrounding
|
||||||
|
#cat: neighborhood grid of pixels. If the current pixel (treated
|
||||||
|
#cat: as an average) is less than the sum of the pixels in
|
||||||
|
#cat: the neighborhood, then the binary value is set to BLACK,
|
||||||
|
#cat: otherwise it is set to WHITE. This binarization technique
|
||||||
|
#cat: is used when there is no VALID IMAP direction for the
|
||||||
|
#cat: block in which the current pixel resides.
|
||||||
|
|
||||||
|
CAUTION: The image to which the input pixel points must be appropriately
|
||||||
|
padded to account for the radius of the neighborhood. Otherwise,
|
||||||
|
this routine may access "unkown" memory.
|
||||||
|
|
||||||
|
Input:
|
||||||
|
pptr - pointer to curent grayscale pixel
|
||||||
|
pw - padded width (in pixels) of the grayscale image
|
||||||
|
ph - padded height (in pixels) of the grayscale image
|
||||||
|
isobin_grid_dim - dimension (in pixels) of the neighborhood
|
||||||
|
Return Code:
|
||||||
|
BLACK_PIXEL - pixel intensity for BLACK
|
||||||
|
WHITE_PIXEL - pixel intensity of WHITE
|
||||||
|
**************************************************************************/
|
||||||
|
|
|
@ -1,26 +1,47 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
|
|
||||||
License:
|
License:
|
||||||
This software was developed at the National Institute of Standards and
|
This software and/or related materials was developed at the National Institute
|
||||||
Technology (NIST) by employees of the Federal Government in the course
|
of Standards and Technology (NIST) by employees of the Federal Government
|
||||||
of their official duties. Pursuant to title 17 Section 105 of the
|
in the course of their official duties. Pursuant to title 17 Section 105
|
||||||
United States Code, this software is not subject to copyright protection
|
of the United States Code, this software is not subject to copyright
|
||||||
and is in the public domain. NIST assumes no responsibility whatsoever for
|
protection and is in the public domain.
|
||||||
its use by other parties, and makes no guarantees, expressed or implied,
|
|
||||||
about its quality, reliability, or any other characteristic.
|
|
||||||
|
|
||||||
Disclaimer:
|
This software and/or related materials have been determined to be not subject
|
||||||
This software was developed to promote biometric standards and biometric
|
to the EAR (see Part 734.3 of the EAR for exact details) because it is
|
||||||
technology testing for the Federal Government in accordance with the USA
|
a publicly available technology and software, and is freely distributed
|
||||||
PATRIOT Act and the Enhanced Border Security and Visa Entry Reform Act.
|
to any interested party with no licensing requirements. Therefore, it is
|
||||||
Specific hardware and software products identified in this software were used
|
permissible to distribute this software as a free download from the internet.
|
||||||
in order to perform the software development. In no case does such
|
|
||||||
identification imply recommendation or endorsement by the National Institute
|
Disclaimer:
|
||||||
of Standards and Technology, nor does it imply that the products and equipment
|
This software and/or related materials was developed to promote biometric
|
||||||
identified are necessarily the best available for the purpose.
|
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.
|
||||||
|
|
||||||
|
This software and/or related materials are provided "AS-IS" without warranty
|
||||||
|
of any kind including NO WARRANTY OF PERFORMANCE, MERCHANTABILITY,
|
||||||
|
NO WARRANTY OF NON-INFRINGEMENT OF ANY 3RD PARTY INTELLECTUAL PROPERTY
|
||||||
|
or FITNESS FOR A PARTICULAR PURPOSE or for any purpose whatsoever, for the
|
||||||
|
licensed product, however used. In no event shall NIST be liable for any
|
||||||
|
damages and/or costs, including but not limited to incidental or consequential
|
||||||
|
damages of any kind, including economic damage or injury to property and lost
|
||||||
|
profits, regardless of whether NIST shall be advised, have reason to know,
|
||||||
|
or in fact shall know of the possibility.
|
||||||
|
|
||||||
|
By using this software, you agree to bear all risk relating to quality,
|
||||||
|
use and performance of the software and/or related materials. You agree
|
||||||
|
to hold the Government harmless from any claim arising from your use
|
||||||
|
of the software.
|
||||||
|
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
LIBRARY: LFS - NIST Latent Fingerprint System
|
LIBRARY: LFS - NIST Latent Fingerprint System
|
||||||
|
|
||||||
|
@ -44,8 +65,6 @@ identified are necessarily the best available for the purpose.
|
||||||
***********************************************************************/
|
***********************************************************************/
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <lfs.h>
|
#include <lfs.h>
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
|
@ -86,7 +105,7 @@ int block_offsets(int **optr, int *ow, int *oh,
|
||||||
int *blkoffs, bx, by, bw, bh, bi, bsize;
|
int *blkoffs, bx, by, bw, bh, bi, bsize;
|
||||||
int blkrow_start, blkrow_size, offset;
|
int blkrow_start, blkrow_size, offset;
|
||||||
int lastbw, lastbh;
|
int lastbw, lastbh;
|
||||||
int pad2, pw;
|
int pad2, pw, ph;
|
||||||
|
|
||||||
/* Test if unpadded image is smaller than a single block */
|
/* Test if unpadded image is smaller than a single block */
|
||||||
if((iw < blocksize) || (ih < blocksize)){
|
if((iw < blocksize) || (ih < blocksize)){
|
||||||
|
@ -99,6 +118,7 @@ int block_offsets(int **optr, int *ow, int *oh,
|
||||||
/* Compute padded width and height of image */
|
/* Compute padded width and height of image */
|
||||||
pad2 = pad<<1;
|
pad2 = pad<<1;
|
||||||
pw = iw + pad2;
|
pw = iw + pad2;
|
||||||
|
ph = ih + pad2;
|
||||||
|
|
||||||
/* Compute the number of columns and rows of blocks in the image. */
|
/* Compute the number of columns and rows of blocks in the image. */
|
||||||
/* Take the ceiling to account for "leftovers" at the right and */
|
/* Take the ceiling to account for "leftovers" at the right and */
|
||||||
|
|
211
libfprint/nbis/mindtct/chaincod.c
Normal file
211
libfprint/nbis/mindtct/chaincod.c
Normal file
|
@ -0,0 +1,211 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
|
||||||
|
License:
|
||||||
|
This software and/or related materials 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.
|
||||||
|
|
||||||
|
This software and/or related materials have been determined to be not subject
|
||||||
|
to the EAR (see Part 734.3 of the EAR for exact details) because it is
|
||||||
|
a publicly available technology and software, and is freely distributed
|
||||||
|
to any interested party with no licensing requirements. Therefore, it is
|
||||||
|
permissible to distribute this software as a free download from the internet.
|
||||||
|
|
||||||
|
Disclaimer:
|
||||||
|
This software and/or related materials 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.
|
||||||
|
|
||||||
|
This software and/or related materials are provided "AS-IS" without warranty
|
||||||
|
of any kind including NO WARRANTY OF PERFORMANCE, MERCHANTABILITY,
|
||||||
|
NO WARRANTY OF NON-INFRINGEMENT OF ANY 3RD PARTY INTELLECTUAL PROPERTY
|
||||||
|
or FITNESS FOR A PARTICULAR PURPOSE or for any purpose whatsoever, for the
|
||||||
|
licensed product, however used. In no event shall NIST be liable for any
|
||||||
|
damages and/or costs, including but not limited to incidental or consequential
|
||||||
|
damages of any kind, including economic damage or injury to property and lost
|
||||||
|
profits, regardless of whether NIST shall be advised, have reason to know,
|
||||||
|
or in fact shall know of the possibility.
|
||||||
|
|
||||||
|
By using this software, you agree to bear all risk relating to quality,
|
||||||
|
use and performance of the software and/or related materials. You agree
|
||||||
|
to hold the Government harmless from any claim arising from your use
|
||||||
|
of the software.
|
||||||
|
|
||||||
|
*******************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
LIBRARY: LFS - NIST Latent Fingerprint System
|
||||||
|
|
||||||
|
FILE: CHAINCODE.C
|
||||||
|
AUTHOR: Michael D. Garris
|
||||||
|
DATE: 05/11/1999
|
||||||
|
|
||||||
|
Contains routines responsible for generating and manipulating
|
||||||
|
chain codes as part of the NIST Latent Fingerprint System (LFS).
|
||||||
|
|
||||||
|
***********************************************************************
|
||||||
|
ROUTINES:
|
||||||
|
chain_code_loop()
|
||||||
|
is_chain_clockwise()
|
||||||
|
***********************************************************************/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <lfs.h>
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
#cat: chain_code_loop - Converts a feature's contour points into an
|
||||||
|
#cat: 8-connected chain code vector. This encoding represents
|
||||||
|
#cat: the direction taken between each adjacent point in the
|
||||||
|
#cat: contour. Chain codes may be used for many purposes, such
|
||||||
|
#cat: as computing the perimeter or area of an object, and they
|
||||||
|
#cat: may be used in object detection and recognition.
|
||||||
|
|
||||||
|
Input:
|
||||||
|
contour_x - x-coord list for feature's contour points
|
||||||
|
contour_y - y-coord list for feature's contour points
|
||||||
|
ncontour - number of points in contour
|
||||||
|
Output:
|
||||||
|
ochain - resulting vector of chain codes
|
||||||
|
onchain - number of codes in chain
|
||||||
|
(same as number of points in contour)
|
||||||
|
Return Code:
|
||||||
|
Zero - chain code successful derived
|
||||||
|
Negative - system error
|
||||||
|
**************************************************************************/
|
||||||
|
int chain_code_loop(int **ochain, int *onchain,
|
||||||
|
const int *contour_x, const int *contour_y, const int ncontour)
|
||||||
|
{
|
||||||
|
int *chain;
|
||||||
|
int i, j, dx, dy;
|
||||||
|
|
||||||
|
/* If we don't have at least 3 points in the contour ... */
|
||||||
|
if(ncontour <= 3){
|
||||||
|
/* Then we don't have a loop, so set chain length to 0 */
|
||||||
|
/* and return without any allocations. */
|
||||||
|
*onchain = 0;
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Allocate chain code vector. It will be the same length as the */
|
||||||
|
/* number of points in the contour. There will be one chain code */
|
||||||
|
/* between each point on the contour including a code between the */
|
||||||
|
/* last to the first point on the contour (completing the loop). */
|
||||||
|
chain = (int *)malloc(ncontour * sizeof(int));
|
||||||
|
/* If the allocation fails ... */
|
||||||
|
if(chain == (int *)NULL){
|
||||||
|
fprintf(stderr, "ERROR : chain_code_loop : malloc : chain\n");
|
||||||
|
return(-170);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* For each neighboring point in the list (with "i" pointing to the */
|
||||||
|
/* previous neighbor and "j" pointing to the next neighbor... */
|
||||||
|
for(i = 0, j=1; i < ncontour-1; i++, j++){
|
||||||
|
/* Compute delta in X between neighbors. */
|
||||||
|
dx = contour_x[j] - contour_x[i];
|
||||||
|
/* Compute delta in Y between neighbors. */
|
||||||
|
dy = contour_y[j] - contour_y[i];
|
||||||
|
/* Derive chain code index from neighbor deltas. */
|
||||||
|
/* The deltas are on the range [-1..1], so to use them as indices */
|
||||||
|
/* into the code list, they must first be incremented by one. */
|
||||||
|
chain[i] = *(g_chaincodes_nbr8+((dy+1)*NBR8_DIM)+dx+1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Now derive chain code between last and first points in the */
|
||||||
|
/* contour list. */
|
||||||
|
dx = contour_x[0] - contour_x[i];
|
||||||
|
dy = contour_y[0] - contour_y[i];
|
||||||
|
chain[i] = *(g_chaincodes_nbr8+((dy+1)*NBR8_DIM)+dx+1);
|
||||||
|
|
||||||
|
/* Store results to the output pointers. */
|
||||||
|
*ochain = chain;
|
||||||
|
*onchain = ncontour;
|
||||||
|
|
||||||
|
/* Return normally. */
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
#cat: is_chain_clockwise - Takes an 8-connected chain code vector and
|
||||||
|
#cat: determines if the codes are ordered clockwise or
|
||||||
|
#cat: counter-clockwise.
|
||||||
|
#cat: The routine also requires a default return value be
|
||||||
|
#cat: specified in the case the the routine is not able to
|
||||||
|
#cat: definitively determine the chains direction. This allows
|
||||||
|
#cat: the default response to be application-specific.
|
||||||
|
|
||||||
|
Input:
|
||||||
|
chain - chain code vector
|
||||||
|
nchain - number of codes in chain
|
||||||
|
default_ret - default return code (used when we can't tell the order)
|
||||||
|
Return Code:
|
||||||
|
TRUE - chain determined to be ordered clockwise
|
||||||
|
FALSE - chain determined to be ordered counter-clockwise
|
||||||
|
Default - could not determine the order of the chain
|
||||||
|
**************************************************************************/
|
||||||
|
int is_chain_clockwise(const int *chain, const int nchain,
|
||||||
|
const int default_ret)
|
||||||
|
{
|
||||||
|
int i, j, d, sum;
|
||||||
|
|
||||||
|
/* Initialize turn-accumulator to 0. */
|
||||||
|
sum = 0;
|
||||||
|
|
||||||
|
/* Foreach neighboring code in chain, compute the difference in */
|
||||||
|
/* direction and accumulate. Left-hand turns increment, whereas */
|
||||||
|
/* right-hand decrement. */
|
||||||
|
for(i = 0, j =1; i < nchain-1; i++, j++){
|
||||||
|
/* Compute delta in neighbor direction. */
|
||||||
|
d = chain[j] - chain[i];
|
||||||
|
/* Make the delta the "inner" distance. */
|
||||||
|
/* If delta >= 4, for example if chain_i==2 and chain_j==7 (which */
|
||||||
|
/* means the contour went from a step up to step down-to-the-right) */
|
||||||
|
/* then 5=(7-2) which is >=4, so -3=(5-8) which means that the */
|
||||||
|
/* change in direction is a righ-hand turn of 3 units). */
|
||||||
|
if(d >= 4)
|
||||||
|
d -= 8;
|
||||||
|
/* If delta <= -4, for example if chain_i==7 and chain_j==2 (which */
|
||||||
|
/* means the contour went from a step down-to-the-right to step up) */
|
||||||
|
/* then -5=(2-7) which is <=-4, so 3=(-5+8) which means that the */
|
||||||
|
/* change in direction is a left-hand turn of 3 units). */
|
||||||
|
else if (d <= -4)
|
||||||
|
d += 8;
|
||||||
|
|
||||||
|
/* The delta direction is then accumulated. */
|
||||||
|
sum += d;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Now we need to add in the final delta direction between the last */
|
||||||
|
/* and first codes in the chain. */
|
||||||
|
d = chain[0] - chain[i];
|
||||||
|
if(d >= 4)
|
||||||
|
d -= 8;
|
||||||
|
else if (d <= -4)
|
||||||
|
d += 8;
|
||||||
|
sum += d;
|
||||||
|
|
||||||
|
/* If the final turn_accumulator == 0, then we CAN'T TELL the */
|
||||||
|
/* direction of the chain code, so return the default return value. */
|
||||||
|
if(sum == 0)
|
||||||
|
return(default_ret);
|
||||||
|
/* Otherwise, if the final turn-accumulator is positive ... */
|
||||||
|
else if(sum > 0)
|
||||||
|
/* Then we had a greater amount of left-hand turns than right-hand */
|
||||||
|
/* turns, so the chain is in COUNTER-CLOCKWISE order, so return FALSE. */
|
||||||
|
return(FALSE);
|
||||||
|
/* Otherwise, the final turn-accumulator is negative ... */
|
||||||
|
else
|
||||||
|
/* So we had a greater amount of right-hand turns than left-hand */
|
||||||
|
/* turns, so the chain is in CLOCKWISE order, so return TRUE. */
|
||||||
|
return(TRUE);
|
||||||
|
}
|
|
@ -1,26 +1,47 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
|
|
||||||
License:
|
License:
|
||||||
This software was developed at the National Institute of Standards and
|
This software and/or related materials was developed at the National Institute
|
||||||
Technology (NIST) by employees of the Federal Government in the course
|
of Standards and Technology (NIST) by employees of the Federal Government
|
||||||
of their official duties. Pursuant to title 17 Section 105 of the
|
in the course of their official duties. Pursuant to title 17 Section 105
|
||||||
United States Code, this software is not subject to copyright protection
|
of the United States Code, this software is not subject to copyright
|
||||||
and is in the public domain. NIST assumes no responsibility whatsoever for
|
protection and is in the public domain.
|
||||||
its use by other parties, and makes no guarantees, expressed or implied,
|
|
||||||
about its quality, reliability, or any other characteristic.
|
|
||||||
|
|
||||||
Disclaimer:
|
This software and/or related materials have been determined to be not subject
|
||||||
This software was developed to promote biometric standards and biometric
|
to the EAR (see Part 734.3 of the EAR for exact details) because it is
|
||||||
technology testing for the Federal Government in accordance with the USA
|
a publicly available technology and software, and is freely distributed
|
||||||
PATRIOT Act and the Enhanced Border Security and Visa Entry Reform Act.
|
to any interested party with no licensing requirements. Therefore, it is
|
||||||
Specific hardware and software products identified in this software were used
|
permissible to distribute this software as a free download from the internet.
|
||||||
in order to perform the software development. In no case does such
|
|
||||||
identification imply recommendation or endorsement by the National Institute
|
Disclaimer:
|
||||||
of Standards and Technology, nor does it imply that the products and equipment
|
This software and/or related materials was developed to promote biometric
|
||||||
identified are necessarily the best available for the purpose.
|
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.
|
||||||
|
|
||||||
|
This software and/or related materials are provided "AS-IS" without warranty
|
||||||
|
of any kind including NO WARRANTY OF PERFORMANCE, MERCHANTABILITY,
|
||||||
|
NO WARRANTY OF NON-INFRINGEMENT OF ANY 3RD PARTY INTELLECTUAL PROPERTY
|
||||||
|
or FITNESS FOR A PARTICULAR PURPOSE or for any purpose whatsoever, for the
|
||||||
|
licensed product, however used. In no event shall NIST be liable for any
|
||||||
|
damages and/or costs, including but not limited to incidental or consequential
|
||||||
|
damages of any kind, including economic damage or injury to property and lost
|
||||||
|
profits, regardless of whether NIST shall be advised, have reason to know,
|
||||||
|
or in fact shall know of the possibility.
|
||||||
|
|
||||||
|
By using this software, you agree to bear all risk relating to quality,
|
||||||
|
use and performance of the software and/or related materials. You agree
|
||||||
|
to hold the Government harmless from any claim arising from your use
|
||||||
|
of the software.
|
||||||
|
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
LIBRARY: LFS - NIST Latent Fingerprint System
|
LIBRARY: LFS - NIST Latent Fingerprint System
|
||||||
|
|
||||||
|
@ -50,7 +71,6 @@ identified are necessarily the best available for the purpose.
|
||||||
***********************************************************************/
|
***********************************************************************/
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
|
||||||
#include <lfs.h>
|
#include <lfs.h>
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
|
@ -591,236 +611,6 @@ int get_centered_contour(int **ocontour_x, int **ocontour_y,
|
||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
#cat: start_scan_nbr - Takes a two pixel coordinates that are either
|
|
||||||
#cat: aligned north-to-south or east-to-west, and returns the
|
|
||||||
#cat: position the second pixel is in realtionship to the first.
|
|
||||||
#cat: The positions returned are based on 8-connectedness.
|
|
||||||
#cat: NOTE, this routine does NOT account for diagonal positions.
|
|
||||||
|
|
||||||
Input:
|
|
||||||
x_prev - x-coord of first point
|
|
||||||
y_prev - y-coord of first point
|
|
||||||
x_next - x-coord of second point
|
|
||||||
y_next - y-coord of second point
|
|
||||||
Return Code:
|
|
||||||
NORTH - second pixel above first
|
|
||||||
SOUTH - second pixel below first
|
|
||||||
EAST - second pixel right of first
|
|
||||||
WEST - second pixel left of first
|
|
||||||
**************************************************************************/
|
|
||||||
static int start_scan_nbr(const int x_prev, const int y_prev,
|
|
||||||
const int x_next, const int y_next)
|
|
||||||
{
|
|
||||||
if((x_prev==x_next) && (y_next > y_prev))
|
|
||||||
return(SOUTH);
|
|
||||||
else if ((x_prev==x_next) && (y_next < y_prev))
|
|
||||||
return(NORTH);
|
|
||||||
else if ((x_next > x_prev) && (y_prev==y_next))
|
|
||||||
return(EAST);
|
|
||||||
else if ((x_next < x_prev) && (y_prev==y_next))
|
|
||||||
return(WEST);
|
|
||||||
|
|
||||||
/* Added by MDG on 03-16-05 */
|
|
||||||
/* Should never reach here. Added to remove compiler warning. */
|
|
||||||
return(INVALID_DIR); /* -1 */
|
|
||||||
}
|
|
||||||
|
|
||||||
/*************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
#cat: next_scan_nbr - Advances the given 8-connected neighbor index
|
|
||||||
#cat: on location in the specifiec direction (clockwise or
|
|
||||||
#cat: counter-clockwise).
|
|
||||||
|
|
||||||
Input:
|
|
||||||
nbr_i - current 8-connected neighbor index
|
|
||||||
scan_clock - direction in which the neighbor index is to be advanced
|
|
||||||
Return Code:
|
|
||||||
Next neighbor - 8-connected index of next neighbor
|
|
||||||
**************************************************************************/
|
|
||||||
static int next_scan_nbr(const int nbr_i, const int scan_clock)
|
|
||||||
{
|
|
||||||
int new_i;
|
|
||||||
|
|
||||||
/* If scanning neighbors clockwise ... */
|
|
||||||
if(scan_clock == SCAN_CLOCKWISE)
|
|
||||||
/* Advance one neighbor clockwise. */
|
|
||||||
new_i = (nbr_i+1)%8;
|
|
||||||
/* Otherwise, scanning neighbors counter-clockwise ... */
|
|
||||||
else
|
|
||||||
/* Advance one neighbor counter-clockwise. */
|
|
||||||
/* There are 8 pixels in the neighborhood, so to */
|
|
||||||
/* decrement with wrapping from 0 around to 7, add */
|
|
||||||
/* the nieghbor index by 7 and mod with 8. */
|
|
||||||
new_i = (nbr_i+7)%8;
|
|
||||||
|
|
||||||
/* Return the new neighbor index. */
|
|
||||||
return(new_i);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
#cat: next_contour_pixel - Takes a pixel coordinate of a point determined
|
|
||||||
#cat: to be on the interior edge of a feature (ridge or valley-
|
|
||||||
#cat: ending), and attempts to locate a neighboring pixel on the
|
|
||||||
#cat: feature's contour. Neighbors of the current feature pixel
|
|
||||||
#cat: are searched in a specified direction (clockwise or counter-
|
|
||||||
#cat: clockwise) and the first pair of adjacent/neigboring pixels
|
|
||||||
#cat: found with the first pixel having the color of the feature
|
|
||||||
#cat: and the second the opposite color are returned as the next
|
|
||||||
#cat: point on the contour. One exception happens when the new
|
|
||||||
#cat: point is on an "exposed" corner.
|
|
||||||
|
|
||||||
Input:
|
|
||||||
cur_x_loc - x-pixel coord of current point on feature's
|
|
||||||
interior contour
|
|
||||||
cur_y_loc - y-pixel coord of current point on feature's
|
|
||||||
interior contour
|
|
||||||
cur_x_edge - x-pixel coord of corresponding edge pixel
|
|
||||||
(exterior to feature)
|
|
||||||
cur_y_edge - y-pixel coord of corresponding edge pixel
|
|
||||||
(exterior to feature)
|
|
||||||
scan_clock - direction in which neighboring pixels are to be scanned
|
|
||||||
for the next contour pixel
|
|
||||||
bdata - binary image data (0==while & 1==black)
|
|
||||||
iw - width (in pixels) of image
|
|
||||||
ih - height (in pixels) of image
|
|
||||||
Output:
|
|
||||||
next_x_loc - x-pixel coord of next point on feature's interior contour
|
|
||||||
next_y_loc - y-pixel coord of next point on feature's interior contour
|
|
||||||
next_x_edge - x-pixel coord of corresponding edge (exterior to feature)
|
|
||||||
next_y_edge - y-pixel coord of corresponding edge (exterior to feature)
|
|
||||||
Return Code:
|
|
||||||
TRUE - next contour point found and returned
|
|
||||||
FALSE - next contour point NOT found
|
|
||||||
**************************************************************************/
|
|
||||||
/*************************************************************************/
|
|
||||||
static int next_contour_pixel(int *next_x_loc, int *next_y_loc,
|
|
||||||
int *next_x_edge, int *next_y_edge,
|
|
||||||
const int cur_x_loc, const int cur_y_loc,
|
|
||||||
const int cur_x_edge, const int cur_y_edge,
|
|
||||||
const int scan_clock,
|
|
||||||
unsigned char *bdata, const int iw, const int ih)
|
|
||||||
{
|
|
||||||
int feature_pix, edge_pix;
|
|
||||||
int prev_nbr_pix, prev_nbr_x, prev_nbr_y;
|
|
||||||
int cur_nbr_pix, cur_nbr_x, cur_nbr_y;
|
|
||||||
int ni, nx, ny, npix;
|
|
||||||
int nbr_i, i;
|
|
||||||
|
|
||||||
/* Get the feature's pixel value. */
|
|
||||||
feature_pix = *(bdata + (cur_y_loc * iw) + cur_x_loc);
|
|
||||||
/* Get the feature's edge pixel value. */
|
|
||||||
edge_pix = *(bdata + (cur_y_edge * iw) + cur_x_edge);
|
|
||||||
|
|
||||||
/* Get the nieghbor position of the feature's edge pixel in relationship */
|
|
||||||
/* to the feature's actual position. */
|
|
||||||
/* REMEBER: The feature's position is always interior and on a ridge */
|
|
||||||
/* ending (black pixel) or (for bifurcations) on a valley ending (white */
|
|
||||||
/* pixel). The feature's edge pixel is an adjacent pixel to the feature */
|
|
||||||
/* pixel that is exterior to the ridge or valley ending and opposite in */
|
|
||||||
/* pixel value. */
|
|
||||||
nbr_i = start_scan_nbr(cur_x_loc, cur_y_loc, cur_x_edge, cur_y_edge);
|
|
||||||
|
|
||||||
/* Set current neighbor scan pixel to the feature's edge pixel. */
|
|
||||||
cur_nbr_x = cur_x_edge;
|
|
||||||
cur_nbr_y = cur_y_edge;
|
|
||||||
cur_nbr_pix = edge_pix;
|
|
||||||
|
|
||||||
/* Foreach pixel neighboring the feature pixel ... */
|
|
||||||
for(i = 0; i < 8; i++){
|
|
||||||
|
|
||||||
/* Set current neighbor scan pixel to previous scan pixel. */
|
|
||||||
prev_nbr_x = cur_nbr_x;
|
|
||||||
prev_nbr_y = cur_nbr_y;
|
|
||||||
prev_nbr_pix = cur_nbr_pix;
|
|
||||||
|
|
||||||
/* Bump pixel neighbor index clockwise or counter-clockwise. */
|
|
||||||
nbr_i = next_scan_nbr(nbr_i, scan_clock);
|
|
||||||
|
|
||||||
/* Set current scan pixel to the new neighbor. */
|
|
||||||
/* REMEMBER: the neighbors are being scanned around the original */
|
|
||||||
/* feature point. */
|
|
||||||
cur_nbr_x = cur_x_loc + g_nbr8_dx[nbr_i];
|
|
||||||
cur_nbr_y = cur_y_loc + g_nbr8_dy[nbr_i];
|
|
||||||
|
|
||||||
/* If new neighbor is not within image boundaries... */
|
|
||||||
if((cur_nbr_x < 0) || (cur_nbr_x >= iw) ||
|
|
||||||
(cur_nbr_y < 0) || (cur_nbr_y >= ih))
|
|
||||||
/* Return (FALSE==>Failure) if neighbor out of bounds. */
|
|
||||||
return(FALSE);
|
|
||||||
|
|
||||||
/* Get the new neighbor's pixel value. */
|
|
||||||
cur_nbr_pix = *(bdata + (cur_nbr_y * iw) + cur_nbr_x);
|
|
||||||
|
|
||||||
/* If the new neighbor's pixel value is the same as the feature's */
|
|
||||||
/* pixel value AND the previous neighbor's pixel value is the same */
|
|
||||||
/* as the features's edge, then we have "likely" found our next */
|
|
||||||
/* contour pixel. */
|
|
||||||
if((cur_nbr_pix == feature_pix) && (prev_nbr_pix == edge_pix)){
|
|
||||||
|
|
||||||
/* Check to see if current neighbor is on the corner of the */
|
|
||||||
/* neighborhood, and if so, test to see if it is "exposed". */
|
|
||||||
/* The neighborhood corners have odd neighbor indicies. */
|
|
||||||
if(nbr_i % 2){
|
|
||||||
/* To do this, look ahead one more neighbor pixel. */
|
|
||||||
ni = next_scan_nbr(nbr_i, scan_clock);
|
|
||||||
nx = cur_x_loc + g_nbr8_dx[ni];
|
|
||||||
ny = cur_y_loc + g_nbr8_dy[ni];
|
|
||||||
/* If new neighbor is not within image boundaries... */
|
|
||||||
if((nx < 0) || (nx >= iw) ||
|
|
||||||
(ny < 0) || (ny >= ih))
|
|
||||||
/* Return (FALSE==>Failure) if neighbor out of bounds. */
|
|
||||||
return(FALSE);
|
|
||||||
npix = *(bdata + (ny * iw) + nx);
|
|
||||||
|
|
||||||
/* If the next neighbor's value is also the same as the */
|
|
||||||
/* feature's pixel, then corner is NOT exposed... */
|
|
||||||
if(npix == feature_pix){
|
|
||||||
/* Assign the current neighbor pair to the output pointers. */
|
|
||||||
*next_x_loc = cur_nbr_x;
|
|
||||||
*next_y_loc = cur_nbr_y;
|
|
||||||
*next_x_edge = prev_nbr_x;
|
|
||||||
*next_y_edge = prev_nbr_y;
|
|
||||||
/* Return TRUE==>Success. */
|
|
||||||
return(TRUE);
|
|
||||||
}
|
|
||||||
/* Otherwise, corner pixel is "exposed" so skip it. */
|
|
||||||
else{
|
|
||||||
/* Skip current corner neighbor by resetting it to the */
|
|
||||||
/* next neighbor, which upon the iteration will immediately */
|
|
||||||
/* become the previous neighbor. */
|
|
||||||
cur_nbr_x = nx;
|
|
||||||
cur_nbr_y = ny;
|
|
||||||
cur_nbr_pix = npix;
|
|
||||||
/* Advance neighbor index. */
|
|
||||||
nbr_i = ni;
|
|
||||||
/* Advance neighbor count. */
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/* Otherwise, current neighbor is not a corner ... */
|
|
||||||
else{
|
|
||||||
/* Assign the current neighbor pair to the output pointers. */
|
|
||||||
*next_x_loc = cur_nbr_x;
|
|
||||||
*next_y_loc = cur_nbr_y;
|
|
||||||
*next_x_edge = prev_nbr_x;
|
|
||||||
*next_y_edge = prev_nbr_y;
|
|
||||||
/* Return TRUE==>Success. */
|
|
||||||
return(TRUE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* If we get here, then we did not find the next contour pixel */
|
|
||||||
/* within the 8 neighbors of the current feature pixel so */
|
|
||||||
/* return (FALSE==>Failure). */
|
|
||||||
/* NOTE: This must mean we found a single isolated pixel. */
|
|
||||||
/* Perhaps this should be filled? */
|
|
||||||
return(FALSE);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
**************************************************************************
|
**************************************************************************
|
||||||
#cat: trace_contour - Takes the pixel coordinate of a detected minutia
|
#cat: trace_contour - Takes the pixel coordinate of a detected minutia
|
||||||
|
@ -1046,6 +836,236 @@ int search_contour(const int x_search, const int y_search,
|
||||||
return(NOT_FOUND);
|
return(NOT_FOUND);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
#cat: next_contour_pixel - Takes a pixel coordinate of a point determined
|
||||||
|
#cat: to be on the interior edge of a feature (ridge or valley-
|
||||||
|
#cat: ending), and attempts to locate a neighboring pixel on the
|
||||||
|
#cat: feature's contour. Neighbors of the current feature pixel
|
||||||
|
#cat: are searched in a specified direction (clockwise or counter-
|
||||||
|
#cat: clockwise) and the first pair of adjacent/neigboring pixels
|
||||||
|
#cat: found with the first pixel having the color of the feature
|
||||||
|
#cat: and the second the opposite color are returned as the next
|
||||||
|
#cat: point on the contour. One exception happens when the new
|
||||||
|
#cat: point is on an "exposed" corner.
|
||||||
|
|
||||||
|
Input:
|
||||||
|
cur_x_loc - x-pixel coord of current point on feature's
|
||||||
|
interior contour
|
||||||
|
cur_y_loc - y-pixel coord of current point on feature's
|
||||||
|
interior contour
|
||||||
|
cur_x_edge - x-pixel coord of corresponding edge pixel
|
||||||
|
(exterior to feature)
|
||||||
|
cur_y_edge - y-pixel coord of corresponding edge pixel
|
||||||
|
(exterior to feature)
|
||||||
|
scan_clock - direction in which neighboring pixels are to be scanned
|
||||||
|
for the next contour pixel
|
||||||
|
bdata - binary image data (0==while & 1==black)
|
||||||
|
iw - width (in pixels) of image
|
||||||
|
ih - height (in pixels) of image
|
||||||
|
Output:
|
||||||
|
next_x_loc - x-pixel coord of next point on feature's interior contour
|
||||||
|
next_y_loc - y-pixel coord of next point on feature's interior contour
|
||||||
|
next_x_edge - x-pixel coord of corresponding edge (exterior to feature)
|
||||||
|
next_y_edge - y-pixel coord of corresponding edge (exterior to feature)
|
||||||
|
Return Code:
|
||||||
|
TRUE - next contour point found and returned
|
||||||
|
FALSE - next contour point NOT found
|
||||||
|
**************************************************************************/
|
||||||
|
/*************************************************************************/
|
||||||
|
int next_contour_pixel(int *next_x_loc, int *next_y_loc,
|
||||||
|
int *next_x_edge, int *next_y_edge,
|
||||||
|
const int cur_x_loc, const int cur_y_loc,
|
||||||
|
const int cur_x_edge, const int cur_y_edge,
|
||||||
|
const int scan_clock,
|
||||||
|
unsigned char *bdata, const int iw, const int ih)
|
||||||
|
{
|
||||||
|
int feature_pix, edge_pix;
|
||||||
|
int prev_nbr_pix, prev_nbr_x, prev_nbr_y;
|
||||||
|
int cur_nbr_pix, cur_nbr_x, cur_nbr_y;
|
||||||
|
int ni, nx, ny, npix;
|
||||||
|
int nbr_i, i;
|
||||||
|
|
||||||
|
/* Get the feature's pixel value. */
|
||||||
|
feature_pix = *(bdata + (cur_y_loc * iw) + cur_x_loc);
|
||||||
|
/* Get the feature's edge pixel value. */
|
||||||
|
edge_pix = *(bdata + (cur_y_edge * iw) + cur_x_edge);
|
||||||
|
|
||||||
|
/* Get the nieghbor position of the feature's edge pixel in relationship */
|
||||||
|
/* to the feature's actual position. */
|
||||||
|
/* REMEBER: The feature's position is always interior and on a ridge */
|
||||||
|
/* ending (black pixel) or (for bifurcations) on a valley ending (white */
|
||||||
|
/* pixel). The feature's edge pixel is an adjacent pixel to the feature */
|
||||||
|
/* pixel that is exterior to the ridge or valley ending and opposite in */
|
||||||
|
/* pixel value. */
|
||||||
|
nbr_i = start_scan_nbr(cur_x_loc, cur_y_loc, cur_x_edge, cur_y_edge);
|
||||||
|
|
||||||
|
/* Set current neighbor scan pixel to the feature's edge pixel. */
|
||||||
|
cur_nbr_x = cur_x_edge;
|
||||||
|
cur_nbr_y = cur_y_edge;
|
||||||
|
cur_nbr_pix = edge_pix;
|
||||||
|
|
||||||
|
/* Foreach pixel neighboring the feature pixel ... */
|
||||||
|
for(i = 0; i < 8; i++){
|
||||||
|
|
||||||
|
/* Set current neighbor scan pixel to previous scan pixel. */
|
||||||
|
prev_nbr_x = cur_nbr_x;
|
||||||
|
prev_nbr_y = cur_nbr_y;
|
||||||
|
prev_nbr_pix = cur_nbr_pix;
|
||||||
|
|
||||||
|
/* Bump pixel neighbor index clockwise or counter-clockwise. */
|
||||||
|
nbr_i = next_scan_nbr(nbr_i, scan_clock);
|
||||||
|
|
||||||
|
/* Set current scan pixel to the new neighbor. */
|
||||||
|
/* REMEMBER: the neighbors are being scanned around the original */
|
||||||
|
/* feature point. */
|
||||||
|
cur_nbr_x = cur_x_loc + g_nbr8_dx[nbr_i];
|
||||||
|
cur_nbr_y = cur_y_loc + g_nbr8_dy[nbr_i];
|
||||||
|
|
||||||
|
/* If new neighbor is not within image boundaries... */
|
||||||
|
if((cur_nbr_x < 0) || (cur_nbr_x >= iw) ||
|
||||||
|
(cur_nbr_y < 0) || (cur_nbr_y >= ih))
|
||||||
|
/* Return (FALSE==>Failure) if neighbor out of bounds. */
|
||||||
|
return(FALSE);
|
||||||
|
|
||||||
|
/* Get the new neighbor's pixel value. */
|
||||||
|
cur_nbr_pix = *(bdata + (cur_nbr_y * iw) + cur_nbr_x);
|
||||||
|
|
||||||
|
/* If the new neighbor's pixel value is the same as the feature's */
|
||||||
|
/* pixel value AND the previous neighbor's pixel value is the same */
|
||||||
|
/* as the features's edge, then we have "likely" found our next */
|
||||||
|
/* contour pixel. */
|
||||||
|
if((cur_nbr_pix == feature_pix) && (prev_nbr_pix == edge_pix)){
|
||||||
|
|
||||||
|
/* Check to see if current neighbor is on the corner of the */
|
||||||
|
/* neighborhood, and if so, test to see if it is "exposed". */
|
||||||
|
/* The neighborhood corners have odd neighbor indicies. */
|
||||||
|
if(nbr_i % 2){
|
||||||
|
/* To do this, look ahead one more neighbor pixel. */
|
||||||
|
ni = next_scan_nbr(nbr_i, scan_clock);
|
||||||
|
nx = cur_x_loc + g_nbr8_dx[ni];
|
||||||
|
ny = cur_y_loc + g_nbr8_dy[ni];
|
||||||
|
/* If new neighbor is not within image boundaries... */
|
||||||
|
if((nx < 0) || (nx >= iw) ||
|
||||||
|
(ny < 0) || (ny >= ih))
|
||||||
|
/* Return (FALSE==>Failure) if neighbor out of bounds. */
|
||||||
|
return(FALSE);
|
||||||
|
npix = *(bdata + (ny * iw) + nx);
|
||||||
|
|
||||||
|
/* If the next neighbor's value is also the same as the */
|
||||||
|
/* feature's pixel, then corner is NOT exposed... */
|
||||||
|
if(npix == feature_pix){
|
||||||
|
/* Assign the current neighbor pair to the output pointers. */
|
||||||
|
*next_x_loc = cur_nbr_x;
|
||||||
|
*next_y_loc = cur_nbr_y;
|
||||||
|
*next_x_edge = prev_nbr_x;
|
||||||
|
*next_y_edge = prev_nbr_y;
|
||||||
|
/* Return TRUE==>Success. */
|
||||||
|
return(TRUE);
|
||||||
|
}
|
||||||
|
/* Otherwise, corner pixel is "exposed" so skip it. */
|
||||||
|
else{
|
||||||
|
/* Skip current corner neighbor by resetting it to the */
|
||||||
|
/* next neighbor, which upon the iteration will immediately */
|
||||||
|
/* become the previous neighbor. */
|
||||||
|
cur_nbr_x = nx;
|
||||||
|
cur_nbr_y = ny;
|
||||||
|
cur_nbr_pix = npix;
|
||||||
|
/* Advance neighbor index. */
|
||||||
|
nbr_i = ni;
|
||||||
|
/* Advance neighbor count. */
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* Otherwise, current neighbor is not a corner ... */
|
||||||
|
else{
|
||||||
|
/* Assign the current neighbor pair to the output pointers. */
|
||||||
|
*next_x_loc = cur_nbr_x;
|
||||||
|
*next_y_loc = cur_nbr_y;
|
||||||
|
*next_x_edge = prev_nbr_x;
|
||||||
|
*next_y_edge = prev_nbr_y;
|
||||||
|
/* Return TRUE==>Success. */
|
||||||
|
return(TRUE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If we get here, then we did not find the next contour pixel */
|
||||||
|
/* within the 8 neighbors of the current feature pixel so */
|
||||||
|
/* return (FALSE==>Failure). */
|
||||||
|
/* NOTE: This must mean we found a single isolated pixel. */
|
||||||
|
/* Perhaps this should be filled? */
|
||||||
|
return(FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
#cat: start_scan_nbr - Takes a two pixel coordinates that are either
|
||||||
|
#cat: aligned north-to-south or east-to-west, and returns the
|
||||||
|
#cat: position the second pixel is in realtionship to the first.
|
||||||
|
#cat: The positions returned are based on 8-connectedness.
|
||||||
|
#cat: NOTE, this routine does NOT account for diagonal positions.
|
||||||
|
|
||||||
|
Input:
|
||||||
|
x_prev - x-coord of first point
|
||||||
|
y_prev - y-coord of first point
|
||||||
|
x_next - x-coord of second point
|
||||||
|
y_next - y-coord of second point
|
||||||
|
Return Code:
|
||||||
|
NORTH - second pixel above first
|
||||||
|
SOUTH - second pixel below first
|
||||||
|
EAST - second pixel right of first
|
||||||
|
WEST - second pixel left of first
|
||||||
|
**************************************************************************/
|
||||||
|
int start_scan_nbr(const int x_prev, const int y_prev,
|
||||||
|
const int x_next, const int y_next)
|
||||||
|
{
|
||||||
|
if((x_prev==x_next) && (y_next > y_prev))
|
||||||
|
return(SOUTH);
|
||||||
|
else if ((x_prev==x_next) && (y_next < y_prev))
|
||||||
|
return(NORTH);
|
||||||
|
else if ((x_next > x_prev) && (y_prev==y_next))
|
||||||
|
return(EAST);
|
||||||
|
else if ((x_next < x_prev) && (y_prev==y_next))
|
||||||
|
return(WEST);
|
||||||
|
|
||||||
|
/* Added by MDG on 03-16-05 */
|
||||||
|
/* Should never reach here. Added to remove compiler warning. */
|
||||||
|
return(INVALID_DIR); /* -1 */
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
#cat: next_scan_nbr - Advances the given 8-connected neighbor index
|
||||||
|
#cat: on location in the specifiec direction (clockwise or
|
||||||
|
#cat: counter-clockwise).
|
||||||
|
|
||||||
|
Input:
|
||||||
|
nbr_i - current 8-connected neighbor index
|
||||||
|
scan_clock - direction in which the neighbor index is to be advanced
|
||||||
|
Return Code:
|
||||||
|
Next neighbor - 8-connected index of next neighbor
|
||||||
|
**************************************************************************/
|
||||||
|
int next_scan_nbr(const int nbr_i, const int scan_clock)
|
||||||
|
{
|
||||||
|
int new_i;
|
||||||
|
|
||||||
|
/* If scanning neighbors clockwise ... */
|
||||||
|
if(scan_clock == SCAN_CLOCKWISE)
|
||||||
|
/* Advance one neighbor clockwise. */
|
||||||
|
new_i = (nbr_i+1)%8;
|
||||||
|
/* Otherwise, scanning neighbors counter-clockwise ... */
|
||||||
|
else
|
||||||
|
/* Advance one neighbor counter-clockwise. */
|
||||||
|
/* There are 8 pixels in the neighborhood, so to */
|
||||||
|
/* decrement with wrapping from 0 around to 7, add */
|
||||||
|
/* the nieghbor index by 7 and mod with 8. */
|
||||||
|
new_i = (nbr_i+7)%8;
|
||||||
|
|
||||||
|
/* Return the new neighbor index. */
|
||||||
|
return(new_i);
|
||||||
|
}
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
**************************************************************************
|
**************************************************************************
|
||||||
#cat: min_contour_theta - Takes a contour list and analyzes it locating the
|
#cat: min_contour_theta - Takes a contour list and analyzes it locating the
|
||||||
|
|
|
@ -1,26 +1,47 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
|
|
||||||
License:
|
License:
|
||||||
This software was developed at the National Institute of Standards and
|
This software and/or related materials was developed at the National Institute
|
||||||
Technology (NIST) by employees of the Federal Government in the course
|
of Standards and Technology (NIST) by employees of the Federal Government
|
||||||
of their official duties. Pursuant to title 17 Section 105 of the
|
in the course of their official duties. Pursuant to title 17 Section 105
|
||||||
United States Code, this software is not subject to copyright protection
|
of the United States Code, this software is not subject to copyright
|
||||||
and is in the public domain. NIST assumes no responsibility whatsoever for
|
protection and is in the public domain.
|
||||||
its use by other parties, and makes no guarantees, expressed or implied,
|
|
||||||
about its quality, reliability, or any other characteristic.
|
|
||||||
|
|
||||||
Disclaimer:
|
This software and/or related materials have been determined to be not subject
|
||||||
This software was developed to promote biometric standards and biometric
|
to the EAR (see Part 734.3 of the EAR for exact details) because it is
|
||||||
technology testing for the Federal Government in accordance with the USA
|
a publicly available technology and software, and is freely distributed
|
||||||
PATRIOT Act and the Enhanced Border Security and Visa Entry Reform Act.
|
to any interested party with no licensing requirements. Therefore, it is
|
||||||
Specific hardware and software products identified in this software were used
|
permissible to distribute this software as a free download from the internet.
|
||||||
in order to perform the software development. In no case does such
|
|
||||||
identification imply recommendation or endorsement by the National Institute
|
Disclaimer:
|
||||||
of Standards and Technology, nor does it imply that the products and equipment
|
This software and/or related materials was developed to promote biometric
|
||||||
identified are necessarily the best available for the purpose.
|
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.
|
||||||
|
|
||||||
|
This software and/or related materials are provided "AS-IS" without warranty
|
||||||
|
of any kind including NO WARRANTY OF PERFORMANCE, MERCHANTABILITY,
|
||||||
|
NO WARRANTY OF NON-INFRINGEMENT OF ANY 3RD PARTY INTELLECTUAL PROPERTY
|
||||||
|
or FITNESS FOR A PARTICULAR PURPOSE or for any purpose whatsoever, for the
|
||||||
|
licensed product, however used. In no event shall NIST be liable for any
|
||||||
|
damages and/or costs, including but not limited to incidental or consequential
|
||||||
|
damages of any kind, including economic damage or injury to property and lost
|
||||||
|
profits, regardless of whether NIST shall be advised, have reason to know,
|
||||||
|
or in fact shall know of the possibility.
|
||||||
|
|
||||||
|
By using this software, you agree to bear all risk relating to quality,
|
||||||
|
use and performance of the software and/or related materials. You agree
|
||||||
|
to hold the Government harmless from any claim arising from your use
|
||||||
|
of the software.
|
||||||
|
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
LIBRARY: LFS - NIST Latent Fingerprint System
|
LIBRARY: LFS - NIST Latent Fingerprint System
|
||||||
|
|
||||||
|
@ -35,16 +56,46 @@ identified are necessarily the best available for the purpose.
|
||||||
|
|
||||||
***********************************************************************
|
***********************************************************************
|
||||||
ROUTINES:
|
ROUTINES:
|
||||||
|
lfs_detect_minutiae()
|
||||||
lfs_detect_minutiae_V2()
|
lfs_detect_minutiae_V2()
|
||||||
get_minutiae()
|
|
||||||
|
|
||||||
***********************************************************************/
|
***********************************************************************/
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
|
||||||
#include <lfs.h>
|
#include <lfs.h>
|
||||||
|
#include <mytime.h>
|
||||||
#include <log.h>
|
#include <log.h>
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
#cat: lfs_detect_minutiae - Takes a grayscale fingerprint image (of arbitrary
|
||||||
|
#cat: size), and returns a map of directional ridge flow in the image
|
||||||
|
#cat: (2 versions), a binarized image designating ridges from valleys,
|
||||||
|
#cat: and a list of minutiae (including position, type, direction,
|
||||||
|
#cat: neighbors, and ridge counts to neighbors).
|
||||||
|
|
||||||
|
Input:
|
||||||
|
idata - input 8-bit grayscale fingerprint image data
|
||||||
|
iw - width (in pixels) of the image
|
||||||
|
ih - height (in pixels) of the image
|
||||||
|
lfsparms - parameters and thresholds for controlling LFS
|
||||||
|
Output:
|
||||||
|
ominutiae - resulting list of minutiae
|
||||||
|
oimap - resulting IMAP
|
||||||
|
{invalid (-1) or valid ridge directions}
|
||||||
|
onmap - resulting NMAP
|
||||||
|
{invalid (-1), high-curvature (-2), blanked blocks {-3} or
|
||||||
|
valid ridge directions}
|
||||||
|
omw - width (in blocks) of image maps
|
||||||
|
omh - height (in blocks) of image maps
|
||||||
|
obdata - resulting binarized image
|
||||||
|
{0 = black pixel (ridge) and 255 = white pixel (valley)}
|
||||||
|
obw - width (in pixels) of the binary image
|
||||||
|
obh - height (in pixels) of the binary image
|
||||||
|
Return Code:
|
||||||
|
Zero - successful completion
|
||||||
|
Negative - system error
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
#cat: lfs_detect_minutiae_V2 - Takes a grayscale fingerprint image (of
|
#cat: lfs_detect_minutiae_V2 - Takes a grayscale fingerprint image (of
|
||||||
#cat: arbitrary size), and returns a set of image block maps,
|
#cat: arbitrary size), and returns a set of image block maps,
|
||||||
|
@ -81,7 +132,7 @@ identified are necessarily the best available for the purpose.
|
||||||
Zero - successful completion
|
Zero - successful completion
|
||||||
Negative - system error
|
Negative - system error
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
static int lfs_detect_minutiae_V2(MINUTIAE **ominutiae,
|
int lfs_detect_minutiae_V2(MINUTIAE **ominutiae,
|
||||||
int **odmap, int **olcmap, int **olfmap, int **ohcmap,
|
int **odmap, int **olcmap, int **olfmap, int **ohcmap,
|
||||||
int *omw, int *omh,
|
int *omw, int *omh,
|
||||||
unsigned char **obdata, int *obw, int *obh,
|
unsigned char **obdata, int *obw, int *obh,
|
||||||
|
@ -99,6 +150,8 @@ static int lfs_detect_minutiae_V2(MINUTIAE **ominutiae,
|
||||||
int ret, maxpad;
|
int ret, maxpad;
|
||||||
MINUTIAE *minutiae;
|
MINUTIAE *minutiae;
|
||||||
|
|
||||||
|
set_timer(total_timer);
|
||||||
|
|
||||||
/******************/
|
/******************/
|
||||||
/* INITIALIZATION */
|
/* INITIALIZATION */
|
||||||
/******************/
|
/******************/
|
||||||
|
@ -181,6 +234,7 @@ static int lfs_detect_minutiae_V2(MINUTIAE **ominutiae,
|
||||||
/******************/
|
/******************/
|
||||||
/* MAPS */
|
/* MAPS */
|
||||||
/******************/
|
/******************/
|
||||||
|
set_timer(imap_timer);
|
||||||
|
|
||||||
/* Generate block maps from the input image. */
|
/* Generate block maps from the input image. */
|
||||||
if((ret = gen_image_maps(&direction_map, &low_contrast_map,
|
if((ret = gen_image_maps(&direction_map, &low_contrast_map,
|
||||||
|
@ -200,9 +254,12 @@ static int lfs_detect_minutiae_V2(MINUTIAE **ominutiae,
|
||||||
|
|
||||||
print2log("\nMAPS DONE\n");
|
print2log("\nMAPS DONE\n");
|
||||||
|
|
||||||
|
time_accum(imap_timer, imap_time);
|
||||||
|
|
||||||
/******************/
|
/******************/
|
||||||
/* BINARIZARION */
|
/* BINARIZARION */
|
||||||
/******************/
|
/******************/
|
||||||
|
set_timer(bin_timer);
|
||||||
|
|
||||||
/* Initialize lookup table for pixel offsets to rotated grids */
|
/* Initialize lookup table for pixel offsets to rotated grids */
|
||||||
/* used for directional binarization. */
|
/* used for directional binarization. */
|
||||||
|
@ -254,9 +311,12 @@ static int lfs_detect_minutiae_V2(MINUTIAE **ominutiae,
|
||||||
|
|
||||||
print2log("\nBINARIZATION DONE\n");
|
print2log("\nBINARIZATION DONE\n");
|
||||||
|
|
||||||
|
time_accum(bin_timer, bin_time);
|
||||||
|
|
||||||
/******************/
|
/******************/
|
||||||
/* DETECTION */
|
/* DETECTION */
|
||||||
/******************/
|
/******************/
|
||||||
|
set_timer(minutia_timer);
|
||||||
|
|
||||||
/* Convert 8-bit grayscale binary image [0,255] to */
|
/* Convert 8-bit grayscale binary image [0,255] to */
|
||||||
/* 8-bit binary image [0,1]. */
|
/* 8-bit binary image [0,1]. */
|
||||||
|
@ -281,6 +341,10 @@ static int lfs_detect_minutiae_V2(MINUTIAE **ominutiae,
|
||||||
return(ret);
|
return(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
time_accum(minutia_timer, minutia_time);
|
||||||
|
|
||||||
|
set_timer(rm_minutia_timer);
|
||||||
|
|
||||||
if((ret = remove_false_minutia_V2(minutiae, bdata, iw, ih,
|
if((ret = remove_false_minutia_V2(minutiae, bdata, iw, ih,
|
||||||
direction_map, low_flow_map, high_curve_map, mw, mh,
|
direction_map, low_flow_map, high_curve_map, mw, mh,
|
||||||
lfsparms))){
|
lfsparms))){
|
||||||
|
@ -297,9 +361,13 @@ static int lfs_detect_minutiae_V2(MINUTIAE **ominutiae,
|
||||||
|
|
||||||
print2log("\nMINUTIA DETECTION DONE\n");
|
print2log("\nMINUTIA DETECTION DONE\n");
|
||||||
|
|
||||||
|
time_accum(rm_minutia_timer, rm_minutia_time);
|
||||||
|
|
||||||
/******************/
|
/******************/
|
||||||
/* RIDGE COUNTS */
|
/* RIDGE COUNTS */
|
||||||
/******************/
|
/******************/
|
||||||
|
set_timer(ridge_count_timer);
|
||||||
|
|
||||||
if((ret = count_minutiae_ridges(minutiae, bdata, iw, ih, lfsparms))){
|
if((ret = count_minutiae_ridges(minutiae, bdata, iw, ih, lfsparms))){
|
||||||
/* Free memory allocated to this point. */
|
/* Free memory allocated to this point. */
|
||||||
free(pdata);
|
free(pdata);
|
||||||
|
@ -314,6 +382,8 @@ static int lfs_detect_minutiae_V2(MINUTIAE **ominutiae,
|
||||||
|
|
||||||
print2log("\nNEIGHBOR RIDGE COUNT DONE\n");
|
print2log("\nNEIGHBOR RIDGE COUNT DONE\n");
|
||||||
|
|
||||||
|
time_accum(ridge_count_timer, ridge_count_time);
|
||||||
|
|
||||||
/******************/
|
/******************/
|
||||||
/* WRAP-UP */
|
/* WRAP-UP */
|
||||||
/******************/
|
/******************/
|
||||||
|
@ -337,6 +407,28 @@ static int lfs_detect_minutiae_V2(MINUTIAE **ominutiae,
|
||||||
*obh = bh;
|
*obh = bh;
|
||||||
*ominutiae = minutiae;
|
*ominutiae = minutiae;
|
||||||
|
|
||||||
|
time_accum(total_timer, total_time);
|
||||||
|
|
||||||
|
/******************/
|
||||||
|
/* PRINT TIMINGS */
|
||||||
|
/******************/
|
||||||
|
/* These Timings will print when TIMER is defined. */
|
||||||
|
/* print MAP generation timing statistics */
|
||||||
|
print_time(stderr, "TIMER: MAPS time = %f (secs)\n", imap_time);
|
||||||
|
/* print binarization timing statistics */
|
||||||
|
print_time(stderr, "TIMER: Binarization time = %f (secs)\n", bin_time);
|
||||||
|
/* print minutia detection timing statistics */
|
||||||
|
print_time(stderr, "TIMER: Minutia Detection time = %f (secs)\n",
|
||||||
|
minutia_time);
|
||||||
|
/* print minutia removal timing statistics */
|
||||||
|
print_time(stderr, "TIMER: Minutia Removal time = %f (secs)\n",
|
||||||
|
rm_minutia_time);
|
||||||
|
/* print neighbor ridge count timing statistics */
|
||||||
|
print_time(stderr, "TIMER: Neighbor Ridge Counting time = %f (secs)\n",
|
||||||
|
ridge_count_time);
|
||||||
|
/* print total timing statistics */
|
||||||
|
print_time(stderr, "TIMER: Total time = %f (secs)\n", total_time);
|
||||||
|
|
||||||
/* If LOG_REPORT defined, close log report file. */
|
/* If LOG_REPORT defined, close log report file. */
|
||||||
if((ret = close_logfile()))
|
if((ret = close_logfile()))
|
||||||
return(ret);
|
return(ret);
|
||||||
|
@ -344,112 +436,3 @@ static int lfs_detect_minutiae_V2(MINUTIAE **ominutiae,
|
||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
#cat: get_minutiae - Takes a grayscale fingerprint image, binarizes the input
|
|
||||||
#cat: image, and detects minutiae points using LFS Version 2.
|
|
||||||
#cat: The routine passes back the detected minutiae, the
|
|
||||||
#cat: binarized image, and a set of image quality maps.
|
|
||||||
|
|
||||||
Input:
|
|
||||||
idata - grayscale fingerprint image data
|
|
||||||
iw - width (in pixels) of the grayscale image
|
|
||||||
ih - height (in pixels) of the grayscale image
|
|
||||||
id - pixel depth (in bits) of the grayscale image
|
|
||||||
ppmm - the scan resolution (in pixels/mm) of the grayscale image
|
|
||||||
lfsparms - parameters and thresholds for controlling LFS
|
|
||||||
Output:
|
|
||||||
ominutiae - points to a structure containing the
|
|
||||||
detected minutiae
|
|
||||||
oquality_map - resulting integrated image quality map
|
|
||||||
odirection_map - resulting direction map
|
|
||||||
olow_contrast_map - resulting low contrast map
|
|
||||||
olow_flow_map - resulting low ridge flow map
|
|
||||||
ohigh_curve_map - resulting high curvature map
|
|
||||||
omap_w - width (in blocks) of image maps
|
|
||||||
omap_h - height (in blocks) of image maps
|
|
||||||
obdata - points to binarized image data
|
|
||||||
obw - width (in pixels) of binarized image
|
|
||||||
obh - height (in pixels) of binarized image
|
|
||||||
obd - pixel depth (in bits) of binarized image
|
|
||||||
Return Code:
|
|
||||||
Zero - successful completion
|
|
||||||
Negative - system error
|
|
||||||
**************************************************************************/
|
|
||||||
int get_minutiae(MINUTIAE **ominutiae, int **oquality_map,
|
|
||||||
int **odirection_map, int **olow_contrast_map,
|
|
||||||
int **olow_flow_map, int **ohigh_curve_map,
|
|
||||||
int *omap_w, int *omap_h,
|
|
||||||
unsigned char **obdata, int *obw, int *obh, int *obd,
|
|
||||||
unsigned char *idata, const int iw, const int ih,
|
|
||||||
const int id, const double ppmm, const LFSPARMS *lfsparms)
|
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
MINUTIAE *minutiae = NULL;
|
|
||||||
int *direction_map = NULL, *low_contrast_map = NULL, *low_flow_map = NULL;
|
|
||||||
int *high_curve_map = NULL, *quality_map = NULL;
|
|
||||||
int map_w = 0, map_h = 0;
|
|
||||||
unsigned char *bdata = NULL;
|
|
||||||
int bw = 0, bh = 0;
|
|
||||||
|
|
||||||
/* If input image is not 8-bit grayscale ... */
|
|
||||||
if(id != 8){
|
|
||||||
fprintf(stderr, "ERROR : get_minutiae : input image pixel ");
|
|
||||||
fprintf(stderr, "depth = %d != 8.\n", id);
|
|
||||||
return(-2);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Detect minutiae in grayscale fingerpeint image. */
|
|
||||||
if((ret = lfs_detect_minutiae_V2(&minutiae,
|
|
||||||
&direction_map, &low_contrast_map,
|
|
||||||
&low_flow_map, &high_curve_map,
|
|
||||||
&map_w, &map_h,
|
|
||||||
&bdata, &bw, &bh,
|
|
||||||
idata, iw, ih, lfsparms))){
|
|
||||||
return(ret);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Build integrated quality map. */
|
|
||||||
if((ret = gen_quality_map(&quality_map,
|
|
||||||
direction_map, low_contrast_map,
|
|
||||||
low_flow_map, high_curve_map, map_w, map_h))){
|
|
||||||
free_minutiae(minutiae);
|
|
||||||
free(direction_map);
|
|
||||||
free(low_contrast_map);
|
|
||||||
free(low_flow_map);
|
|
||||||
free(high_curve_map);
|
|
||||||
free(bdata);
|
|
||||||
return(ret);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Assign reliability from quality map. */
|
|
||||||
if((ret = combined_minutia_quality(minutiae, quality_map, map_w, map_h,
|
|
||||||
lfsparms->blocksize,
|
|
||||||
idata, iw, ih, id, ppmm))){
|
|
||||||
free_minutiae(minutiae);
|
|
||||||
free(direction_map);
|
|
||||||
free(low_contrast_map);
|
|
||||||
free(low_flow_map);
|
|
||||||
free(high_curve_map);
|
|
||||||
free(quality_map);
|
|
||||||
free(bdata);
|
|
||||||
return(ret);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Set output pointers. */
|
|
||||||
*ominutiae = minutiae;
|
|
||||||
*oquality_map = quality_map;
|
|
||||||
*odirection_map = direction_map;
|
|
||||||
*olow_contrast_map = low_contrast_map;
|
|
||||||
*olow_flow_map = low_flow_map;
|
|
||||||
*ohigh_curve_map = high_curve_map;
|
|
||||||
*omap_w = map_w;
|
|
||||||
*omap_h = map_h;
|
|
||||||
*obdata = bdata;
|
|
||||||
*obw = bw;
|
|
||||||
*obh = bh;
|
|
||||||
*obd = id;
|
|
||||||
|
|
||||||
/* Return normally. */
|
|
||||||
return(0);
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,26 +1,47 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
|
|
||||||
License:
|
License:
|
||||||
This software was developed at the National Institute of Standards and
|
This software and/or related materials was developed at the National Institute
|
||||||
Technology (NIST) by employees of the Federal Government in the course
|
of Standards and Technology (NIST) by employees of the Federal Government
|
||||||
of their official duties. Pursuant to title 17 Section 105 of the
|
in the course of their official duties. Pursuant to title 17 Section 105
|
||||||
United States Code, this software is not subject to copyright protection
|
of the United States Code, this software is not subject to copyright
|
||||||
and is in the public domain. NIST assumes no responsibility whatsoever for
|
protection and is in the public domain.
|
||||||
its use by other parties, and makes no guarantees, expressed or implied,
|
|
||||||
about its quality, reliability, or any other characteristic.
|
|
||||||
|
|
||||||
Disclaimer:
|
This software and/or related materials have been determined to be not subject
|
||||||
This software was developed to promote biometric standards and biometric
|
to the EAR (see Part 734.3 of the EAR for exact details) because it is
|
||||||
technology testing for the Federal Government in accordance with the USA
|
a publicly available technology and software, and is freely distributed
|
||||||
PATRIOT Act and the Enhanced Border Security and Visa Entry Reform Act.
|
to any interested party with no licensing requirements. Therefore, it is
|
||||||
Specific hardware and software products identified in this software were used
|
permissible to distribute this software as a free download from the internet.
|
||||||
in order to perform the software development. In no case does such
|
|
||||||
identification imply recommendation or endorsement by the National Institute
|
Disclaimer:
|
||||||
of Standards and Technology, nor does it imply that the products and equipment
|
This software and/or related materials was developed to promote biometric
|
||||||
identified are necessarily the best available for the purpose.
|
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.
|
||||||
|
|
||||||
|
This software and/or related materials are provided "AS-IS" without warranty
|
||||||
|
of any kind including NO WARRANTY OF PERFORMANCE, MERCHANTABILITY,
|
||||||
|
NO WARRANTY OF NON-INFRINGEMENT OF ANY 3RD PARTY INTELLECTUAL PROPERTY
|
||||||
|
or FITNESS FOR A PARTICULAR PURPOSE or for any purpose whatsoever, for the
|
||||||
|
licensed product, however used. In no event shall NIST be liable for any
|
||||||
|
damages and/or costs, including but not limited to incidental or consequential
|
||||||
|
damages of any kind, including economic damage or injury to property and lost
|
||||||
|
profits, regardless of whether NIST shall be advised, have reason to know,
|
||||||
|
or in fact shall know of the possibility.
|
||||||
|
|
||||||
|
By using this software, you agree to bear all risk relating to quality,
|
||||||
|
use and performance of the software and/or related materials. You agree
|
||||||
|
to hold the Government harmless from any claim arising from your use
|
||||||
|
of the software.
|
||||||
|
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
LIBRARY: LFS - NIST Latent Fingerprint System
|
LIBRARY: LFS - NIST Latent Fingerprint System
|
||||||
|
|
||||||
|
@ -44,87 +65,8 @@ identified are necessarily the best available for the purpose.
|
||||||
***********************************************************************/
|
***********************************************************************/
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
|
||||||
#include <lfs.h>
|
#include <lfs.h>
|
||||||
|
|
||||||
/*************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
#cat: sum_rot_block_rows - Computes a vector or pixel row sums by sampling
|
|
||||||
#cat: the current image block at a given orientation. The
|
|
||||||
#cat: sampling is conducted using a precomputed set of rotated
|
|
||||||
#cat: pixel offsets (called a grid) relative to the orgin of
|
|
||||||
#cat: the image block.
|
|
||||||
|
|
||||||
Input:
|
|
||||||
blkptr - the pixel address of the origin of the current image block
|
|
||||||
grid_offsets - the rotated pixel offsets for a block-sized grid
|
|
||||||
rotated according to a specific orientation
|
|
||||||
blocksize - the width and height of the image block and thus the size
|
|
||||||
of the rotated grid
|
|
||||||
Output:
|
|
||||||
rowsums - the resulting vector of pixel row sums
|
|
||||||
**************************************************************************/
|
|
||||||
static void sum_rot_block_rows(int *rowsums, const unsigned char *blkptr,
|
|
||||||
const int *grid_offsets, const int blocksize)
|
|
||||||
{
|
|
||||||
int ix, iy, gi;
|
|
||||||
|
|
||||||
/* Initialize rotation offset index. */
|
|
||||||
gi = 0;
|
|
||||||
|
|
||||||
/* For each row in block ... */
|
|
||||||
for(iy = 0; iy < blocksize; iy++){
|
|
||||||
/* The sums are accumlated along the rotated rows of the grid, */
|
|
||||||
/* so initialize row sum to 0. */
|
|
||||||
rowsums[iy] = 0;
|
|
||||||
/* Foreach column in block ... */
|
|
||||||
for(ix = 0; ix < blocksize; ix++){
|
|
||||||
/* Accumulate pixel value at rotated grid position in image */
|
|
||||||
rowsums[iy] += *(blkptr + grid_offsets[gi]);
|
|
||||||
gi++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
#cat: dft_power - Computes the DFT power by applying a specific wave form
|
|
||||||
#cat: frequency to a vector of pixel row sums computed from a
|
|
||||||
#cat: specific orientation of the block image
|
|
||||||
|
|
||||||
Input:
|
|
||||||
rowsums - accumulated rows of pixels from within a rotated grid
|
|
||||||
overlaying an input image block
|
|
||||||
wave - the wave form (cosine and sine components) at a specific
|
|
||||||
frequency
|
|
||||||
wavelen - the length of the wave form (must match the height of the
|
|
||||||
image block which is the length of the rowsum vector)
|
|
||||||
Output:
|
|
||||||
power - the computed DFT power for the given wave form at the
|
|
||||||
given orientation within the image block
|
|
||||||
**************************************************************************/
|
|
||||||
static void dft_power(double *power, const int *rowsums,
|
|
||||||
const DFTWAVE *wave, const int wavelen)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
double cospart, sinpart;
|
|
||||||
|
|
||||||
/* Initialize accumulators */
|
|
||||||
cospart = 0.0;
|
|
||||||
sinpart = 0.0;
|
|
||||||
|
|
||||||
/* Accumulate cos and sin components of DFT. */
|
|
||||||
for(i = 0; i < wavelen; i++){
|
|
||||||
/* Multiply each rotated row sum by its */
|
|
||||||
/* corresponding cos or sin point in DFT wave. */
|
|
||||||
cospart += (rowsums[i] * wave->cos[i]);
|
|
||||||
sinpart += (rowsums[i] * wave->sin[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Power is the sum of the squared cos and sin components */
|
|
||||||
*power = (cospart * cospart) + (sinpart * sinpart);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
**************************************************************************
|
**************************************************************************
|
||||||
#cat: dft_dir_powers - Conducts the DFT analysis on a block of image data.
|
#cat: dft_dir_powers - Conducts the DFT analysis on a block of image data.
|
||||||
|
@ -199,105 +141,80 @@ int dft_dir_powers(double **powers, unsigned char *pdata,
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
**************************************************************************
|
**************************************************************************
|
||||||
#cat: get_max_norm - Analyses a DFT power vector for a specific wave form
|
#cat: sum_rot_block_rows - Computes a vector or pixel row sums by sampling
|
||||||
#cat: applied at different orientations (directions) to the
|
#cat: the current image block at a given orientation. The
|
||||||
#cat: current image block. The routine retuns the maximum
|
#cat: sampling is conducted using a precomputed set of rotated
|
||||||
#cat: power value in the vector, the direction at which the
|
#cat: pixel offsets (called a grid) relative to the orgin of
|
||||||
#cat: maximum occurs, and a normalized power value. The
|
#cat: the image block.
|
||||||
#cat: normalized power is computed as the maximum power divided
|
|
||||||
#cat: by the average power across all the directions. These
|
|
||||||
#cat: simple statistics are fundamental to the selection of
|
|
||||||
#cat: a dominant direction flow for the image block.
|
|
||||||
|
|
||||||
Input:
|
Input:
|
||||||
power_vector - the DFT power values derived form a specific wave form
|
blkptr - the pixel address of the origin of the current image block
|
||||||
applied at different directions
|
grid_offsets - the rotated pixel offsets for a block-sized grid
|
||||||
ndirs - the number of directions to which the wave form was applied
|
rotated according to a specific orientation
|
||||||
|
blocksize - the width and height of the image block and thus the size
|
||||||
|
of the rotated grid
|
||||||
Output:
|
Output:
|
||||||
powmax - the maximum power value in the DFT power vector
|
rowsums - the resulting vector of pixel row sums
|
||||||
powmax_dir - the direciton at which the maximum power value occured
|
|
||||||
pownorm - the normalized power corresponding to the maximum power
|
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
static void get_max_norm(double *powmax, int *powmax_dir,
|
void sum_rot_block_rows(int *rowsums, const unsigned char *blkptr,
|
||||||
double *pownorm, const double *power_vector, const int ndirs)
|
const int *grid_offsets, const int blocksize)
|
||||||
{
|
{
|
||||||
int dir;
|
int ix, iy, gi;
|
||||||
double max_v, powsum;
|
|
||||||
int max_i;
|
|
||||||
double powmean;
|
|
||||||
|
|
||||||
/* Find max power value and store corresponding direction */
|
/* Initialize rotation offset index. */
|
||||||
max_v = power_vector[0];
|
gi = 0;
|
||||||
max_i = 0;
|
|
||||||
|
|
||||||
/* Sum the total power in a block at a given direction */
|
/* For each row in block ... */
|
||||||
powsum = power_vector[0];
|
for(iy = 0; iy < blocksize; iy++){
|
||||||
|
/* The sums are accumlated along the rotated rows of the grid, */
|
||||||
/* For each direction ... */
|
/* so initialize row sum to 0. */
|
||||||
for(dir = 1; dir < ndirs; dir++){
|
rowsums[iy] = 0;
|
||||||
powsum += power_vector[dir];
|
/* Foreach column in block ... */
|
||||||
if(power_vector[dir] > max_v){
|
for(ix = 0; ix < blocksize; ix++){
|
||||||
max_v = power_vector[dir];
|
/* Accumulate pixel value at rotated grid position in image */
|
||||||
max_i = dir;
|
rowsums[iy] += *(blkptr + grid_offsets[gi]);
|
||||||
|
gi++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
*powmax = max_v;
|
|
||||||
*powmax_dir = max_i;
|
|
||||||
|
|
||||||
/* Powmean is used as denominator for pownorm, so setting */
|
|
||||||
/* a non-zero minimum avoids possible division by zero. */
|
|
||||||
powmean = max(powsum, MIN_POWER_SUM)/(double)ndirs;
|
|
||||||
|
|
||||||
*pownorm = *powmax / powmean;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
**************************************************************************
|
**************************************************************************
|
||||||
#cat: sort_dft_waves - Creates a ranked list of DFT wave form statistics
|
#cat: dft_power - Computes the DFT power by applying a specific wave form
|
||||||
#cat: by sorting on the normalized squared maximum power.
|
#cat: frequency to a vector of pixel row sums computed from a
|
||||||
|
#cat: specific orientation of the block image
|
||||||
|
|
||||||
Input:
|
Input:
|
||||||
powmaxs - maximum DFT power for each wave form used to derive
|
rowsums - accumulated rows of pixels from within a rotated grid
|
||||||
statistics
|
overlaying an input image block
|
||||||
pownorms - normalized maximum power corresponding to values in powmaxs
|
wave - the wave form (cosine and sine components) at a specific
|
||||||
nstats - number of wave forms used to derive statistics (N Wave - 1)
|
frequency
|
||||||
|
wavelen - the length of the wave form (must match the height of the
|
||||||
|
image block which is the length of the rowsum vector)
|
||||||
Output:
|
Output:
|
||||||
wis - sorted list of indices corresponding to the ranked set of
|
power - the computed DFT power for the given wave form at the
|
||||||
wave form statistics. These indices will be used as
|
given orientation within the image block
|
||||||
indirect addresses when processing the power statistics
|
|
||||||
in descending order of "dominance"
|
|
||||||
Return Code:
|
|
||||||
Zero - successful completion
|
|
||||||
Negative - system error
|
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
static int sort_dft_waves(int *wis, const double *powmaxs, const double *pownorms,
|
void dft_power(double *power, const int *rowsums,
|
||||||
const int nstats)
|
const DFTWAVE *wave, const int wavelen)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
double *pownorms2;
|
double cospart, sinpart;
|
||||||
|
|
||||||
/* Allocate normalized power^2 array */
|
/* Initialize accumulators */
|
||||||
pownorms2 = (double *)malloc(nstats * sizeof(double));
|
cospart = 0.0;
|
||||||
if(pownorms2 == (double *)NULL){
|
sinpart = 0.0;
|
||||||
fprintf(stderr, "ERROR : sort_dft_waves : malloc : pownorms2\n");
|
|
||||||
return(-100);
|
/* Accumulate cos and sin components of DFT. */
|
||||||
|
for(i = 0; i < wavelen; i++){
|
||||||
|
/* Multiply each rotated row sum by its */
|
||||||
|
/* corresponding cos or sin point in DFT wave. */
|
||||||
|
cospart += (rowsums[i] * wave->cos[i]);
|
||||||
|
sinpart += (rowsums[i] * wave->sin[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
for(i = 0; i < nstats; i++){
|
/* Power is the sum of the squared cos and sin components */
|
||||||
/* Wis will hold the sorted statistic indices when all is done. */
|
*power = (cospart * cospart) + (sinpart * sinpart);
|
||||||
wis[i] = i;
|
|
||||||
/* This is normalized squared max power. */
|
|
||||||
pownorms2[i] = powmaxs[i] * pownorms[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Sort the statistic indices on the normalized squared power. */
|
|
||||||
bubble_sort_double_dec_2(pownorms2, wis, nstats);
|
|
||||||
|
|
||||||
/* Deallocate the working memory. */
|
|
||||||
free(pownorms2);
|
|
||||||
|
|
||||||
return(0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
|
@ -356,3 +273,106 @@ int dft_power_stats(int *wis, double *powmaxs, int *powmax_dirs,
|
||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
#cat: get_max_norm - Analyses a DFT power vector for a specific wave form
|
||||||
|
#cat: applied at different orientations (directions) to the
|
||||||
|
#cat: current image block. The routine retuns the maximum
|
||||||
|
#cat: power value in the vector, the direction at which the
|
||||||
|
#cat: maximum occurs, and a normalized power value. The
|
||||||
|
#cat: normalized power is computed as the maximum power divided
|
||||||
|
#cat: by the average power across all the directions. These
|
||||||
|
#cat: simple statistics are fundamental to the selection of
|
||||||
|
#cat: a dominant direction flow for the image block.
|
||||||
|
|
||||||
|
Input:
|
||||||
|
power_vector - the DFT power values derived form a specific wave form
|
||||||
|
applied at different directions
|
||||||
|
ndirs - the number of directions to which the wave form was applied
|
||||||
|
Output:
|
||||||
|
powmax - the maximum power value in the DFT power vector
|
||||||
|
powmax_dir - the direciton at which the maximum power value occured
|
||||||
|
pownorm - the normalized power corresponding to the maximum power
|
||||||
|
**************************************************************************/
|
||||||
|
void get_max_norm(double *powmax, int *powmax_dir,
|
||||||
|
double *pownorm, const double *power_vector, const int ndirs)
|
||||||
|
{
|
||||||
|
int dir;
|
||||||
|
double max_v, powsum;
|
||||||
|
int max_i;
|
||||||
|
double powmean;
|
||||||
|
|
||||||
|
/* Find max power value and store corresponding direction */
|
||||||
|
max_v = power_vector[0];
|
||||||
|
max_i = 0;
|
||||||
|
|
||||||
|
/* Sum the total power in a block at a given direction */
|
||||||
|
powsum = power_vector[0];
|
||||||
|
|
||||||
|
/* For each direction ... */
|
||||||
|
for(dir = 1; dir < ndirs; dir++){
|
||||||
|
powsum += power_vector[dir];
|
||||||
|
if(power_vector[dir] > max_v){
|
||||||
|
max_v = power_vector[dir];
|
||||||
|
max_i = dir;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
*powmax = max_v;
|
||||||
|
*powmax_dir = max_i;
|
||||||
|
|
||||||
|
/* Powmean is used as denominator for pownorm, so setting */
|
||||||
|
/* a non-zero minimum avoids possible division by zero. */
|
||||||
|
powmean = max(powsum, MIN_POWER_SUM)/(double)ndirs;
|
||||||
|
|
||||||
|
*pownorm = *powmax / powmean;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
#cat: sort_dft_waves - Creates a ranked list of DFT wave form statistics
|
||||||
|
#cat: by sorting on the normalized squared maximum power.
|
||||||
|
|
||||||
|
Input:
|
||||||
|
powmaxs - maximum DFT power for each wave form used to derive
|
||||||
|
statistics
|
||||||
|
pownorms - normalized maximum power corresponding to values in powmaxs
|
||||||
|
nstats - number of wave forms used to derive statistics (N Wave - 1)
|
||||||
|
Output:
|
||||||
|
wis - sorted list of indices corresponding to the ranked set of
|
||||||
|
wave form statistics. These indices will be used as
|
||||||
|
indirect addresses when processing the power statistics
|
||||||
|
in descending order of "dominance"
|
||||||
|
Return Code:
|
||||||
|
Zero - successful completion
|
||||||
|
Negative - system error
|
||||||
|
**************************************************************************/
|
||||||
|
int sort_dft_waves(int *wis, const double *powmaxs, const double *pownorms,
|
||||||
|
const int nstats)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
double *pownorms2;
|
||||||
|
|
||||||
|
/* Allocate normalized power^2 array */
|
||||||
|
pownorms2 = (double *)malloc(nstats * sizeof(double));
|
||||||
|
if(pownorms2 == (double *)NULL){
|
||||||
|
fprintf(stderr, "ERROR : sort_dft_waves : malloc : pownorms2\n");
|
||||||
|
return(-100);
|
||||||
|
}
|
||||||
|
|
||||||
|
for(i = 0; i < nstats; i++){
|
||||||
|
/* Wis will hold the sorted statistic indices when all is done. */
|
||||||
|
wis[i] = i;
|
||||||
|
/* This is normalized squared max power. */
|
||||||
|
pownorms2[i] = powmaxs[i] * pownorms[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Sort the statistic indices on the normalized squared power. */
|
||||||
|
bubble_sort_double_dec_2(pownorms2, wis, nstats);
|
||||||
|
|
||||||
|
/* Deallocate the working memory. */
|
||||||
|
free(pownorms2);
|
||||||
|
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,26 +1,47 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
|
|
||||||
License:
|
License:
|
||||||
This software was developed at the National Institute of Standards and
|
This software and/or related materials was developed at the National Institute
|
||||||
Technology (NIST) by employees of the Federal Government in the course
|
of Standards and Technology (NIST) by employees of the Federal Government
|
||||||
of their official duties. Pursuant to title 17 Section 105 of the
|
in the course of their official duties. Pursuant to title 17 Section 105
|
||||||
United States Code, this software is not subject to copyright protection
|
of the United States Code, this software is not subject to copyright
|
||||||
and is in the public domain. NIST assumes no responsibility whatsoever for
|
protection and is in the public domain.
|
||||||
its use by other parties, and makes no guarantees, expressed or implied,
|
|
||||||
about its quality, reliability, or any other characteristic.
|
|
||||||
|
|
||||||
Disclaimer:
|
This software and/or related materials have been determined to be not subject
|
||||||
This software was developed to promote biometric standards and biometric
|
to the EAR (see Part 734.3 of the EAR for exact details) because it is
|
||||||
technology testing for the Federal Government in accordance with the USA
|
a publicly available technology and software, and is freely distributed
|
||||||
PATRIOT Act and the Enhanced Border Security and Visa Entry Reform Act.
|
to any interested party with no licensing requirements. Therefore, it is
|
||||||
Specific hardware and software products identified in this software were used
|
permissible to distribute this software as a free download from the internet.
|
||||||
in order to perform the software development. In no case does such
|
|
||||||
identification imply recommendation or endorsement by the National Institute
|
Disclaimer:
|
||||||
of Standards and Technology, nor does it imply that the products and equipment
|
This software and/or related materials was developed to promote biometric
|
||||||
identified are necessarily the best available for the purpose.
|
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.
|
||||||
|
|
||||||
|
This software and/or related materials are provided "AS-IS" without warranty
|
||||||
|
of any kind including NO WARRANTY OF PERFORMANCE, MERCHANTABILITY,
|
||||||
|
NO WARRANTY OF NON-INFRINGEMENT OF ANY 3RD PARTY INTELLECTUAL PROPERTY
|
||||||
|
or FITNESS FOR A PARTICULAR PURPOSE or for any purpose whatsoever, for the
|
||||||
|
licensed product, however used. In no event shall NIST be liable for any
|
||||||
|
damages and/or costs, including but not limited to incidental or consequential
|
||||||
|
damages of any kind, including economic damage or injury to property and lost
|
||||||
|
profits, regardless of whether NIST shall be advised, have reason to know,
|
||||||
|
or in fact shall know of the possibility.
|
||||||
|
|
||||||
|
By using this software, you agree to bear all risk relating to quality,
|
||||||
|
use and performance of the software and/or related materials. You agree
|
||||||
|
to hold the Government harmless from any claim arising from your use
|
||||||
|
of the software.
|
||||||
|
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
LIBRARY: LFS - NIST Latent Fingerprint System
|
LIBRARY: LFS - NIST Latent Fingerprint System
|
||||||
|
|
||||||
|
@ -40,7 +61,6 @@ identified are necessarily the best available for the purpose.
|
||||||
***********************************************************************/
|
***********************************************************************/
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
|
||||||
#include <lfs.h>
|
#include <lfs.h>
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
|
|
175
libfprint/nbis/mindtct/getmin.c
Normal file
175
libfprint/nbis/mindtct/getmin.c
Normal file
|
@ -0,0 +1,175 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
|
||||||
|
License:
|
||||||
|
This software and/or related materials 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.
|
||||||
|
|
||||||
|
This software and/or related materials have been determined to be not subject
|
||||||
|
to the EAR (see Part 734.3 of the EAR for exact details) because it is
|
||||||
|
a publicly available technology and software, and is freely distributed
|
||||||
|
to any interested party with no licensing requirements. Therefore, it is
|
||||||
|
permissible to distribute this software as a free download from the internet.
|
||||||
|
|
||||||
|
Disclaimer:
|
||||||
|
This software and/or related materials 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.
|
||||||
|
|
||||||
|
This software and/or related materials are provided "AS-IS" without warranty
|
||||||
|
of any kind including NO WARRANTY OF PERFORMANCE, MERCHANTABILITY,
|
||||||
|
NO WARRANTY OF NON-INFRINGEMENT OF ANY 3RD PARTY INTELLECTUAL PROPERTY
|
||||||
|
or FITNESS FOR A PARTICULAR PURPOSE or for any purpose whatsoever, for the
|
||||||
|
licensed product, however used. In no event shall NIST be liable for any
|
||||||
|
damages and/or costs, including but not limited to incidental or consequential
|
||||||
|
damages of any kind, including economic damage or injury to property and lost
|
||||||
|
profits, regardless of whether NIST shall be advised, have reason to know,
|
||||||
|
or in fact shall know of the possibility.
|
||||||
|
|
||||||
|
By using this software, you agree to bear all risk relating to quality,
|
||||||
|
use and performance of the software and/or related materials. You agree
|
||||||
|
to hold the Government harmless from any claim arising from your use
|
||||||
|
of the software.
|
||||||
|
|
||||||
|
*******************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
LIBRARY: LFS - NIST Latent Fingerprint System
|
||||||
|
|
||||||
|
FILE: GETMIN.C
|
||||||
|
AUTHOR: Michael D. Garris
|
||||||
|
DATE: 09/10/2004
|
||||||
|
UPDATED: 03/16/2005 by MDG
|
||||||
|
|
||||||
|
Takes an 8-bit grayscale fingerpinrt image and detects minutiae
|
||||||
|
as part of the NIST Latent Fingerprint System (LFS), returning
|
||||||
|
minutiae with final reliabilities and maps including a merged
|
||||||
|
quality map.
|
||||||
|
|
||||||
|
***********************************************************************
|
||||||
|
ROUTINES:
|
||||||
|
get_minutiae()
|
||||||
|
|
||||||
|
***********************************************************************/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <lfs.h>
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
#cat: get_minutiae - Takes a grayscale fingerprint image, binarizes the input
|
||||||
|
#cat: image, and detects minutiae points using LFS Version 2.
|
||||||
|
#cat: The routine passes back the detected minutiae, the
|
||||||
|
#cat: binarized image, and a set of image quality maps.
|
||||||
|
|
||||||
|
Input:
|
||||||
|
idata - grayscale fingerprint image data
|
||||||
|
iw - width (in pixels) of the grayscale image
|
||||||
|
ih - height (in pixels) of the grayscale image
|
||||||
|
id - pixel depth (in bits) of the grayscale image
|
||||||
|
ppmm - the scan resolution (in pixels/mm) of the grayscale image
|
||||||
|
lfsparms - parameters and thresholds for controlling LFS
|
||||||
|
Output:
|
||||||
|
ominutiae - points to a structure containing the
|
||||||
|
detected minutiae
|
||||||
|
oquality_map - resulting integrated image quality map
|
||||||
|
odirection_map - resulting direction map
|
||||||
|
olow_contrast_map - resulting low contrast map
|
||||||
|
olow_flow_map - resulting low ridge flow map
|
||||||
|
ohigh_curve_map - resulting high curvature map
|
||||||
|
omap_w - width (in blocks) of image maps
|
||||||
|
omap_h - height (in blocks) of image maps
|
||||||
|
obdata - points to binarized image data
|
||||||
|
obw - width (in pixels) of binarized image
|
||||||
|
obh - height (in pixels) of binarized image
|
||||||
|
obd - pixel depth (in bits) of binarized image
|
||||||
|
Return Code:
|
||||||
|
Zero - successful completion
|
||||||
|
Negative - system error
|
||||||
|
**************************************************************************/
|
||||||
|
int get_minutiae(MINUTIAE **ominutiae, int **oquality_map,
|
||||||
|
int **odirection_map, int **olow_contrast_map,
|
||||||
|
int **olow_flow_map, int **ohigh_curve_map,
|
||||||
|
int *omap_w, int *omap_h,
|
||||||
|
unsigned char **obdata, int *obw, int *obh, int *obd,
|
||||||
|
unsigned char *idata, const int iw, const int ih,
|
||||||
|
const int id, const double ppmm, const LFSPARMS *lfsparms)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
MINUTIAE *minutiae;
|
||||||
|
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;
|
||||||
|
|
||||||
|
/* If input image is not 8-bit grayscale ... */
|
||||||
|
if(id != 8){
|
||||||
|
fprintf(stderr, "ERROR : get_minutiae : input image pixel ");
|
||||||
|
fprintf(stderr, "depth = %d != 8.\n", id);
|
||||||
|
return(-2);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Detect minutiae in grayscale fingerpeint image. */
|
||||||
|
if((ret = lfs_detect_minutiae_V2(&minutiae,
|
||||||
|
&direction_map, &low_contrast_map,
|
||||||
|
&low_flow_map, &high_curve_map,
|
||||||
|
&map_w, &map_h,
|
||||||
|
&bdata, &bw, &bh,
|
||||||
|
idata, iw, ih, lfsparms))){
|
||||||
|
return(ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Build integrated quality map. */
|
||||||
|
if((ret = gen_quality_map(&quality_map,
|
||||||
|
direction_map, low_contrast_map,
|
||||||
|
low_flow_map, high_curve_map, map_w, map_h))){
|
||||||
|
free_minutiae(minutiae);
|
||||||
|
free(direction_map);
|
||||||
|
free(low_contrast_map);
|
||||||
|
free(low_flow_map);
|
||||||
|
free(high_curve_map);
|
||||||
|
free(bdata);
|
||||||
|
return(ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Assign reliability from quality map. */
|
||||||
|
if((ret = combined_minutia_quality(minutiae, quality_map, map_w, map_h,
|
||||||
|
lfsparms->blocksize,
|
||||||
|
idata, iw, ih, id, ppmm))){
|
||||||
|
free_minutiae(minutiae);
|
||||||
|
free(direction_map);
|
||||||
|
free(low_contrast_map);
|
||||||
|
free(low_flow_map);
|
||||||
|
free(high_curve_map);
|
||||||
|
free(quality_map);
|
||||||
|
free(bdata);
|
||||||
|
return(ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set output pointers. */
|
||||||
|
*ominutiae = minutiae;
|
||||||
|
*oquality_map = quality_map;
|
||||||
|
*odirection_map = direction_map;
|
||||||
|
*olow_contrast_map = low_contrast_map;
|
||||||
|
*olow_flow_map = low_flow_map;
|
||||||
|
*ohigh_curve_map = high_curve_map;
|
||||||
|
*omap_w = map_w;
|
||||||
|
*omap_h = map_h;
|
||||||
|
*obdata = bdata;
|
||||||
|
*obw = bw;
|
||||||
|
*obh = bh;
|
||||||
|
*obd = id;
|
||||||
|
|
||||||
|
/* Return normally. */
|
||||||
|
return(0);
|
||||||
|
}
|
|
@ -1,26 +1,47 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
|
|
||||||
License:
|
License:
|
||||||
This software was developed at the National Institute of Standards and
|
This software and/or related materials was developed at the National Institute
|
||||||
Technology (NIST) by employees of the Federal Government in the course
|
of Standards and Technology (NIST) by employees of the Federal Government
|
||||||
of their official duties. Pursuant to title 17 Section 105 of the
|
in the course of their official duties. Pursuant to title 17 Section 105
|
||||||
United States Code, this software is not subject to copyright protection
|
of the United States Code, this software is not subject to copyright
|
||||||
and is in the public domain. NIST assumes no responsibility whatsoever for
|
protection and is in the public domain.
|
||||||
its use by other parties, and makes no guarantees, expressed or implied,
|
|
||||||
about its quality, reliability, or any other characteristic.
|
|
||||||
|
|
||||||
Disclaimer:
|
This software and/or related materials have been determined to be not subject
|
||||||
This software was developed to promote biometric standards and biometric
|
to the EAR (see Part 734.3 of the EAR for exact details) because it is
|
||||||
technology testing for the Federal Government in accordance with the USA
|
a publicly available technology and software, and is freely distributed
|
||||||
PATRIOT Act and the Enhanced Border Security and Visa Entry Reform Act.
|
to any interested party with no licensing requirements. Therefore, it is
|
||||||
Specific hardware and software products identified in this software were used
|
permissible to distribute this software as a free download from the internet.
|
||||||
in order to perform the software development. In no case does such
|
|
||||||
identification imply recommendation or endorsement by the National Institute
|
Disclaimer:
|
||||||
of Standards and Technology, nor does it imply that the products and equipment
|
This software and/or related materials was developed to promote biometric
|
||||||
identified are necessarily the best available for the purpose.
|
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.
|
||||||
|
|
||||||
|
This software and/or related materials are provided "AS-IS" without warranty
|
||||||
|
of any kind including NO WARRANTY OF PERFORMANCE, MERCHANTABILITY,
|
||||||
|
NO WARRANTY OF NON-INFRINGEMENT OF ANY 3RD PARTY INTELLECTUAL PROPERTY
|
||||||
|
or FITNESS FOR A PARTICULAR PURPOSE or for any purpose whatsoever, for the
|
||||||
|
licensed product, however used. In no event shall NIST be liable for any
|
||||||
|
damages and/or costs, including but not limited to incidental or consequential
|
||||||
|
damages of any kind, including economic damage or injury to property and lost
|
||||||
|
profits, regardless of whether NIST shall be advised, have reason to know,
|
||||||
|
or in fact shall know of the possibility.
|
||||||
|
|
||||||
|
By using this software, you agree to bear all risk relating to quality,
|
||||||
|
use and performance of the software and/or related materials. You agree
|
||||||
|
to hold the Government harmless from any claim arising from your use
|
||||||
|
of the software.
|
||||||
|
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
LIBRARY: LFS - NIST Latent Fingerprint System
|
LIBRARY: LFS - NIST Latent Fingerprint System
|
||||||
|
|
||||||
|
@ -40,7 +61,7 @@ identified are necessarily the best available for the purpose.
|
||||||
/*************************************************************************/
|
/*************************************************************************/
|
||||||
|
|
||||||
#ifdef LOG_REPORT
|
#ifdef LOG_REPORT
|
||||||
FILE *g_logfp;
|
FILE *logfp;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Constants (C) for defining 4 DFT frequencies, where */
|
/* Constants (C) for defining 4 DFT frequencies, where */
|
||||||
|
@ -129,8 +150,6 @@ LFSPARMS g_lfsparms = {
|
||||||
PORES_STEPS_BWD,
|
PORES_STEPS_BWD,
|
||||||
PORES_MIN_DIST2,
|
PORES_MIN_DIST2,
|
||||||
PORES_MAX_RATIO,
|
PORES_MAX_RATIO,
|
||||||
FALSE, /* not removing perimeter points by default */
|
|
||||||
PERIMETER_PTS_DISTANCE,
|
|
||||||
|
|
||||||
/* Ridge Counting Controls */
|
/* Ridge Counting Controls */
|
||||||
MAX_NBRS,
|
MAX_NBRS,
|
||||||
|
@ -215,8 +234,6 @@ LFSPARMS g_lfsparms_V2 = {
|
||||||
PORES_STEPS_BWD,
|
PORES_STEPS_BWD,
|
||||||
PORES_MIN_DIST2,
|
PORES_MIN_DIST2,
|
||||||
PORES_MAX_RATIO,
|
PORES_MAX_RATIO,
|
||||||
FALSE, /* not removing perimeter points by default */
|
|
||||||
PERIMETER_PTS_DISTANCE,
|
|
||||||
|
|
||||||
/* Ridge Counting Controls */
|
/* Ridge Counting Controls */
|
||||||
MAX_NBRS,
|
MAX_NBRS,
|
||||||
|
|
|
@ -1,26 +1,47 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
|
|
||||||
License:
|
License:
|
||||||
This software was developed at the National Institute of Standards and
|
This software and/or related materials was developed at the National Institute
|
||||||
Technology (NIST) by employees of the Federal Government in the course
|
of Standards and Technology (NIST) by employees of the Federal Government
|
||||||
of their official duties. Pursuant to title 17 Section 105 of the
|
in the course of their official duties. Pursuant to title 17 Section 105
|
||||||
United States Code, this software is not subject to copyright protection
|
of the United States Code, this software is not subject to copyright
|
||||||
and is in the public domain. NIST assumes no responsibility whatsoever for
|
protection and is in the public domain.
|
||||||
its use by other parties, and makes no guarantees, expressed or implied,
|
|
||||||
about its quality, reliability, or any other characteristic.
|
|
||||||
|
|
||||||
Disclaimer:
|
This software and/or related materials have been determined to be not subject
|
||||||
This software was developed to promote biometric standards and biometric
|
to the EAR (see Part 734.3 of the EAR for exact details) because it is
|
||||||
technology testing for the Federal Government in accordance with the USA
|
a publicly available technology and software, and is freely distributed
|
||||||
PATRIOT Act and the Enhanced Border Security and Visa Entry Reform Act.
|
to any interested party with no licensing requirements. Therefore, it is
|
||||||
Specific hardware and software products identified in this software were used
|
permissible to distribute this software as a free download from the internet.
|
||||||
in order to perform the software development. In no case does such
|
|
||||||
identification imply recommendation or endorsement by the National Institute
|
Disclaimer:
|
||||||
of Standards and Technology, nor does it imply that the products and equipment
|
This software and/or related materials was developed to promote biometric
|
||||||
identified are necessarily the best available for the purpose.
|
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.
|
||||||
|
|
||||||
|
This software and/or related materials are provided "AS-IS" without warranty
|
||||||
|
of any kind including NO WARRANTY OF PERFORMANCE, MERCHANTABILITY,
|
||||||
|
NO WARRANTY OF NON-INFRINGEMENT OF ANY 3RD PARTY INTELLECTUAL PROPERTY
|
||||||
|
or FITNESS FOR A PARTICULAR PURPOSE or for any purpose whatsoever, for the
|
||||||
|
licensed product, however used. In no event shall NIST be liable for any
|
||||||
|
damages and/or costs, including but not limited to incidental or consequential
|
||||||
|
damages of any kind, including economic damage or injury to property and lost
|
||||||
|
profits, regardless of whether NIST shall be advised, have reason to know,
|
||||||
|
or in fact shall know of the possibility.
|
||||||
|
|
||||||
|
By using this software, you agree to bear all risk relating to quality,
|
||||||
|
use and performance of the software and/or related materials. You agree
|
||||||
|
to hold the Government harmless from any claim arising from your use
|
||||||
|
of the software.
|
||||||
|
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
LIBRARY: LFS - NIST Latent Fingerprint System
|
LIBRARY: LFS - NIST Latent Fingerprint System
|
||||||
|
|
||||||
|
@ -45,7 +66,6 @@ identified are necessarily the best available for the purpose.
|
||||||
***********************************************************************/
|
***********************************************************************/
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
|
||||||
#include <memory.h>
|
#include <memory.h>
|
||||||
#include <lfs.h>
|
#include <lfs.h>
|
||||||
|
|
||||||
|
@ -65,18 +85,6 @@ identified are necessarily the best available for the purpose.
|
||||||
Output:
|
Output:
|
||||||
idata - contains the bit-shifted results
|
idata - contains the bit-shifted results
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
void bits_6to8(unsigned char *idata, const int iw, const int ih)
|
|
||||||
{
|
|
||||||
int i, isize;
|
|
||||||
unsigned char *iptr;
|
|
||||||
|
|
||||||
isize = iw * ih;
|
|
||||||
iptr = idata;
|
|
||||||
for(i = 0; i < isize; i++){
|
|
||||||
/* Multiply every pixel value by 4 so that [0..64) -> [0..255) */
|
|
||||||
*iptr++ <<= 2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
**************************************************************************
|
**************************************************************************
|
||||||
|
|
|
@ -1,26 +1,47 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
|
|
||||||
License:
|
License:
|
||||||
This software was developed at the National Institute of Standards and
|
This software and/or related materials was developed at the National Institute
|
||||||
Technology (NIST) by employees of the Federal Government in the course
|
of Standards and Technology (NIST) by employees of the Federal Government
|
||||||
of their official duties. Pursuant to title 17 Section 105 of the
|
in the course of their official duties. Pursuant to title 17 Section 105
|
||||||
United States Code, this software is not subject to copyright protection
|
of the United States Code, this software is not subject to copyright
|
||||||
and is in the public domain. NIST assumes no responsibility whatsoever for
|
protection and is in the public domain.
|
||||||
its use by other parties, and makes no guarantees, expressed or implied,
|
|
||||||
about its quality, reliability, or any other characteristic.
|
|
||||||
|
|
||||||
Disclaimer:
|
This software and/or related materials have been determined to be not subject
|
||||||
This software was developed to promote biometric standards and biometric
|
to the EAR (see Part 734.3 of the EAR for exact details) because it is
|
||||||
technology testing for the Federal Government in accordance with the USA
|
a publicly available technology and software, and is freely distributed
|
||||||
PATRIOT Act and the Enhanced Border Security and Visa Entry Reform Act.
|
to any interested party with no licensing requirements. Therefore, it is
|
||||||
Specific hardware and software products identified in this software were used
|
permissible to distribute this software as a free download from the internet.
|
||||||
in order to perform the software development. In no case does such
|
|
||||||
identification imply recommendation or endorsement by the National Institute
|
Disclaimer:
|
||||||
of Standards and Technology, nor does it imply that the products and equipment
|
This software and/or related materials was developed to promote biometric
|
||||||
identified are necessarily the best available for the purpose.
|
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.
|
||||||
|
|
||||||
|
This software and/or related materials are provided "AS-IS" without warranty
|
||||||
|
of any kind including NO WARRANTY OF PERFORMANCE, MERCHANTABILITY,
|
||||||
|
NO WARRANTY OF NON-INFRINGEMENT OF ANY 3RD PARTY INTELLECTUAL PROPERTY
|
||||||
|
or FITNESS FOR A PARTICULAR PURPOSE or for any purpose whatsoever, for the
|
||||||
|
licensed product, however used. In no event shall NIST be liable for any
|
||||||
|
damages and/or costs, including but not limited to incidental or consequential
|
||||||
|
damages of any kind, including economic damage or injury to property and lost
|
||||||
|
profits, regardless of whether NIST shall be advised, have reason to know,
|
||||||
|
or in fact shall know of the possibility.
|
||||||
|
|
||||||
|
By using this software, you agree to bear all risk relating to quality,
|
||||||
|
use and performance of the software and/or related materials. You agree
|
||||||
|
to hold the Government harmless from any claim arising from your use
|
||||||
|
of the software.
|
||||||
|
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
LIBRARY: LFS - NIST Latent Fingerprint System
|
LIBRARY: LFS - NIST Latent Fingerprint System
|
||||||
|
|
||||||
|
@ -37,6 +58,7 @@ identified are necessarily the best available for the purpose.
|
||||||
ROUTINES:
|
ROUTINES:
|
||||||
init_dir2rad()
|
init_dir2rad()
|
||||||
init_dftwaves()
|
init_dftwaves()
|
||||||
|
get_max_padding()
|
||||||
get_max_padding_V2()
|
get_max_padding_V2()
|
||||||
init_rotgrids()
|
init_rotgrids()
|
||||||
alloc_dir_powers()
|
alloc_dir_powers()
|
||||||
|
@ -44,7 +66,6 @@ identified are necessarily the best available for the purpose.
|
||||||
***********************************************************************/
|
***********************************************************************/
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
|
||||||
#include <lfs.h>
|
#include <lfs.h>
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
|
@ -242,6 +263,33 @@ int init_dftwaves(DFTWAVES **optr, const double *dft_coefs,
|
||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
#cat: get_max_padding - Deterines the maximum amount of image pixel padding
|
||||||
|
#cat: required by all LFS processes. Padding is currently
|
||||||
|
#cat: required by the rotated grids used in DFT analyses,
|
||||||
|
#cat: rotated grids used in directional binarization,
|
||||||
|
#cat: and in the grid used for isotropic binarization.
|
||||||
|
#cat: The NIST generalized code enables the parameters
|
||||||
|
#cat: governing these processes to be redefined, so a check
|
||||||
|
#cat: at runtime is required to determine which process
|
||||||
|
#cat: requires the most padding. By using the maximum as
|
||||||
|
#cat: the padding factor, all processes will run safely
|
||||||
|
#cat: with a single padding of the input image avoiding the
|
||||||
|
#cat: need to repad for further processes.
|
||||||
|
|
||||||
|
Input:
|
||||||
|
imap_blocksize - the size (in pixels) of each IMAP block in the image
|
||||||
|
dirbin_grid_w - the width (in pixels) of the rotated grids used in
|
||||||
|
directional binarization
|
||||||
|
dirbin_grid_h - the height (in pixels) of the rotated grids used in
|
||||||
|
directional binarization
|
||||||
|
isobin_grid_dim - the dimension (in pixels) of the square grid used in
|
||||||
|
isotropic binarization
|
||||||
|
Return Code:
|
||||||
|
Non-negative - the maximum padding required for all processes
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
**************************************************************************
|
**************************************************************************
|
||||||
#cat: get_max_padding_V2 - Deterines the maximum amount of image pixel padding
|
#cat: get_max_padding_V2 - Deterines the maximum amount of image pixel padding
|
||||||
|
|
|
@ -1,26 +1,47 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
|
|
||||||
License:
|
License:
|
||||||
This software was developed at the National Institute of Standards and
|
This software and/or related materials was developed at the National Institute
|
||||||
Technology (NIST) by employees of the Federal Government in the course
|
of Standards and Technology (NIST) by employees of the Federal Government
|
||||||
of their official duties. Pursuant to title 17 Section 105 of the
|
in the course of their official duties. Pursuant to title 17 Section 105
|
||||||
United States Code, this software is not subject to copyright protection
|
of the United States Code, this software is not subject to copyright
|
||||||
and is in the public domain. NIST assumes no responsibility whatsoever for
|
protection and is in the public domain.
|
||||||
its use by other parties, and makes no guarantees, expressed or implied,
|
|
||||||
about its quality, reliability, or any other characteristic.
|
|
||||||
|
|
||||||
Disclaimer:
|
This software and/or related materials have been determined to be not subject
|
||||||
This software was developed to promote biometric standards and biometric
|
to the EAR (see Part 734.3 of the EAR for exact details) because it is
|
||||||
technology testing for the Federal Government in accordance with the USA
|
a publicly available technology and software, and is freely distributed
|
||||||
PATRIOT Act and the Enhanced Border Security and Visa Entry Reform Act.
|
to any interested party with no licensing requirements. Therefore, it is
|
||||||
Specific hardware and software products identified in this software were used
|
permissible to distribute this software as a free download from the internet.
|
||||||
in order to perform the software development. In no case does such
|
|
||||||
identification imply recommendation or endorsement by the National Institute
|
Disclaimer:
|
||||||
of Standards and Technology, nor does it imply that the products and equipment
|
This software and/or related materials was developed to promote biometric
|
||||||
identified are necessarily the best available for the purpose.
|
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.
|
||||||
|
|
||||||
|
This software and/or related materials are provided "AS-IS" without warranty
|
||||||
|
of any kind including NO WARRANTY OF PERFORMANCE, MERCHANTABILITY,
|
||||||
|
NO WARRANTY OF NON-INFRINGEMENT OF ANY 3RD PARTY INTELLECTUAL PROPERTY
|
||||||
|
or FITNESS FOR A PARTICULAR PURPOSE or for any purpose whatsoever, for the
|
||||||
|
licensed product, however used. In no event shall NIST be liable for any
|
||||||
|
damages and/or costs, including but not limited to incidental or consequential
|
||||||
|
damages of any kind, including economic damage or injury to property and lost
|
||||||
|
profits, regardless of whether NIST shall be advised, have reason to know,
|
||||||
|
or in fact shall know of the possibility.
|
||||||
|
|
||||||
|
By using this software, you agree to bear all risk relating to quality,
|
||||||
|
use and performance of the software and/or related materials. You agree
|
||||||
|
to hold the Government harmless from any claim arising from your use
|
||||||
|
of the software.
|
||||||
|
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
LIBRARY: LFS - NIST Latent Fingerprint System
|
LIBRARY: LFS - NIST Latent Fingerprint System
|
||||||
|
|
||||||
|
@ -38,7 +59,6 @@ identified are necessarily the best available for the purpose.
|
||||||
***********************************************************************/
|
***********************************************************************/
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
|
||||||
#include <lfs.h>
|
#include <lfs.h>
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
|
|
254
libfprint/nbis/mindtct/link.c
Normal file
254
libfprint/nbis/mindtct/link.c
Normal file
|
@ -0,0 +1,254 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
|
||||||
|
License:
|
||||||
|
This software and/or related materials 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.
|
||||||
|
|
||||||
|
This software and/or related materials have been determined to be not subject
|
||||||
|
to the EAR (see Part 734.3 of the EAR for exact details) because it is
|
||||||
|
a publicly available technology and software, and is freely distributed
|
||||||
|
to any interested party with no licensing requirements. Therefore, it is
|
||||||
|
permissible to distribute this software as a free download from the internet.
|
||||||
|
|
||||||
|
Disclaimer:
|
||||||
|
This software and/or related materials 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.
|
||||||
|
|
||||||
|
This software and/or related materials are provided "AS-IS" without warranty
|
||||||
|
of any kind including NO WARRANTY OF PERFORMANCE, MERCHANTABILITY,
|
||||||
|
NO WARRANTY OF NON-INFRINGEMENT OF ANY 3RD PARTY INTELLECTUAL PROPERTY
|
||||||
|
or FITNESS FOR A PARTICULAR PURPOSE or for any purpose whatsoever, for the
|
||||||
|
licensed product, however used. In no event shall NIST be liable for any
|
||||||
|
damages and/or costs, including but not limited to incidental or consequential
|
||||||
|
damages of any kind, including economic damage or injury to property and lost
|
||||||
|
profits, regardless of whether NIST shall be advised, have reason to know,
|
||||||
|
or in fact shall know of the possibility.
|
||||||
|
|
||||||
|
By using this software, you agree to bear all risk relating to quality,
|
||||||
|
use and performance of the software and/or related materials. You agree
|
||||||
|
to hold the Government harmless from any claim arising from your use
|
||||||
|
of the software.
|
||||||
|
|
||||||
|
*******************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
LIBRARY: LFS - NIST Latent Fingerprint System
|
||||||
|
|
||||||
|
FILE: LINK.C
|
||||||
|
AUTHOR: Michael D. Garris
|
||||||
|
DATE: 08/02/1999
|
||||||
|
UPDATED: 10/04/1999 Version 2 by MDG
|
||||||
|
UPDATED: 03/16/2005 by MDG
|
||||||
|
|
||||||
|
Contains routines responsible for linking compatible minutiae
|
||||||
|
together as part of the NIST Latent Fingerprint System (LFS).
|
||||||
|
|
||||||
|
***********************************************************************
|
||||||
|
ROUTINES:
|
||||||
|
link_minutiae()
|
||||||
|
create_link_table()
|
||||||
|
update_link_table()
|
||||||
|
order_link_table()
|
||||||
|
process_link_table()
|
||||||
|
link_score()
|
||||||
|
***********************************************************************/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <lfs.h>
|
||||||
|
#include <log.h>
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
#cat: link_minutiae - Clusters minutiae that are sufficiently close to each
|
||||||
|
#cat: other and have compatible directions to be considered part
|
||||||
|
#cat: of the same ridge or valley and then links them together.
|
||||||
|
#cat: In linking two minutia, the respective minutia features
|
||||||
|
#cat: in the image are joined by drawing pixels and the points
|
||||||
|
#cat: are removed from the list.
|
||||||
|
|
||||||
|
Input:
|
||||||
|
minutiae - list of true and false minutiae
|
||||||
|
bdata - binary image data (0==while & 1==black)
|
||||||
|
iw - width (in pixels) of image
|
||||||
|
ih - height (in pixels) of image
|
||||||
|
nmap - IMAP ridge flow matrix with invalid, high-curvature,
|
||||||
|
and no-valid-neighbor regions identified
|
||||||
|
mw - width in blocks of the NMAP
|
||||||
|
mh - height in blocks of the NMAP
|
||||||
|
lfsparms - parameters and thresholds for controlling LFS
|
||||||
|
Output:
|
||||||
|
minutiae - list of pruned minutiae
|
||||||
|
bdata - edited binary image with breaks in ridges and valleys filled
|
||||||
|
Return Code:
|
||||||
|
Zero - successful completion
|
||||||
|
Negative - system error
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
#cat: create_link_table - Builds a 2D minutia link table where each cell in the
|
||||||
|
#cat: table represents a potential linking of 2 different
|
||||||
|
#cat: minutia points. Minutia IDs are stored on each axes
|
||||||
|
#cat: and scores representing the degree of compatibility
|
||||||
|
#cat: between 2 minutia are stored in each cell. Note that
|
||||||
|
#cat: the table is sparsely filled with scores.
|
||||||
|
|
||||||
|
Input:
|
||||||
|
tbldim - dimension of each axes of the link table
|
||||||
|
start - index position of starting minutia point in input list
|
||||||
|
minutiae - list of minutia
|
||||||
|
onloop - list of loop flags (on flag for each minutia point in list)
|
||||||
|
nmap - IMAP ridge flow matrix with invalid, high-curvature,
|
||||||
|
and no-valid-neighbor regions identified
|
||||||
|
mw - width in blocks of the NMAP
|
||||||
|
mh - height in blocks of the NMAP
|
||||||
|
bdata - binary image data (0==while & 1==black)
|
||||||
|
iw - width (in pixels) of image
|
||||||
|
ih - height (in pixels) of image
|
||||||
|
lfsparms - parameters and thresholds for controlling LFS
|
||||||
|
Output:
|
||||||
|
olink_table - sparse 2D table containing scores of potentially
|
||||||
|
linked minutia pairs
|
||||||
|
ox_axis - minutia IDs registered along x-axis
|
||||||
|
oy_axis - minutia IDs registered along y-axis
|
||||||
|
onx_axis - number of minutia registered along x-axis
|
||||||
|
ony_axis - number of minutia registered along y-axis
|
||||||
|
on_entries - number of scores currently entered in the table
|
||||||
|
Return Code:
|
||||||
|
Zero - successful completion
|
||||||
|
Negative - system error
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
#cat: update_link_table - Takes the indices of 2 minutia and their link
|
||||||
|
#cat: compatibility score and updates the 2D link table.
|
||||||
|
#cat: The input minutia are registered to positions along
|
||||||
|
#cat: different axes, if they are not already in the table,
|
||||||
|
#cat: and a queue is maintained so that a cluster of
|
||||||
|
#cat: potentially linked points may be gathered.
|
||||||
|
|
||||||
|
Input:
|
||||||
|
link_table - sparse 2D table containing scores of potentially linked
|
||||||
|
minutia pairs
|
||||||
|
x_axis - minutia IDs registered along x-axis
|
||||||
|
y_axis - minutia IDs registered along y-axis
|
||||||
|
nx_axis - number of minutia registered along x-axis
|
||||||
|
ny_axis - number of minutia registered along y-axis
|
||||||
|
n_entries - number of scores currently entered in the table
|
||||||
|
tbldim - dimension of each axes of the link table
|
||||||
|
queue - list of clustered minutiae yet to be used to locate
|
||||||
|
other compatible minutiae
|
||||||
|
head - head of the queue
|
||||||
|
tail - tail of the queue
|
||||||
|
inqueue - flag for each minutia point in minutiae list to signify if
|
||||||
|
it has been clustered with the points in this current link
|
||||||
|
table
|
||||||
|
first - index position of first minutia of current link pair
|
||||||
|
second - index position of second minutia of current link pair
|
||||||
|
score - degree of link compatibility of current link pair
|
||||||
|
Output:
|
||||||
|
link_table - updated sparse 2D table containing scores of potentially
|
||||||
|
linked minutia pairs
|
||||||
|
x_axis - updated minutia IDs registered along x-axis
|
||||||
|
y_axis - updated minutia IDs registered along y-axis
|
||||||
|
nx_axis - updated number of minutia registered along x-axis
|
||||||
|
ny_axis - updated number of minutia registered along y-axis
|
||||||
|
n_entries - updated number of scores currently entered in the table
|
||||||
|
queue - updated list of clustered minutiae yet to be used to locate
|
||||||
|
other compatible minutiae
|
||||||
|
tail - updated tail of the queue
|
||||||
|
inqueue - updated list of flags, one for each minutia point in
|
||||||
|
minutiae list to signify if it has been clustered with
|
||||||
|
the points in this current link table
|
||||||
|
Return Code:
|
||||||
|
Zero - successful completion
|
||||||
|
Negative - system error
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
#cat: order_link_table - Puts the link table in sorted order based on x and
|
||||||
|
#cat: then y-axis entries. These minutia are sorted based
|
||||||
|
#cat: on their point of perpendicular intersection with a
|
||||||
|
#cat: line running from the origin at an angle equal to the
|
||||||
|
#cat: average direction of all entries in the link table.
|
||||||
|
|
||||||
|
Input:
|
||||||
|
link_table - sparse 2D table containing scores of potentially linked
|
||||||
|
minutia pairs
|
||||||
|
x_axis - minutia IDs registered along x-axis
|
||||||
|
y_axis - minutia IDs registered along y-axis
|
||||||
|
nx_axis - number of minutia registered along x-axis
|
||||||
|
ny_axis - number of minutia registered along y-axis
|
||||||
|
n_entries - number of scores currently entered in the table
|
||||||
|
tbldim - dimension of each axes of the link table
|
||||||
|
minutiae - list of minutia
|
||||||
|
ndirs - number of IMAP directions (in semicircle)
|
||||||
|
Output:
|
||||||
|
link_table - sorted sparse 2D table containing scores of potentially
|
||||||
|
linked minutia pairs
|
||||||
|
x_axis - sorted minutia IDs registered along x-axis
|
||||||
|
y_axis - sorted minutia IDs registered along y-axis
|
||||||
|
Return Code:
|
||||||
|
Zero - successful completion
|
||||||
|
Negative - system error
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
#cat: process_link_table - Processes the link table deciding which minutia
|
||||||
|
#cat: pairs in the table should be linked (ie. joined in
|
||||||
|
#cat: the image and removed from the minutiae list (and
|
||||||
|
#cat: from onloop).
|
||||||
|
|
||||||
|
Input:
|
||||||
|
link_table - sparse 2D table containing scores of potentially linked
|
||||||
|
minutia pairs
|
||||||
|
x_axis - minutia IDs registered along x-axis
|
||||||
|
y_axis - minutia IDs registered along y-axis
|
||||||
|
nx_axis - number of minutia registered along x-axis
|
||||||
|
ny_axis - number of minutia registered along y-axis
|
||||||
|
n_entries - number of scores currently entered in the table
|
||||||
|
tbldim - dimension of each axes of the link table
|
||||||
|
minutiae - list of minutia
|
||||||
|
onloop - list of flags signifying which minutia lie on small lakes
|
||||||
|
bdata - binary image data (0==while & 1==black)
|
||||||
|
iw - width (in pixels) of image
|
||||||
|
ih - height (in pixels) of image
|
||||||
|
lfsparms - parameters and thresholds for controlling LFS
|
||||||
|
Output:
|
||||||
|
minutiae - list of pruned minutiae
|
||||||
|
onloop - updated loop flags
|
||||||
|
bdata - edited image with minutia features joined
|
||||||
|
Return Code:
|
||||||
|
Zero - successful completion
|
||||||
|
Negative - system error
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
#cat: link_score - Takes 2 parameters, a 'join angle' and a 'join distance'
|
||||||
|
#cat: computed between 2 minutia and combines these to compute
|
||||||
|
#cat: a score representing the degree of link compatibility
|
||||||
|
#cat: between the 2 minutiae.
|
||||||
|
|
||||||
|
Input:
|
||||||
|
jointheta - angle measured between 2 minutiae
|
||||||
|
joindist - distance between 2 minutiae
|
||||||
|
lfsparms - parameters and thresholds for controlling LFS
|
||||||
|
Return Code:
|
||||||
|
Score - degree of link compatibility
|
||||||
|
**************************************************************************/
|
||||||
|
|
|
@ -1,26 +1,47 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
|
|
||||||
License:
|
License:
|
||||||
This software was developed at the National Institute of Standards and
|
This software and/or related materials was developed at the National Institute
|
||||||
Technology (NIST) by employees of the Federal Government in the course
|
of Standards and Technology (NIST) by employees of the Federal Government
|
||||||
of their official duties. Pursuant to title 17 Section 105 of the
|
in the course of their official duties. Pursuant to title 17 Section 105
|
||||||
United States Code, this software is not subject to copyright protection
|
of the United States Code, this software is not subject to copyright
|
||||||
and is in the public domain. NIST assumes no responsibility whatsoever for
|
protection and is in the public domain.
|
||||||
its use by other parties, and makes no guarantees, expressed or implied,
|
|
||||||
about its quality, reliability, or any other characteristic.
|
|
||||||
|
|
||||||
Disclaimer:
|
This software and/or related materials have been determined to be not subject
|
||||||
This software was developed to promote biometric standards and biometric
|
to the EAR (see Part 734.3 of the EAR for exact details) because it is
|
||||||
technology testing for the Federal Government in accordance with the USA
|
a publicly available technology and software, and is freely distributed
|
||||||
PATRIOT Act and the Enhanced Border Security and Visa Entry Reform Act.
|
to any interested party with no licensing requirements. Therefore, it is
|
||||||
Specific hardware and software products identified in this software were used
|
permissible to distribute this software as a free download from the internet.
|
||||||
in order to perform the software development. In no case does such
|
|
||||||
identification imply recommendation or endorsement by the National Institute
|
Disclaimer:
|
||||||
of Standards and Technology, nor does it imply that the products and equipment
|
This software and/or related materials was developed to promote biometric
|
||||||
identified are necessarily the best available for the purpose.
|
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.
|
||||||
|
|
||||||
|
This software and/or related materials are provided "AS-IS" without warranty
|
||||||
|
of any kind including NO WARRANTY OF PERFORMANCE, MERCHANTABILITY,
|
||||||
|
NO WARRANTY OF NON-INFRINGEMENT OF ANY 3RD PARTY INTELLECTUAL PROPERTY
|
||||||
|
or FITNESS FOR A PARTICULAR PURPOSE or for any purpose whatsoever, for the
|
||||||
|
licensed product, however used. In no event shall NIST be liable for any
|
||||||
|
damages and/or costs, including but not limited to incidental or consequential
|
||||||
|
damages of any kind, including economic damage or injury to property and lost
|
||||||
|
profits, regardless of whether NIST shall be advised, have reason to know,
|
||||||
|
or in fact shall know of the possibility.
|
||||||
|
|
||||||
|
By using this software, you agree to bear all risk relating to quality,
|
||||||
|
use and performance of the software and/or related materials. You agree
|
||||||
|
to hold the Government harmless from any claim arising from your use
|
||||||
|
of the software.
|
||||||
|
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
LIBRARY: LFS - NIST Latent Fingerprint System
|
LIBRARY: LFS - NIST Latent Fingerprint System
|
||||||
|
|
||||||
|
@ -42,17 +63,12 @@ identified are necessarily the best available for the purpose.
|
||||||
|
|
||||||
/* If logging is on, declare global file pointer and supporting */
|
/* If logging is on, declare global file pointer and supporting */
|
||||||
/* global variable for logging intermediate results. */
|
/* global variable for logging intermediate results. */
|
||||||
FILE *logfp;
|
|
||||||
int avrdir;
|
|
||||||
float dir_strength;
|
|
||||||
int nvalid;
|
|
||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
int open_logfile()
|
int open_logfile()
|
||||||
{
|
{
|
||||||
#ifdef LOG_REPORT
|
#ifdef LOG_REPORT
|
||||||
if((logfp = fopen(LOG_FILE, "wb")) == NULL){
|
|
||||||
fprintf(stderr, "ERROR : open_logfile : fopen : %s\n", LOG_FILE);
|
fprintf(stderr, "ERROR : open_logfile : fopen : %s\n", LOG_FILE);
|
||||||
return(-1);
|
return(-1);
|
||||||
}
|
}
|
||||||
|
@ -69,7 +85,6 @@ void print2log(char *fmt, ...)
|
||||||
va_list ap;
|
va_list ap;
|
||||||
|
|
||||||
va_start(ap, fmt);
|
va_start(ap, fmt);
|
||||||
vfprintf(logfp, fmt, ap);
|
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -79,7 +94,6 @@ void print2log(char *fmt, ...)
|
||||||
int close_logfile()
|
int close_logfile()
|
||||||
{
|
{
|
||||||
#ifdef LOG_REPORT
|
#ifdef LOG_REPORT
|
||||||
if(fclose(logfp)){
|
|
||||||
fprintf(stderr, "ERROR : close_logfile : fclose : %s\n", LOG_FILE);
|
fprintf(stderr, "ERROR : close_logfile : fclose : %s\n", LOG_FILE);
|
||||||
return(-1);
|
return(-1);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,26 +1,47 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
|
|
||||||
License:
|
License:
|
||||||
This software was developed at the National Institute of Standards and
|
This software and/or related materials was developed at the National Institute
|
||||||
Technology (NIST) by employees of the Federal Government in the course
|
of Standards and Technology (NIST) by employees of the Federal Government
|
||||||
of their official duties. Pursuant to title 17 Section 105 of the
|
in the course of their official duties. Pursuant to title 17 Section 105
|
||||||
United States Code, this software is not subject to copyright protection
|
of the United States Code, this software is not subject to copyright
|
||||||
and is in the public domain. NIST assumes no responsibility whatsoever for
|
protection and is in the public domain.
|
||||||
its use by other parties, and makes no guarantees, expressed or implied,
|
|
||||||
about its quality, reliability, or any other characteristic.
|
|
||||||
|
|
||||||
Disclaimer:
|
This software and/or related materials have been determined to be not subject
|
||||||
This software was developed to promote biometric standards and biometric
|
to the EAR (see Part 734.3 of the EAR for exact details) because it is
|
||||||
technology testing for the Federal Government in accordance with the USA
|
a publicly available technology and software, and is freely distributed
|
||||||
PATRIOT Act and the Enhanced Border Security and Visa Entry Reform Act.
|
to any interested party with no licensing requirements. Therefore, it is
|
||||||
Specific hardware and software products identified in this software were used
|
permissible to distribute this software as a free download from the internet.
|
||||||
in order to perform the software development. In no case does such
|
|
||||||
identification imply recommendation or endorsement by the National Institute
|
Disclaimer:
|
||||||
of Standards and Technology, nor does it imply that the products and equipment
|
This software and/or related materials was developed to promote biometric
|
||||||
identified are necessarily the best available for the purpose.
|
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.
|
||||||
|
|
||||||
|
This software and/or related materials are provided "AS-IS" without warranty
|
||||||
|
of any kind including NO WARRANTY OF PERFORMANCE, MERCHANTABILITY,
|
||||||
|
NO WARRANTY OF NON-INFRINGEMENT OF ANY 3RD PARTY INTELLECTUAL PROPERTY
|
||||||
|
or FITNESS FOR A PARTICULAR PURPOSE or for any purpose whatsoever, for the
|
||||||
|
licensed product, however used. In no event shall NIST be liable for any
|
||||||
|
damages and/or costs, including but not limited to incidental or consequential
|
||||||
|
damages of any kind, including economic damage or injury to property and lost
|
||||||
|
profits, regardless of whether NIST shall be advised, have reason to know,
|
||||||
|
or in fact shall know of the possibility.
|
||||||
|
|
||||||
|
By using this software, you agree to bear all risk relating to quality,
|
||||||
|
use and performance of the software and/or related materials. You agree
|
||||||
|
to hold the Government harmless from any claim arising from your use
|
||||||
|
of the software.
|
||||||
|
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
LIBRARY: LFS - NIST Latent Fingerprint System
|
LIBRARY: LFS - NIST Latent Fingerprint System
|
||||||
|
|
||||||
|
@ -36,8 +57,6 @@ identified are necessarily the best available for the purpose.
|
||||||
|
|
||||||
***********************************************************************
|
***********************************************************************
|
||||||
ROUTINES:
|
ROUTINES:
|
||||||
chain_code_loop()
|
|
||||||
is_chain_clockwise()
|
|
||||||
get_loop_list()
|
get_loop_list()
|
||||||
on_loop()
|
on_loop()
|
||||||
on_island_lake()
|
on_island_lake()
|
||||||
|
@ -48,161 +67,13 @@ identified are necessarily the best available for the purpose.
|
||||||
get_loop_aspect()
|
get_loop_aspect()
|
||||||
fill_loop()
|
fill_loop()
|
||||||
fill_partial_row()
|
fill_partial_row()
|
||||||
|
flood_loop()
|
||||||
|
flood_fill4()
|
||||||
***********************************************************************/
|
***********************************************************************/
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
|
||||||
#include <lfs.h>
|
#include <lfs.h>
|
||||||
|
|
||||||
/*************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
#cat: chain_code_loop - Converts a feature's contour points into an
|
|
||||||
#cat: 8-connected chain code vector. This encoding represents
|
|
||||||
#cat: the direction taken between each adjacent point in the
|
|
||||||
#cat: contour. Chain codes may be used for many purposes, such
|
|
||||||
#cat: as computing the perimeter or area of an object, and they
|
|
||||||
#cat: may be used in object detection and recognition.
|
|
||||||
|
|
||||||
Input:
|
|
||||||
contour_x - x-coord list for feature's contour points
|
|
||||||
contour_y - y-coord list for feature's contour points
|
|
||||||
ncontour - number of points in contour
|
|
||||||
Output:
|
|
||||||
ochain - resulting vector of chain codes
|
|
||||||
onchain - number of codes in chain
|
|
||||||
(same as number of points in contour)
|
|
||||||
Return Code:
|
|
||||||
Zero - chain code successful derived
|
|
||||||
Negative - system error
|
|
||||||
**************************************************************************/
|
|
||||||
static int chain_code_loop(int **ochain, int *onchain,
|
|
||||||
const int *contour_x, const int *contour_y, const int ncontour)
|
|
||||||
{
|
|
||||||
int *chain;
|
|
||||||
int i, j, dx, dy;
|
|
||||||
|
|
||||||
/* If we don't have at least 3 points in the contour ... */
|
|
||||||
if(ncontour <= 3){
|
|
||||||
/* Then we don't have a loop, so set chain length to 0 */
|
|
||||||
/* and return without any allocations. */
|
|
||||||
*onchain = 0;
|
|
||||||
return(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Allocate chain code vector. It will be the same length as the */
|
|
||||||
/* number of points in the contour. There will be one chain code */
|
|
||||||
/* between each point on the contour including a code between the */
|
|
||||||
/* last to the first point on the contour (completing the loop). */
|
|
||||||
chain = (int *)malloc(ncontour * sizeof(int));
|
|
||||||
/* If the allocation fails ... */
|
|
||||||
if(chain == (int *)NULL){
|
|
||||||
fprintf(stderr, "ERROR : chain_code_loop : malloc : chain\n");
|
|
||||||
return(-170);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* For each neighboring point in the list (with "i" pointing to the */
|
|
||||||
/* previous neighbor and "j" pointing to the next neighbor... */
|
|
||||||
for(i = 0, j=1; i < ncontour-1; i++, j++){
|
|
||||||
/* Compute delta in X between neighbors. */
|
|
||||||
dx = contour_x[j] - contour_x[i];
|
|
||||||
/* Compute delta in Y between neighbors. */
|
|
||||||
dy = contour_y[j] - contour_y[i];
|
|
||||||
/* Derive chain code index from neighbor deltas. */
|
|
||||||
/* The deltas are on the range [-1..1], so to use them as indices */
|
|
||||||
/* into the code list, they must first be incremented by one. */
|
|
||||||
chain[i] = *(g_chaincodes_nbr8+((dy+1)*NBR8_DIM)+dx+1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Now derive chain code between last and first points in the */
|
|
||||||
/* contour list. */
|
|
||||||
dx = contour_x[0] - contour_x[i];
|
|
||||||
dy = contour_y[0] - contour_y[i];
|
|
||||||
chain[i] = *(g_chaincodes_nbr8+((dy+1)*NBR8_DIM)+dx+1);
|
|
||||||
|
|
||||||
/* Store results to the output pointers. */
|
|
||||||
*ochain = chain;
|
|
||||||
*onchain = ncontour;
|
|
||||||
|
|
||||||
/* Return normally. */
|
|
||||||
return(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
#cat: is_chain_clockwise - Takes an 8-connected chain code vector and
|
|
||||||
#cat: determines if the codes are ordered clockwise or
|
|
||||||
#cat: counter-clockwise.
|
|
||||||
#cat: The routine also requires a default return value be
|
|
||||||
#cat: specified in the case the the routine is not able to
|
|
||||||
#cat: definitively determine the chains direction. This allows
|
|
||||||
#cat: the default response to be application-specific.
|
|
||||||
|
|
||||||
Input:
|
|
||||||
chain - chain code vector
|
|
||||||
nchain - number of codes in chain
|
|
||||||
default_ret - default return code (used when we can't tell the order)
|
|
||||||
Return Code:
|
|
||||||
TRUE - chain determined to be ordered clockwise
|
|
||||||
FALSE - chain determined to be ordered counter-clockwise
|
|
||||||
Default - could not determine the order of the chain
|
|
||||||
**************************************************************************/
|
|
||||||
static int is_chain_clockwise(const int *chain, const int nchain,
|
|
||||||
const int default_ret)
|
|
||||||
{
|
|
||||||
int i, j, d, sum;
|
|
||||||
|
|
||||||
/* Initialize turn-accumulator to 0. */
|
|
||||||
sum = 0;
|
|
||||||
|
|
||||||
/* Foreach neighboring code in chain, compute the difference in */
|
|
||||||
/* direction and accumulate. Left-hand turns increment, whereas */
|
|
||||||
/* right-hand decrement. */
|
|
||||||
for(i = 0, j =1; i < nchain-1; i++, j++){
|
|
||||||
/* Compute delta in neighbor direction. */
|
|
||||||
d = chain[j] - chain[i];
|
|
||||||
/* Make the delta the "inner" distance. */
|
|
||||||
/* If delta >= 4, for example if chain_i==2 and chain_j==7 (which */
|
|
||||||
/* means the contour went from a step up to step down-to-the-right) */
|
|
||||||
/* then 5=(7-2) which is >=4, so -3=(5-8) which means that the */
|
|
||||||
/* change in direction is a righ-hand turn of 3 units). */
|
|
||||||
if(d >= 4)
|
|
||||||
d -= 8;
|
|
||||||
/* If delta <= -4, for example if chain_i==7 and chain_j==2 (which */
|
|
||||||
/* means the contour went from a step down-to-the-right to step up) */
|
|
||||||
/* then -5=(2-7) which is <=-4, so 3=(-5+8) which means that the */
|
|
||||||
/* change in direction is a left-hand turn of 3 units). */
|
|
||||||
else if (d <= -4)
|
|
||||||
d += 8;
|
|
||||||
|
|
||||||
/* The delta direction is then accumulated. */
|
|
||||||
sum += d;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Now we need to add in the final delta direction between the last */
|
|
||||||
/* and first codes in the chain. */
|
|
||||||
d = chain[0] - chain[i];
|
|
||||||
if(d >= 4)
|
|
||||||
d -= 8;
|
|
||||||
else if (d <= -4)
|
|
||||||
d += 8;
|
|
||||||
sum += d;
|
|
||||||
|
|
||||||
/* If the final turn_accumulator == 0, then we CAN'T TELL the */
|
|
||||||
/* direction of the chain code, so return the default return value. */
|
|
||||||
if(sum == 0)
|
|
||||||
return(default_ret);
|
|
||||||
/* Otherwise, if the final turn-accumulator is positive ... */
|
|
||||||
else if(sum > 0)
|
|
||||||
/* Then we had a greater amount of left-hand turns than right-hand */
|
|
||||||
/* turns, so the chain is in COUNTER-CLOCKWISE order, so return FALSE. */
|
|
||||||
return(FALSE);
|
|
||||||
/* Otherwise, the final turn-accumulator is negative ... */
|
|
||||||
else
|
|
||||||
/* So we had a greater amount of right-hand turns than left-hand */
|
|
||||||
/* turns, so the chain is in CLOCKWISE order, so return TRUE. */
|
|
||||||
return(TRUE);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
**************************************************************************
|
**************************************************************************
|
||||||
#cat: get_loop_list - Takes a list of minutia points and determines which
|
#cat: get_loop_list - Takes a list of minutia points and determines which
|
||||||
|
@ -228,78 +99,6 @@ static int is_chain_clockwise(const int *chain, const int nchain,
|
||||||
Zero - successful completion
|
Zero - successful completion
|
||||||
Negative - system error
|
Negative - system error
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
int get_loop_list(int **oonloop, MINUTIAE *minutiae, const int loop_len,
|
|
||||||
unsigned char *bdata, const int iw, const int ih)
|
|
||||||
{
|
|
||||||
int i, ret;
|
|
||||||
int *onloop;
|
|
||||||
MINUTIA *minutia;
|
|
||||||
|
|
||||||
/* Allocate a list of onloop flags (one for each minutia in list). */
|
|
||||||
onloop = (int *)malloc(minutiae->num * sizeof(int));
|
|
||||||
if(onloop == (int *)NULL){
|
|
||||||
fprintf(stderr, "ERROR : get_loop_list : malloc : onloop\n");
|
|
||||||
return(-320);
|
|
||||||
}
|
|
||||||
|
|
||||||
i = 0;
|
|
||||||
/* Foreach minutia remaining in list ... */
|
|
||||||
while(i < minutiae->num){
|
|
||||||
/* Assign a temporary pointer. */
|
|
||||||
minutia = minutiae->list[i];
|
|
||||||
/* If current minutia is a bifurcation ... */
|
|
||||||
if(minutia->type == BIFURCATION){
|
|
||||||
/* Check to see if it is on a loop of specified length. */
|
|
||||||
ret = on_loop(minutia, loop_len, bdata, iw, ih);
|
|
||||||
/* If minutia is on a loop... */
|
|
||||||
if(ret == LOOP_FOUND){
|
|
||||||
/* Then set the onloop flag to TRUE. */
|
|
||||||
onloop[i] = TRUE;
|
|
||||||
/* Advance to next minutia in the list. */
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
/* If on loop test IGNORED ... */
|
|
||||||
else if (ret == IGNORE){
|
|
||||||
/* Remove the current minutia from the list. */
|
|
||||||
if((ret = remove_minutia(i, minutiae))){
|
|
||||||
/* Deallocate working memory. */
|
|
||||||
free(onloop);
|
|
||||||
/* Return error code. */
|
|
||||||
return(ret);
|
|
||||||
}
|
|
||||||
/* No need to advance because next minutia has "slid" */
|
|
||||||
/* into position pointed to by 'i'. */
|
|
||||||
}
|
|
||||||
/* If the minutia is NOT on a loop... */
|
|
||||||
else if (ret == FALSE){
|
|
||||||
/* Then set the onloop flag to FALSE. */
|
|
||||||
onloop[i] = FALSE;
|
|
||||||
/* Advance to next minutia in the list. */
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
/* Otherwise, an ERROR occurred while looking for loop. */
|
|
||||||
else{
|
|
||||||
/* Deallocate working memory. */
|
|
||||||
free(onloop);
|
|
||||||
/* Return error code. */
|
|
||||||
return(ret);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/* Otherwise, the current minutia is a ridge-ending... */
|
|
||||||
else{
|
|
||||||
/* Ridge-endings will never be on a loop, so set flag to FALSE. */
|
|
||||||
onloop[i] = FALSE;
|
|
||||||
/* Advance to next minutia in the list. */
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Store flag list to output pointer. */
|
|
||||||
*oonloop = onloop;
|
|
||||||
|
|
||||||
/* Return normally. */
|
|
||||||
return(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
**************************************************************************
|
**************************************************************************
|
||||||
|
@ -558,7 +357,7 @@ int on_hook(const MINUTIA *minutia1, const MINUTIA *minutia2,
|
||||||
/* If trace had an error in following the contour ... */
|
/* If trace had an error in following the contour ... */
|
||||||
if(ret != 0)
|
if(ret != 0)
|
||||||
return(ret);
|
return(ret);
|
||||||
|
|
||||||
|
|
||||||
/* Otherwise, the trace successfully followed the contour, but did */
|
/* Otherwise, the trace successfully followed the contour, but did */
|
||||||
/* not encounter the 2nd minutia point within the specified number */
|
/* not encounter the 2nd minutia point within the specified number */
|
||||||
|
@ -648,107 +447,6 @@ int is_loop_clockwise(const int *contour_x, const int *contour_y,
|
||||||
return(ret);
|
return(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
#cat: get_loop_aspect - Takes a contour list (determined to form a complete
|
|
||||||
#cat: loop) and measures the loop's aspect (the largest and smallest
|
|
||||||
#cat: distances across the loop) and returns the points on the
|
|
||||||
#cat: loop where these distances occur.
|
|
||||||
|
|
||||||
Input:
|
|
||||||
contour_x - x-coord list for loop's contour points
|
|
||||||
contour_y - y-coord list for loop's contour points
|
|
||||||
ncontour - number of points in contour
|
|
||||||
Output:
|
|
||||||
omin_fr - contour point index where minimum aspect occurs
|
|
||||||
omin_to - opposite contour point index where minimum aspect occurs
|
|
||||||
omin_dist - the minimum distance across the loop
|
|
||||||
omax_fr - contour point index where maximum aspect occurs
|
|
||||||
omax_to - contour point index where maximum aspect occurs
|
|
||||||
omax_dist - the maximum distance across the loop
|
|
||||||
**************************************************************************/
|
|
||||||
static void get_loop_aspect(int *omin_fr, int *omin_to, double *omin_dist,
|
|
||||||
int *omax_fr, int *omax_to, double *omax_dist,
|
|
||||||
const int *contour_x, const int *contour_y, const int ncontour)
|
|
||||||
{
|
|
||||||
int halfway, limit;
|
|
||||||
int i, j;
|
|
||||||
double dist;
|
|
||||||
double min_dist, max_dist;
|
|
||||||
int min_i, max_i, min_j, max_j;
|
|
||||||
|
|
||||||
/* Compute half the perimeter of the loop. */
|
|
||||||
halfway = ncontour>>1;
|
|
||||||
|
|
||||||
/* Take opposite points on the contour and walk half way */
|
|
||||||
/* around the loop. */
|
|
||||||
i = 0;
|
|
||||||
j = halfway;
|
|
||||||
/* Compute squared distance between opposite points on loop. */
|
|
||||||
dist = squared_distance(contour_x[i], contour_y[i],
|
|
||||||
contour_x[j], contour_y[j]);
|
|
||||||
|
|
||||||
/* Initialize running minimum and maximum distances along loop. */
|
|
||||||
min_dist = dist;
|
|
||||||
min_i = i;
|
|
||||||
min_j = j;
|
|
||||||
max_dist = dist;
|
|
||||||
max_i = i;
|
|
||||||
max_j = j;
|
|
||||||
/* Bump to next pair of opposite points. */
|
|
||||||
i++;
|
|
||||||
/* Make sure j wraps around end of list. */
|
|
||||||
j++;
|
|
||||||
j %= ncontour;
|
|
||||||
|
|
||||||
/* If the loop is of even length, then we only need to walk half */
|
|
||||||
/* way around as the other half will be exactly redundant. If */
|
|
||||||
/* the loop is of odd length, then the second half will not be */
|
|
||||||
/* be exactly redundant and the difference "may" be meaningful. */
|
|
||||||
/* If execution speed is an issue, then probably get away with */
|
|
||||||
/* walking only the fist half of the loop under ALL conditions. */
|
|
||||||
|
|
||||||
/* If loop has odd length ... */
|
|
||||||
if(ncontour % 2)
|
|
||||||
/* Walk the loop's entire perimeter. */
|
|
||||||
limit = ncontour;
|
|
||||||
/* Otherwise the loop has even length ... */
|
|
||||||
else
|
|
||||||
/* Only walk half the perimeter. */
|
|
||||||
limit = halfway;
|
|
||||||
|
|
||||||
/* While we have not reached our perimeter limit ... */
|
|
||||||
while(i < limit){
|
|
||||||
/* Compute squared distance between opposite points on loop. */
|
|
||||||
dist = squared_distance(contour_x[i], contour_y[i],
|
|
||||||
contour_x[j], contour_y[j]);
|
|
||||||
/* Check the running minimum and maximum distances. */
|
|
||||||
if(dist < min_dist){
|
|
||||||
min_dist = dist;
|
|
||||||
min_i = i;
|
|
||||||
min_j = j;
|
|
||||||
}
|
|
||||||
if(dist > max_dist){
|
|
||||||
max_dist = dist;
|
|
||||||
max_i = i;
|
|
||||||
max_j = j;
|
|
||||||
}
|
|
||||||
/* Bump to next pair of opposite points. */
|
|
||||||
i++;
|
|
||||||
/* Make sure j wraps around end of list. */
|
|
||||||
j++;
|
|
||||||
j %= ncontour;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Assign minimum and maximum distances to output pointers. */
|
|
||||||
*omin_fr = min_i;
|
|
||||||
*omin_to = min_j;
|
|
||||||
*omin_dist = min_dist;
|
|
||||||
*omax_fr = max_i;
|
|
||||||
*omax_to = max_j;
|
|
||||||
*omax_dist = max_dist;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
**************************************************************************
|
**************************************************************************
|
||||||
#cat: process_loop - Takes a contour list that has been determined to form
|
#cat: process_loop - Takes a contour list that has been determined to form
|
||||||
|
@ -776,131 +474,6 @@ static void get_loop_aspect(int *omin_fr, int *omin_to, double *omin_dist,
|
||||||
Zero - loop processed successfully
|
Zero - loop processed successfully
|
||||||
Negative - system error
|
Negative - system error
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
int process_loop(MINUTIAE *minutiae,
|
|
||||||
const int *contour_x, const int *contour_y,
|
|
||||||
const int *contour_ex, const int *contour_ey, const int ncontour,
|
|
||||||
unsigned char *bdata, const int iw, const int ih,
|
|
||||||
const LFSPARMS *lfsparms)
|
|
||||||
{
|
|
||||||
int idir, type, appearing;
|
|
||||||
double min_dist, max_dist;
|
|
||||||
int min_fr, max_fr, min_to, max_to;
|
|
||||||
int mid_x, mid_y, mid_pix;
|
|
||||||
int feature_pix;
|
|
||||||
int ret;
|
|
||||||
MINUTIA *minutia;
|
|
||||||
|
|
||||||
/* If contour is empty, then just return. */
|
|
||||||
if(ncontour <= 0)
|
|
||||||
return(0);
|
|
||||||
|
|
||||||
/* If loop is large enough ... */
|
|
||||||
if(ncontour > lfsparms->min_loop_len){
|
|
||||||
/* Get pixel value of feature's interior. */
|
|
||||||
feature_pix = *(bdata + (contour_y[0] * iw) + contour_x[0]);
|
|
||||||
|
|
||||||
/* Get the aspect dimensions of the loop in units of */
|
|
||||||
/* squared distance. */
|
|
||||||
get_loop_aspect(&min_fr, &min_to, &min_dist,
|
|
||||||
&max_fr, &max_to, &max_dist,
|
|
||||||
contour_x, contour_y, ncontour);
|
|
||||||
|
|
||||||
/* If loop passes aspect ratio tests ... loop is sufficiently */
|
|
||||||
/* narrow or elongated ... */
|
|
||||||
if((min_dist < lfsparms->min_loop_aspect_dist) ||
|
|
||||||
((max_dist/min_dist) >= lfsparms->min_loop_aspect_ratio)){
|
|
||||||
|
|
||||||
/* Update minutiae list with opposite points of max distance */
|
|
||||||
/* on the loop. */
|
|
||||||
|
|
||||||
/* First, check if interior point has proper pixel value. */
|
|
||||||
mid_x = (contour_x[max_fr]+contour_x[max_to])>>1;
|
|
||||||
mid_y = (contour_y[max_fr]+contour_y[max_to])>>1;
|
|
||||||
mid_pix = *(bdata + (mid_y * iw) + mid_x);
|
|
||||||
/* If interior point is the same as the feature... */
|
|
||||||
if(mid_pix == feature_pix){
|
|
||||||
|
|
||||||
/* 1. Treat maximum distance point as a potential minutia. */
|
|
||||||
|
|
||||||
/* Compute direction from maximum loop point to its */
|
|
||||||
/* opposite point. */
|
|
||||||
idir = line2direction(contour_x[max_fr], contour_y[max_fr],
|
|
||||||
contour_x[max_to], contour_y[max_to],
|
|
||||||
lfsparms->num_directions);
|
|
||||||
/* Get type of minutia: BIFURCATION or RIDGE_ENDING. */
|
|
||||||
type = minutia_type(feature_pix);
|
|
||||||
/* Determine if minutia is appearing or disappearing. */
|
|
||||||
if((appearing = is_minutia_appearing(
|
|
||||||
contour_x[max_fr], contour_y[max_fr],
|
|
||||||
contour_ex[max_fr], contour_ey[max_fr])) < 0){
|
|
||||||
/* Return system error code. */
|
|
||||||
return(appearing);
|
|
||||||
}
|
|
||||||
/* Create new minutia object. */
|
|
||||||
if((ret = create_minutia(&minutia,
|
|
||||||
contour_x[max_fr], contour_y[max_fr],
|
|
||||||
contour_ex[max_fr], contour_ey[max_fr],
|
|
||||||
idir, DEFAULT_RELIABILITY,
|
|
||||||
type, appearing, LOOP_ID))){
|
|
||||||
/* Return system error code. */
|
|
||||||
return(ret);
|
|
||||||
}
|
|
||||||
/* Update the minutiae list with potential new minutia. */
|
|
||||||
ret = update_minutiae(minutiae, minutia, bdata, iw, ih, lfsparms);
|
|
||||||
|
|
||||||
/* If minuitia IGNORED and not added to the minutia list ... */
|
|
||||||
if(ret == IGNORE)
|
|
||||||
/* Deallocate the minutia. */
|
|
||||||
free_minutia(minutia);
|
|
||||||
|
|
||||||
/* 2. Treat point opposite of maximum distance point as */
|
|
||||||
/* a potential minutia. */
|
|
||||||
|
|
||||||
/* Flip the direction 180 degrees. Make sure new direction */
|
|
||||||
/* is on the range [0..(ndirsX2)]. */
|
|
||||||
idir += lfsparms->num_directions;
|
|
||||||
idir %= (lfsparms->num_directions<<1);
|
|
||||||
|
|
||||||
/* The type of minutia will stay the same. */
|
|
||||||
|
|
||||||
/* Determine if minutia is appearing or disappearing. */
|
|
||||||
if((appearing = is_minutia_appearing(
|
|
||||||
contour_x[max_to], contour_y[max_to],
|
|
||||||
contour_ex[max_to], contour_ey[max_to])) < 0){
|
|
||||||
/* Return system error code. */
|
|
||||||
return(appearing);
|
|
||||||
}
|
|
||||||
/* Create new minutia object. */
|
|
||||||
if((ret = create_minutia(&minutia,
|
|
||||||
contour_x[max_to], contour_y[max_to],
|
|
||||||
contour_ex[max_to], contour_ey[max_to],
|
|
||||||
idir, DEFAULT_RELIABILITY,
|
|
||||||
type, appearing, LOOP_ID))){
|
|
||||||
/* Return system error code. */
|
|
||||||
return(ret);
|
|
||||||
}
|
|
||||||
/* Update the minutiae list with potential new minutia. */
|
|
||||||
ret = update_minutiae(minutiae, minutia, bdata, iw, ih, lfsparms);
|
|
||||||
|
|
||||||
/* If minuitia IGNORED and not added to the minutia list ... */
|
|
||||||
if(ret == IGNORE)
|
|
||||||
/* Deallocate the minutia. */
|
|
||||||
free_minutia(minutia);
|
|
||||||
|
|
||||||
/* Done successfully processing this loop, so return normally. */
|
|
||||||
return(0);
|
|
||||||
|
|
||||||
} /* Otherwise, loop interior has problems. */
|
|
||||||
} /* Otherwise, loop is not the right shape for minutiae. */
|
|
||||||
} /* Otherwise, loop's perimeter is too small for minutiae. */
|
|
||||||
|
|
||||||
/* If we get here, we have a loop that is assumed to not contain */
|
|
||||||
/* minutiae, so remove the loop from the image. */
|
|
||||||
ret = fill_loop(contour_x, contour_y, ncontour, bdata, iw, ih);
|
|
||||||
|
|
||||||
/* Return either an error code from fill_loop or return normally. */
|
|
||||||
return(ret);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
**************************************************************************
|
**************************************************************************
|
||||||
|
@ -936,6 +509,7 @@ int process_loop_V2(MINUTIAE *minutiae,
|
||||||
unsigned char *bdata, const int iw, const int ih,
|
unsigned char *bdata, const int iw, const int ih,
|
||||||
int *plow_flow_map, const LFSPARMS *lfsparms)
|
int *plow_flow_map, const LFSPARMS *lfsparms)
|
||||||
{
|
{
|
||||||
|
int halfway;
|
||||||
int idir, type, appearing;
|
int idir, type, appearing;
|
||||||
double min_dist, max_dist;
|
double min_dist, max_dist;
|
||||||
int min_fr, max_fr, min_to, max_to;
|
int min_fr, max_fr, min_to, max_to;
|
||||||
|
@ -955,6 +529,9 @@ int process_loop_V2(MINUTIAE *minutiae,
|
||||||
/* Get pixel value of feature's interior. */
|
/* Get pixel value of feature's interior. */
|
||||||
feature_pix = *(bdata + (contour_y[0] * iw) + contour_x[0]);
|
feature_pix = *(bdata + (contour_y[0] * iw) + contour_x[0]);
|
||||||
|
|
||||||
|
/* Compute half the perimeter of the loop. */
|
||||||
|
halfway = ncontour>>1;
|
||||||
|
|
||||||
/* Get the aspect dimensions of the loop in units of */
|
/* Get the aspect dimensions of the loop in units of */
|
||||||
/* squared distance. */
|
/* squared distance. */
|
||||||
get_loop_aspect(&min_fr, &min_to, &min_dist,
|
get_loop_aspect(&min_fr, &min_to, &min_dist,
|
||||||
|
@ -1087,39 +664,103 @@ int process_loop_V2(MINUTIAE *minutiae,
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
**************************************************************************
|
**************************************************************************
|
||||||
#cat: fill_partial_row - Fills a specified range of contiguous pixels on
|
#cat: get_loop_aspect - Takes a contour list (determined to form a complete
|
||||||
#cat: a specified row of an 8-bit pixel image with a specified
|
#cat: loop) and measures the loop's aspect (the largest and smallest
|
||||||
#cat: pixel value. NOTE, the pixel coordinates are assumed to
|
#cat: distances across the loop) and returns the points on the
|
||||||
#cat: be within the image boundaries.
|
#cat: loop where these distances occur.
|
||||||
|
|
||||||
Input:
|
Input:
|
||||||
fill_pix - pixel value to fill with (should be on range [0..255]
|
contour_x - x-coord list for loop's contour points
|
||||||
frx - x-pixel coord where fill should begin
|
contour_y - y-coord list for loop's contour points
|
||||||
tox - x-pixel coord where fill should end (inclusive)
|
ncontour - number of points in contour
|
||||||
y - y-pixel coord of current row being filled
|
|
||||||
bdata - 8-bit image data
|
|
||||||
iw - width (in pixels) of image
|
|
||||||
ih - height (in pixels) of image
|
|
||||||
Output:
|
Output:
|
||||||
bdata - 8-bit image data with partial row filled.
|
omin_fr - contour point index where minimum aspect occurs
|
||||||
|
omin_to - opposite contour point index where minimum aspect occurs
|
||||||
|
omin_dist - the minimum distance across the loop
|
||||||
|
omax_fr - contour point index where maximum aspect occurs
|
||||||
|
omax_to - contour point index where maximum aspect occurs
|
||||||
|
omax_dist - the maximum distance across the loop
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
static void fill_partial_row(const int fill_pix, const int frx, const int tox,
|
void get_loop_aspect(int *omin_fr, int *omin_to, double *omin_dist,
|
||||||
const int y, unsigned char *bdata, const int iw, const int ih)
|
int *omax_fr, int *omax_to, double *omax_dist,
|
||||||
|
const int *contour_x, const int *contour_y, const int ncontour)
|
||||||
{
|
{
|
||||||
int x;
|
int halfway, limit;
|
||||||
unsigned char *bptr;
|
int i, j;
|
||||||
|
double dist;
|
||||||
|
double min_dist, max_dist;
|
||||||
|
int min_i, max_i, min_j, max_j;
|
||||||
|
|
||||||
/* Set pixel pointer to starting x-coord on current row. */
|
/* Compute half the perimeter of the loop. */
|
||||||
bptr = bdata+(y*iw)+frx;
|
halfway = ncontour>>1;
|
||||||
|
|
||||||
/* Foreach pixel between starting and ending x-coord on row */
|
/* Take opposite points on the contour and walk half way */
|
||||||
/* (including the end points) ... */
|
/* around the loop. */
|
||||||
for(x = frx; x <= tox; x++){
|
i = 0;
|
||||||
/* Set current pixel with fill pixel value. */
|
j = halfway;
|
||||||
*bptr = fill_pix;
|
/* Compute squared distance between opposite points on loop. */
|
||||||
/* Bump to next pixel in the row. */
|
dist = squared_distance(contour_x[i], contour_y[i],
|
||||||
bptr++;
|
contour_x[j], contour_y[j]);
|
||||||
|
|
||||||
|
/* Initialize running minimum and maximum distances along loop. */
|
||||||
|
min_dist = dist;
|
||||||
|
min_i = i;
|
||||||
|
min_j = j;
|
||||||
|
max_dist = dist;
|
||||||
|
max_i = i;
|
||||||
|
max_j = j;
|
||||||
|
/* Bump to next pair of opposite points. */
|
||||||
|
i++;
|
||||||
|
/* Make sure j wraps around end of list. */
|
||||||
|
j++;
|
||||||
|
j %= ncontour;
|
||||||
|
|
||||||
|
/* If the loop is of even length, then we only need to walk half */
|
||||||
|
/* way around as the other half will be exactly redundant. If */
|
||||||
|
/* the loop is of odd length, then the second half will not be */
|
||||||
|
/* be exactly redundant and the difference "may" be meaningful. */
|
||||||
|
/* If execution speed is an issue, then probably get away with */
|
||||||
|
/* walking only the fist half of the loop under ALL conditions. */
|
||||||
|
|
||||||
|
/* If loop has odd length ... */
|
||||||
|
if(ncontour % 2)
|
||||||
|
/* Walk the loop's entire perimeter. */
|
||||||
|
limit = ncontour;
|
||||||
|
/* Otherwise the loop has even length ... */
|
||||||
|
else
|
||||||
|
/* Only walk half the perimeter. */
|
||||||
|
limit = halfway;
|
||||||
|
|
||||||
|
/* While we have not reached our perimeter limit ... */
|
||||||
|
while(i < limit){
|
||||||
|
/* Compute squared distance between opposite points on loop. */
|
||||||
|
dist = squared_distance(contour_x[i], contour_y[i],
|
||||||
|
contour_x[j], contour_y[j]);
|
||||||
|
/* Check the running minimum and maximum distances. */
|
||||||
|
if(dist < min_dist){
|
||||||
|
min_dist = dist;
|
||||||
|
min_i = i;
|
||||||
|
min_j = j;
|
||||||
|
}
|
||||||
|
if(dist > max_dist){
|
||||||
|
max_dist = dist;
|
||||||
|
max_i = i;
|
||||||
|
max_j = j;
|
||||||
|
}
|
||||||
|
/* Bump to next pair of opposite points. */
|
||||||
|
i++;
|
||||||
|
/* Make sure j wraps around end of list. */
|
||||||
|
j++;
|
||||||
|
j %= ncontour;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Assign minimum and maximum distances to output pointers. */
|
||||||
|
*omin_fr = min_i;
|
||||||
|
*omin_to = min_j;
|
||||||
|
*omin_dist = min_dist;
|
||||||
|
*omax_fr = max_i;
|
||||||
|
*omax_to = max_j;
|
||||||
|
*omax_dist = max_dist;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
|
@ -1253,3 +894,119 @@ int fill_loop(const int *contour_x, const int *contour_y,
|
||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
#cat: fill_partial_row - Fills a specified range of contiguous pixels on
|
||||||
|
#cat: a specified row of an 8-bit pixel image with a specified
|
||||||
|
#cat: pixel value. NOTE, the pixel coordinates are assumed to
|
||||||
|
#cat: be within the image boundaries.
|
||||||
|
|
||||||
|
Input:
|
||||||
|
fill_pix - pixel value to fill with (should be on range [0..255]
|
||||||
|
frx - x-pixel coord where fill should begin
|
||||||
|
tox - x-pixel coord where fill should end (inclusive)
|
||||||
|
y - y-pixel coord of current row being filled
|
||||||
|
bdata - 8-bit image data
|
||||||
|
iw - width (in pixels) of image
|
||||||
|
ih - height (in pixels) of image
|
||||||
|
Output:
|
||||||
|
bdata - 8-bit image data with partial row filled.
|
||||||
|
**************************************************************************/
|
||||||
|
void fill_partial_row(const int fill_pix, const int frx, const int tox,
|
||||||
|
const int y, unsigned char *bdata, const int iw, const int ih)
|
||||||
|
{
|
||||||
|
int x;
|
||||||
|
unsigned char *bptr;
|
||||||
|
|
||||||
|
/* Set pixel pointer to starting x-coord on current row. */
|
||||||
|
bptr = bdata+(y*iw)+frx;
|
||||||
|
|
||||||
|
/* Foreach pixel between starting and ending x-coord on row */
|
||||||
|
/* (including the end points) ... */
|
||||||
|
for(x = frx; x <= tox; x++){
|
||||||
|
/* Set current pixel with fill pixel value. */
|
||||||
|
*bptr = fill_pix;
|
||||||
|
/* Bump to next pixel in the row. */
|
||||||
|
bptr++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
#cat: flood_loop - Fills a given contour (determined to form a complete loop)
|
||||||
|
#cat: with a specified pixel value using a recursive flood-fill
|
||||||
|
#cat: technique.
|
||||||
|
#cat: NOTE, this fill approach will NOT always work with the
|
||||||
|
#cat: contours generated in this application because they
|
||||||
|
#cat: are NOT guaranteed to be ENTIRELY surrounded by 8-connected
|
||||||
|
#cat: pixels not equal to the fill pixel value. This is unfortunate
|
||||||
|
#cat: because the flood-fill is a simple algorithm that will handle
|
||||||
|
#cat: complex/concaved shapes.
|
||||||
|
|
||||||
|
Input:
|
||||||
|
contour_x - x-coord list for loop's contour points
|
||||||
|
contour_y - y-coord list for loop's contour points
|
||||||
|
ncontour - number of points in contour
|
||||||
|
bdata - binary image data (0==while & 1==black)
|
||||||
|
iw - width (in pixels) of image
|
||||||
|
ih - height (in pixels) of image
|
||||||
|
Output:
|
||||||
|
bdata - binary image data with loop filled
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
#cat: flood_fill4 - Recursively floods a region of an 8-bit pixel image with a
|
||||||
|
#cat: specified pixel value given a starting (seed) point. The
|
||||||
|
#cat: recursion is based neighbors being 4-connected.
|
||||||
|
|
||||||
|
Input:
|
||||||
|
fill_pix - 8-bit pixel value to be filled with (on range [0..255]
|
||||||
|
x - starting x-pixel coord
|
||||||
|
y - starting y-pixel coord
|
||||||
|
bdata - 8-bit pixel image data
|
||||||
|
iw - width (in pixels) of image
|
||||||
|
ih - height (in pixels) of image
|
||||||
|
Output:
|
||||||
|
bdata - 8-bit pixel image data with region filled
|
||||||
|
**************************************************************************/
|
||||||
|
void flood_fill4(const int fill_pix, const int x, const int y,
|
||||||
|
unsigned char *bdata, const int iw, const int ih)
|
||||||
|
{
|
||||||
|
unsigned char *pptr;
|
||||||
|
int y_north, y_south, x_east, x_west;
|
||||||
|
|
||||||
|
/* Get address of current pixel. */
|
||||||
|
pptr = bdata + (y*iw) + x;
|
||||||
|
/* If pixel needs to be filled ... */
|
||||||
|
if(*pptr != fill_pix){
|
||||||
|
/* Fill the current pixel. */
|
||||||
|
*pptr = fill_pix;
|
||||||
|
|
||||||
|
/* Recursively invoke flood on the pixel's 4 neighbors. */
|
||||||
|
/* Test to make sure neighbors are within image boudaries */
|
||||||
|
/* before invoking each flood. */
|
||||||
|
y_north = y-1;
|
||||||
|
y_south = y+1;
|
||||||
|
x_west = x-1;
|
||||||
|
x_east = x+1;
|
||||||
|
|
||||||
|
/* Invoke North */
|
||||||
|
if(y_north >= 0)
|
||||||
|
flood_fill4(fill_pix, x, y_north, bdata, iw, ih);
|
||||||
|
|
||||||
|
/* Invoke East */
|
||||||
|
if(x_east < iw)
|
||||||
|
flood_fill4(fill_pix, x_east, y, bdata, iw, ih);
|
||||||
|
|
||||||
|
/* Invoke South */
|
||||||
|
if(y_south < ih)
|
||||||
|
flood_fill4(fill_pix, x, y_south, bdata, iw, ih);
|
||||||
|
|
||||||
|
/* Invoke West */
|
||||||
|
if(x_west >= 0)
|
||||||
|
flood_fill4(fill_pix, x_west, y, bdata, iw, ih);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Otherwise, there is nothing to be done. */
|
||||||
|
}
|
||||||
|
|
|
@ -1,26 +1,47 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
|
|
||||||
License:
|
License:
|
||||||
This software was developed at the National Institute of Standards and
|
This software and/or related materials was developed at the National Institute
|
||||||
Technology (NIST) by employees of the Federal Government in the course
|
of Standards and Technology (NIST) by employees of the Federal Government
|
||||||
of their official duties. Pursuant to title 17 Section 105 of the
|
in the course of their official duties. Pursuant to title 17 Section 105
|
||||||
United States Code, this software is not subject to copyright protection
|
of the United States Code, this software is not subject to copyright
|
||||||
and is in the public domain. NIST assumes no responsibility whatsoever for
|
protection and is in the public domain.
|
||||||
its use by other parties, and makes no guarantees, expressed or implied,
|
|
||||||
about its quality, reliability, or any other characteristic.
|
|
||||||
|
|
||||||
Disclaimer:
|
This software and/or related materials have been determined to be not subject
|
||||||
This software was developed to promote biometric standards and biometric
|
to the EAR (see Part 734.3 of the EAR for exact details) because it is
|
||||||
technology testing for the Federal Government in accordance with the USA
|
a publicly available technology and software, and is freely distributed
|
||||||
PATRIOT Act and the Enhanced Border Security and Visa Entry Reform Act.
|
to any interested party with no licensing requirements. Therefore, it is
|
||||||
Specific hardware and software products identified in this software were used
|
permissible to distribute this software as a free download from the internet.
|
||||||
in order to perform the software development. In no case does such
|
|
||||||
identification imply recommendation or endorsement by the National Institute
|
Disclaimer:
|
||||||
of Standards and Technology, nor does it imply that the products and equipment
|
This software and/or related materials was developed to promote biometric
|
||||||
identified are necessarily the best available for the purpose.
|
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.
|
||||||
|
|
||||||
|
This software and/or related materials are provided "AS-IS" without warranty
|
||||||
|
of any kind including NO WARRANTY OF PERFORMANCE, MERCHANTABILITY,
|
||||||
|
NO WARRANTY OF NON-INFRINGEMENT OF ANY 3RD PARTY INTELLECTUAL PROPERTY
|
||||||
|
or FITNESS FOR A PARTICULAR PURPOSE or for any purpose whatsoever, for the
|
||||||
|
licensed product, however used. In no event shall NIST be liable for any
|
||||||
|
damages and/or costs, including but not limited to incidental or consequential
|
||||||
|
damages of any kind, including economic damage or injury to property and lost
|
||||||
|
profits, regardless of whether NIST shall be advised, have reason to know,
|
||||||
|
or in fact shall know of the possibility.
|
||||||
|
|
||||||
|
By using this software, you agree to bear all risk relating to quality,
|
||||||
|
use and performance of the software and/or related materials. You agree
|
||||||
|
to hold the Government harmless from any claim arising from your use
|
||||||
|
of the software.
|
||||||
|
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
LIBRARY: LFS - NIST Latent Fingerprint System
|
LIBRARY: LFS - NIST Latent Fingerprint System
|
||||||
|
|
||||||
|
@ -46,6 +67,7 @@ identified are necessarily the best available for the purpose.
|
||||||
pixelize_map()
|
pixelize_map()
|
||||||
smooth_direction_map()
|
smooth_direction_map()
|
||||||
gen_high_curve_map()
|
gen_high_curve_map()
|
||||||
|
gen_imap()
|
||||||
gen_initial_imap()
|
gen_initial_imap()
|
||||||
primary_dir_test()
|
primary_dir_test()
|
||||||
secondary_fork_test()
|
secondary_fork_test()
|
||||||
|
@ -58,6 +80,7 @@ identified are necessarily the best available for the purpose.
|
||||||
average_8nbr_dir()
|
average_8nbr_dir()
|
||||||
num_valid_8nbrs()
|
num_valid_8nbrs()
|
||||||
smooth_imap()
|
smooth_imap()
|
||||||
|
gen_nmap()
|
||||||
vorticity()
|
vorticity()
|
||||||
accum_nbr_vorticity()
|
accum_nbr_vorticity()
|
||||||
curvature()
|
curvature()
|
||||||
|
@ -65,8 +88,6 @@ identified are necessarily the best available for the purpose.
|
||||||
***********************************************************************/
|
***********************************************************************/
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <lfs.h>
|
#include <lfs.h>
|
||||||
#include <morph.h>
|
#include <morph.h>
|
||||||
#include <log.h>
|
#include <log.h>
|
||||||
|
@ -307,10 +328,6 @@ int gen_initial_maps(int **odmap, int **olcmap, int **olfmap,
|
||||||
xmaxlimit = pw - dftgrids->pad - lfsparms->windowsize - 1;
|
xmaxlimit = pw - dftgrids->pad - lfsparms->windowsize - 1;
|
||||||
ymaxlimit = ph - dftgrids->pad - lfsparms->windowsize - 1;
|
ymaxlimit = ph - dftgrids->pad - lfsparms->windowsize - 1;
|
||||||
|
|
||||||
/* max limits should not be negative */
|
|
||||||
xmaxlimit = MAX(xmaxlimit, 0);
|
|
||||||
ymaxlimit = MAX(ymaxlimit, 0);
|
|
||||||
|
|
||||||
/* Foreach block in image ... */
|
/* Foreach block in image ... */
|
||||||
for(bi = 0; bi < bsize; bi++){
|
for(bi = 0; bi < bsize; bi++){
|
||||||
/* Adjust block offset from pointing to block origin to pointing */
|
/* Adjust block offset from pointing to block origin to pointing */
|
||||||
|
@ -393,9 +410,9 @@ int gen_initial_maps(int **odmap, int **olcmap, int **olfmap,
|
||||||
{ int _w;
|
{ int _w;
|
||||||
fprintf(logfp, " Power\n");
|
fprintf(logfp, " Power\n");
|
||||||
for(_w = 0; _w < nstats; _w++){
|
for(_w = 0; _w < nstats; _w++){
|
||||||
/* Add 1 to wis[w] to create index to original dft_coefs[] */
|
/* Add 1 to wis[w] to create index to original g_dft_coefs[] */
|
||||||
fprintf(logfp, " wis[%d] %d %12.3f %2d %9.3f %12.3f\n",
|
fprintf(logfp, " wis[%d] %d %12.3f %2d %9.3f %12.3f\n",
|
||||||
_w, wis[_w]+1,
|
_w, wis[_w]+1,
|
||||||
powmaxs[wis[_w]], powmax_dirs[wis[_w]], pownorms[wis[_w]],
|
powmaxs[wis[_w]], powmax_dirs[wis[_w]], pownorms[wis[_w]],
|
||||||
powers[0][powmax_dirs[wis[_w]]]);
|
powers[0][powmax_dirs[wis[_w]]]);
|
||||||
}
|
}
|
||||||
|
@ -647,7 +664,7 @@ int morph_TF_map(int *tfmap, const int mw, const int mh,
|
||||||
unsigned char *cimage, *mimage, *cptr;
|
unsigned char *cimage, *mimage, *cptr;
|
||||||
int *mptr;
|
int *mptr;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
|
||||||
/* Convert TRUE/FALSE map into a binary byte image. */
|
/* Convert TRUE/FALSE map into a binary byte image. */
|
||||||
cimage = (unsigned char *)malloc(mw*mh);
|
cimage = (unsigned char *)malloc(mw*mh);
|
||||||
|
@ -925,13 +942,37 @@ int gen_high_curve_map(int **ohcmap, int *direction_map,
|
||||||
} /* bx */
|
} /* bx */
|
||||||
} /* by */
|
} /* by */
|
||||||
|
|
||||||
/* Assign High Curvature Map to output pointer. */
|
/* Assign High Curvature Map to output pointer. */
|
||||||
*ohcmap = high_curve_map;
|
*ohcmap = high_curve_map;
|
||||||
|
|
||||||
/* Return normally. */
|
/* Return normally. */
|
||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
#cat: gen_imap - Computes an IMAP, which is a 2D vector of integer directions,
|
||||||
|
#cat: where each direction represents the dominant ridge flow in
|
||||||
|
#cat: a block of the input grayscale image. This routine will
|
||||||
|
#cat: generate an IMAP for arbitrarily sized, non-square, images.
|
||||||
|
|
||||||
|
Input:
|
||||||
|
pdata - padded input image data (8 bits [0..256) grayscale)
|
||||||
|
pw - padded width (in pixels) of the input image
|
||||||
|
ph - padded height (in pixels) of the input image
|
||||||
|
dir2rad - lookup table for converting integer directions
|
||||||
|
dftwaves - structure containing the DFT wave forms
|
||||||
|
dftgrids - structure containing the rotated pixel grid offsets
|
||||||
|
lfsparms - parameters and thresholds for controlling LFS
|
||||||
|
Output:
|
||||||
|
optr - points to the created IMAP
|
||||||
|
ow - width (in blocks) of the IMAP
|
||||||
|
oh - height (in blocks) of the IMAP
|
||||||
|
Return Code:
|
||||||
|
Zero - successful completion
|
||||||
|
Negative - system error
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
**************************************************************************
|
**************************************************************************
|
||||||
#cat: gen_initial_imap - Creates an initial IMAP from the given input image.
|
#cat: gen_initial_imap - Creates an initial IMAP from the given input image.
|
||||||
|
@ -959,126 +1000,6 @@ int gen_high_curve_map(int **ohcmap, int *direction_map,
|
||||||
Zero - successful completion
|
Zero - successful completion
|
||||||
Negative - system error
|
Negative - system error
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
int gen_initial_imap(int **optr, int *blkoffs, const int mw, const int mh,
|
|
||||||
unsigned char *pdata, const int pw, const int ph,
|
|
||||||
const DFTWAVES *dftwaves, const ROTGRIDS *dftgrids,
|
|
||||||
const LFSPARMS *lfsparms)
|
|
||||||
{
|
|
||||||
int *imap;
|
|
||||||
int bi, bsize, blkdir;
|
|
||||||
int *wis, *powmax_dirs;
|
|
||||||
double **powers, *powmaxs, *pownorms;
|
|
||||||
int nstats;
|
|
||||||
int ret; /* return code */
|
|
||||||
|
|
||||||
print2log("INITIAL MAP\n");
|
|
||||||
|
|
||||||
/* Compute total number of blocks in IMAP */
|
|
||||||
bsize = mw * mh;
|
|
||||||
|
|
||||||
/* Allocate IMAP memory */
|
|
||||||
imap = (int *)malloc(bsize * sizeof(int));
|
|
||||||
if(imap == (int *)NULL){
|
|
||||||
fprintf(stderr, "ERROR : gen_initial_imap : malloc : imap\n");
|
|
||||||
return(-70);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Allocate DFT directional power vectors */
|
|
||||||
if((ret = alloc_dir_powers(&powers, dftwaves->nwaves, dftgrids->ngrids))){
|
|
||||||
/* Free memory allocated to this point. */
|
|
||||||
free(imap);
|
|
||||||
return(ret);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Allocate DFT power statistic arrays */
|
|
||||||
/* Compute length of statistics arrays. Statistics not needed */
|
|
||||||
/* for the first DFT wave, so the length is number of waves - 1. */
|
|
||||||
nstats = dftwaves->nwaves - 1;
|
|
||||||
if((ret = alloc_power_stats(&wis, &powmaxs, &powmax_dirs,
|
|
||||||
&pownorms, nstats))){
|
|
||||||
/* Free memory allocated to this point. */
|
|
||||||
free(imap);
|
|
||||||
free_dir_powers(powers, dftwaves->nwaves);
|
|
||||||
return(ret);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Initialize the imap to -1 */
|
|
||||||
memset(imap, INVALID_DIR, bsize * sizeof(int));
|
|
||||||
|
|
||||||
/* Foreach block in imap ... */
|
|
||||||
for(bi = 0; bi < bsize; bi++){
|
|
||||||
|
|
||||||
print2log(" BLOCK %2d (%2d, %2d)\n", bi, bi%mw, bi/mw);
|
|
||||||
|
|
||||||
/* Compute DFT powers */
|
|
||||||
if((ret = dft_dir_powers(powers, pdata, blkoffs[bi], pw, ph,
|
|
||||||
dftwaves, dftgrids))){
|
|
||||||
/* Free memory allocated to this point. */
|
|
||||||
free(imap);
|
|
||||||
free_dir_powers(powers, dftwaves->nwaves);
|
|
||||||
free(wis);
|
|
||||||
free(powmaxs);
|
|
||||||
free(powmax_dirs);
|
|
||||||
free(pownorms);
|
|
||||||
return(ret);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Compute DFT power statistics, skipping first applied DFT */
|
|
||||||
/* wave. This is dependent on how the primary and secondary */
|
|
||||||
/* direction tests work below. */
|
|
||||||
if((ret = dft_power_stats(wis, powmaxs, powmax_dirs, pownorms, powers,
|
|
||||||
1, dftwaves->nwaves, dftgrids->ngrids))){
|
|
||||||
/* Free memory allocated to this point. */
|
|
||||||
free(imap);
|
|
||||||
free_dir_powers(powers, dftwaves->nwaves);
|
|
||||||
free(wis);
|
|
||||||
free(powmaxs);
|
|
||||||
free(powmax_dirs);
|
|
||||||
free(pownorms);
|
|
||||||
return(ret);
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef LOG_REPORT /*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/
|
|
||||||
{ int _w;
|
|
||||||
fprintf(logfp, " Power\n");
|
|
||||||
for(_w = 0; _w < nstats; _w++){
|
|
||||||
/* Add 1 to wis[w] to create index to original dft_coefs[] */
|
|
||||||
fprintf(logfp, " wis[%d] %d %12.3f %2d %9.3f %12.3f\n",
|
|
||||||
_w, wis[_w]+1,
|
|
||||||
powmaxs[wis[_w]], powmax_dirs[wis[_w]], pownorms[wis[_w]],
|
|
||||||
powers[0][powmax_dirs[wis[_w]]]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
|
|
||||||
|
|
||||||
/* Conduct primary direction test */
|
|
||||||
blkdir = primary_dir_test(powers, wis, powmaxs, powmax_dirs,
|
|
||||||
pownorms, nstats, lfsparms);
|
|
||||||
|
|
||||||
if(blkdir != INVALID_DIR)
|
|
||||||
imap[bi] = blkdir;
|
|
||||||
else{
|
|
||||||
/* Conduct secondary (fork) direction test */
|
|
||||||
blkdir = secondary_fork_test(powers, wis, powmaxs, powmax_dirs,
|
|
||||||
pownorms, nstats, lfsparms);
|
|
||||||
if(blkdir != INVALID_DIR)
|
|
||||||
imap[bi] = blkdir;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Otherwise current block direction in IMAP remains INVALID */
|
|
||||||
|
|
||||||
} /* bi */
|
|
||||||
|
|
||||||
/* Deallocate working memory */
|
|
||||||
free_dir_powers(powers, dftwaves->nwaves);
|
|
||||||
free(wis);
|
|
||||||
free(powmaxs);
|
|
||||||
free(powmax_dirs);
|
|
||||||
free(pownorms);
|
|
||||||
|
|
||||||
*optr = imap;
|
|
||||||
return(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
**************************************************************************
|
**************************************************************************
|
||||||
|
@ -1093,7 +1014,7 @@ int gen_initial_imap(int **optr, int *blkoffs, const int mw, const int mh,
|
||||||
powmaxs - maximum power for each of the highest N-1 frequencies
|
powmaxs - maximum power for each of the highest N-1 frequencies
|
||||||
powmax_dirs - directions associated with each of the N-1 maximum powers
|
powmax_dirs - directions associated with each of the N-1 maximum powers
|
||||||
pownorms - normalized power for each of the highest N-1 frequencies
|
pownorms - normalized power for each of the highest N-1 frequencies
|
||||||
nstats - N-1 wave frequencies (where N is the length of dft_coefs)
|
nstats - N-1 wave frequencies (where N is the length of g_dft_coefs)
|
||||||
lfsparms - parameters and thresholds for controlling LFS
|
lfsparms - parameters and thresholds for controlling LFS
|
||||||
Return Code:
|
Return Code:
|
||||||
Zero or Positive - The selected IMAP integer direction
|
Zero or Positive - The selected IMAP integer direction
|
||||||
|
@ -1120,7 +1041,7 @@ int primary_dir_test(double **powers, const int *wis,
|
||||||
(powers[0][powmax_dirs[wis[w]]] <= lfsparms->powmax_max)){
|
(powers[0][powmax_dirs[wis[w]]] <= lfsparms->powmax_max)){
|
||||||
|
|
||||||
#ifdef LOG_REPORT /*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/
|
#ifdef LOG_REPORT /*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/
|
||||||
/* Add 1 to wis[w] to create index to original dft_coefs[] */
|
/* Add 1 to wis[w] to create index to original g_dft_coefs[] */
|
||||||
fprintf(logfp,
|
fprintf(logfp,
|
||||||
" Selected Wave = %d\n", wis[w]+1);
|
" Selected Wave = %d\n", wis[w]+1);
|
||||||
fprintf(logfp,
|
fprintf(logfp,
|
||||||
|
@ -1177,7 +1098,7 @@ int primary_dir_test(double **powers, const int *wis,
|
||||||
powmaxs - maximum power for each of the highest N-1 frequencies
|
powmaxs - maximum power for each of the highest N-1 frequencies
|
||||||
powmax_dirs - directions associated with each of the N-1 maximum powers
|
powmax_dirs - directions associated with each of the N-1 maximum powers
|
||||||
pownorms - normalized power for each of the highest N-1 frequencies
|
pownorms - normalized power for each of the highest N-1 frequencies
|
||||||
nstats - N-1 wave frequencies (where N is the length of dft_coefs)
|
nstats - N-1 wave frequencies (where N is the length of g_dft_coefs)
|
||||||
lfsparms - parameters and thresholds for controlling LFS
|
lfsparms - parameters and thresholds for controlling LFS
|
||||||
Return Code:
|
Return Code:
|
||||||
Zero or Positive - The selected IMAP integer direction
|
Zero or Positive - The selected IMAP integer direction
|
||||||
|
@ -2022,76 +1943,29 @@ int num_valid_8nbrs(int *imap, const int mx, const int my,
|
||||||
Output:
|
Output:
|
||||||
imap - vector of smoothed input values
|
imap - vector of smoothed input values
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
void smooth_imap(int *imap, const int mw, const int mh,
|
|
||||||
const DIR2RAD *dir2rad, const LFSPARMS *lfsparms)
|
|
||||||
{
|
|
||||||
int mx, my;
|
|
||||||
int *iptr;
|
|
||||||
int avrdir, nvalid;
|
|
||||||
double dir_strength;
|
|
||||||
|
|
||||||
print2log("SMOOTH MAP\n");
|
/*************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
#cat: gen_nmap - Computes an NMAP from its associated 2D vector of integer
|
||||||
|
#cat: directions (IMAP). Each value in the NMAP either represents
|
||||||
|
#cat: a direction of dominant ridge flow in a block of the input
|
||||||
|
#cat: grayscale image, or it contains a codes describing why such
|
||||||
|
#cat: a direction was not procuded.
|
||||||
|
#cat: For example, blocks near areas of high-curvature (such as
|
||||||
|
#cat: with cores and deltas) will not produce reliable IMAP
|
||||||
|
#cat: directions.
|
||||||
|
|
||||||
iptr = imap;
|
Input:
|
||||||
for(my = 0; my < mh; my++){
|
imap - associated input vector of IMAP directions
|
||||||
for(mx = 0; mx < mw; mx++){
|
mw - the width (in blocks) of the IMAP
|
||||||
/* Compute average direction from neighbors, returning the */
|
mh - the height (in blocks) of the IMAP
|
||||||
/* number of valid neighbors used in the computation, and */
|
lfsparms - parameters and thresholds for controlling LFS
|
||||||
/* the "strength" of the average direction. */
|
Output:
|
||||||
average_8nbr_dir(&avrdir, &dir_strength, &nvalid,
|
optr - points to the created NMAP
|
||||||
imap, mx, my, mw, mh, dir2rad);
|
Return Code:
|
||||||
|
Zero - successful completion
|
||||||
/* If average direction strength is strong enough */
|
Negative - system error
|
||||||
/* (Ex. thresh==0.2)... */
|
**************************************************************************/
|
||||||
if(dir_strength >= lfsparms->dir_strength_min){
|
|
||||||
/* If IMAP direction is valid ... */
|
|
||||||
if(*iptr != INVALID_DIR){
|
|
||||||
/* Conduct valid neighbor test (Ex. thresh==3)... */
|
|
||||||
if(nvalid >= lfsparms->rmv_valid_nbr_min){
|
|
||||||
|
|
||||||
#ifdef LOG_REPORT /*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/
|
|
||||||
fprintf(logfp, " BLOCK %2d (%2d, %2d)\n",
|
|
||||||
mx+(my*mw), mx, my);
|
|
||||||
fprintf(logfp, " Average NBR : %2d %6.3f %d\n",
|
|
||||||
avrdir, dir_strength, nvalid);
|
|
||||||
fprintf(logfp, " 1. Valid NBR (%d >= %d)\n",
|
|
||||||
nvalid, lfsparms->rmv_valid_nbr_min);
|
|
||||||
fprintf(logfp, " Valid Direction = %d\n", *iptr);
|
|
||||||
fprintf(logfp, " Smoothed Direction = %d\n", avrdir);
|
|
||||||
#endif /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
|
|
||||||
|
|
||||||
/* Reassign valid IMAP direction with average direction. */
|
|
||||||
*iptr = avrdir;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/* Otherwise IMAP direction is invalid ... */
|
|
||||||
else{
|
|
||||||
/* Even if IMAP value is invalid, if number of valid */
|
|
||||||
/* neighbors is big enough (Ex. thresh==7)... */
|
|
||||||
if(nvalid >= lfsparms->smth_valid_nbr_min){
|
|
||||||
|
|
||||||
#ifdef LOG_REPORT /*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/
|
|
||||||
fprintf(logfp, " BLOCK %2d (%2d, %2d)\n",
|
|
||||||
mx+(my*mw), mx, my);
|
|
||||||
fprintf(logfp, " Average NBR : %2d %6.3f %d\n",
|
|
||||||
avrdir, dir_strength, nvalid);
|
|
||||||
fprintf(logfp, " 2. Invalid NBR (%d >= %d)\n",
|
|
||||||
nvalid, lfsparms->smth_valid_nbr_min);
|
|
||||||
fprintf(logfp, " Invalid Direction = %d\n", *iptr);
|
|
||||||
fprintf(logfp, " Smoothed Direction = %d\n", avrdir);
|
|
||||||
#endif /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
|
|
||||||
|
|
||||||
/* Assign invalid IMAP direction with average direction. */
|
|
||||||
*iptr = avrdir;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Bump to next IMAP direction. */
|
|
||||||
iptr++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
**************************************************************************
|
**************************************************************************
|
||||||
|
|
|
@ -1,26 +1,47 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
|
|
||||||
License:
|
License:
|
||||||
This software was developed at the National Institute of Standards and
|
This software and/or related materials was developed at the National Institute
|
||||||
Technology (NIST) by employees of the Federal Government in the course
|
of Standards and Technology (NIST) by employees of the Federal Government
|
||||||
of their official duties. Pursuant to title 17 Section 105 of the
|
in the course of their official duties. Pursuant to title 17 Section 105
|
||||||
United States Code, this software is not subject to copyright protection
|
of the United States Code, this software is not subject to copyright
|
||||||
and is in the public domain. NIST assumes no responsibility whatsoever for
|
protection and is in the public domain.
|
||||||
its use by other parties, and makes no guarantees, expressed or implied,
|
|
||||||
about its quality, reliability, or any other characteristic.
|
|
||||||
|
|
||||||
Disclaimer:
|
This software and/or related materials have been determined to be not subject
|
||||||
This software was developed to promote biometric standards and biometric
|
to the EAR (see Part 734.3 of the EAR for exact details) because it is
|
||||||
technology testing for the Federal Government in accordance with the USA
|
a publicly available technology and software, and is freely distributed
|
||||||
PATRIOT Act and the Enhanced Border Security and Visa Entry Reform Act.
|
to any interested party with no licensing requirements. Therefore, it is
|
||||||
Specific hardware and software products identified in this software were used
|
permissible to distribute this software as a free download from the internet.
|
||||||
in order to perform the software development. In no case does such
|
|
||||||
identification imply recommendation or endorsement by the National Institute
|
Disclaimer:
|
||||||
of Standards and Technology, nor does it imply that the products and equipment
|
This software and/or related materials was developed to promote biometric
|
||||||
identified are necessarily the best available for the purpose.
|
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.
|
||||||
|
|
||||||
|
This software and/or related materials are provided "AS-IS" without warranty
|
||||||
|
of any kind including NO WARRANTY OF PERFORMANCE, MERCHANTABILITY,
|
||||||
|
NO WARRANTY OF NON-INFRINGEMENT OF ANY 3RD PARTY INTELLECTUAL PROPERTY
|
||||||
|
or FITNESS FOR A PARTICULAR PURPOSE or for any purpose whatsoever, for the
|
||||||
|
licensed product, however used. In no event shall NIST be liable for any
|
||||||
|
damages and/or costs, including but not limited to incidental or consequential
|
||||||
|
damages of any kind, including economic damage or injury to property and lost
|
||||||
|
profits, regardless of whether NIST shall be advised, have reason to know,
|
||||||
|
or in fact shall know of the possibility.
|
||||||
|
|
||||||
|
By using this software, you agree to bear all risk relating to quality,
|
||||||
|
use and performance of the software and/or related materials. You agree
|
||||||
|
to hold the Government harmless from any claim arising from your use
|
||||||
|
of the software.
|
||||||
|
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
LIBRARY: LFS - NIST Latent Fingerprint System
|
LIBRARY: LFS - NIST Latent Fingerprint System
|
||||||
|
|
||||||
|
@ -46,14 +67,14 @@ identified are necessarily the best available for the purpose.
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
**************************************************************************
|
**************************************************************************
|
||||||
#cat: match_1st_pair - Determines which of the feature_patterns[] have their
|
#cat: match_1st_pair - Determines which of the g_feature_patterns[] have their
|
||||||
#cat: first pixel pair match the specified pixel pair.
|
#cat: first pixel pair match the specified pixel pair.
|
||||||
|
|
||||||
Input:
|
Input:
|
||||||
p1 - first pixel value of pair
|
p1 - first pixel value of pair
|
||||||
p2 - second pixel value of pair
|
p2 - second pixel value of pair
|
||||||
Output:
|
Output:
|
||||||
possible - list of matching feature_patterns[] indices
|
possible - list of matching g_feature_patterns[] indices
|
||||||
nposs - number of matches
|
nposs - number of matches
|
||||||
Return Code:
|
Return Code:
|
||||||
nposs - number of matches
|
nposs - number of matches
|
||||||
|
@ -84,16 +105,16 @@ int match_1st_pair(unsigned char p1, unsigned char p2,
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
**************************************************************************
|
**************************************************************************
|
||||||
#cat: match_2nd_pair - Determines which of the passed feature_patterns[] have
|
#cat: match_2nd_pair - Determines which of the passed g_feature_patterns[] have
|
||||||
#cat: their second pixel pair match the specified pixel pair.
|
#cat: their second pixel pair match the specified pixel pair.
|
||||||
|
|
||||||
Input:
|
Input:
|
||||||
p1 - first pixel value of pair
|
p1 - first pixel value of pair
|
||||||
p2 - second pixel value of pair
|
p2 - second pixel value of pair
|
||||||
possible - list of potentially-matching feature_patterns[] indices
|
possible - list of potentially-matching g_feature_patterns[] indices
|
||||||
nposs - number of potential matches
|
nposs - number of potential matches
|
||||||
Output:
|
Output:
|
||||||
possible - list of matching feature_patterns[] indices
|
possible - list of matching g_feature_patterns[] indices
|
||||||
nposs - number of matches
|
nposs - number of matches
|
||||||
Return Code:
|
Return Code:
|
||||||
nposs - number of matches
|
nposs - number of matches
|
||||||
|
@ -132,16 +153,16 @@ int match_2nd_pair(unsigned char p1, unsigned char p2,
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
**************************************************************************
|
**************************************************************************
|
||||||
#cat: match_3rd_pair - Determines which of the passed feature_patterns[] have
|
#cat: match_3rd_pair - Determines which of the passed g_feature_patterns[] have
|
||||||
#cat: their third pixel pair match the specified pixel pair.
|
#cat: their third pixel pair match the specified pixel pair.
|
||||||
|
|
||||||
Input:
|
Input:
|
||||||
p1 - first pixel value of pair
|
p1 - first pixel value of pair
|
||||||
p2 - second pixel value of pair
|
p2 - second pixel value of pair
|
||||||
possible - list of potentially-matching feature_patterns[] indices
|
possible - list of potentially-matching g_feature_patterns[] indices
|
||||||
nposs - number of potential matches
|
nposs - number of potential matches
|
||||||
Output:
|
Output:
|
||||||
possible - list of matching feature_patterns[] indices
|
possible - list of matching g_feature_patterns[] indices
|
||||||
nposs - number of matches
|
nposs - number of matches
|
||||||
Return Code:
|
Return Code:
|
||||||
nposs - number of matches
|
nposs - number of matches
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,26 +1,47 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
|
|
||||||
License:
|
License:
|
||||||
This software was developed at the National Institute of Standards and
|
This software and/or related materials was developed at the National Institute
|
||||||
Technology (NIST) by employees of the Federal Government in the course
|
of Standards and Technology (NIST) by employees of the Federal Government
|
||||||
of their official duties. Pursuant to title 17 Section 105 of the
|
in the course of their official duties. Pursuant to title 17 Section 105
|
||||||
United States Code, this software is not subject to copyright protection
|
of the United States Code, this software is not subject to copyright
|
||||||
and is in the public domain. NIST assumes no responsibility whatsoever for
|
protection and is in the public domain.
|
||||||
its use by other parties, and makes no guarantees, expressed or implied,
|
|
||||||
about its quality, reliability, or any other characteristic.
|
|
||||||
|
|
||||||
Disclaimer:
|
This software and/or related materials have been determined to be not subject
|
||||||
This software was developed to promote biometric standards and biometric
|
to the EAR (see Part 734.3 of the EAR for exact details) because it is
|
||||||
technology testing for the Federal Government in accordance with the USA
|
a publicly available technology and software, and is freely distributed
|
||||||
PATRIOT Act and the Enhanced Border Security and Visa Entry Reform Act.
|
to any interested party with no licensing requirements. Therefore, it is
|
||||||
Specific hardware and software products identified in this software were used
|
permissible to distribute this software as a free download from the internet.
|
||||||
in order to perform the software development. In no case does such
|
|
||||||
identification imply recommendation or endorsement by the National Institute
|
Disclaimer:
|
||||||
of Standards and Technology, nor does it imply that the products and equipment
|
This software and/or related materials was developed to promote biometric
|
||||||
identified are necessarily the best available for the purpose.
|
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.
|
||||||
|
|
||||||
|
This software and/or related materials are provided "AS-IS" without warranty
|
||||||
|
of any kind including NO WARRANTY OF PERFORMANCE, MERCHANTABILITY,
|
||||||
|
NO WARRANTY OF NON-INFRINGEMENT OF ANY 3RD PARTY INTELLECTUAL PROPERTY
|
||||||
|
or FITNESS FOR A PARTICULAR PURPOSE or for any purpose whatsoever, for the
|
||||||
|
licensed product, however used. In no event shall NIST be liable for any
|
||||||
|
damages and/or costs, including but not limited to incidental or consequential
|
||||||
|
damages of any kind, including economic damage or injury to property and lost
|
||||||
|
profits, regardless of whether NIST shall be advised, have reason to know,
|
||||||
|
or in fact shall know of the possibility.
|
||||||
|
|
||||||
|
By using this software, you agree to bear all risk relating to quality,
|
||||||
|
use and performance of the software and/or related materials. You agree
|
||||||
|
to hold the Government harmless from any claim arising from your use
|
||||||
|
of the software.
|
||||||
|
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
LIBRARY: LFS - NIST Latent Fingerprint System
|
LIBRARY: LFS - NIST Latent Fingerprint System
|
||||||
|
|
||||||
|
@ -69,13 +90,13 @@ void erode_charimage_2(unsigned char *inp, unsigned char *out,
|
||||||
{
|
{
|
||||||
int row, col;
|
int row, col;
|
||||||
unsigned char *itr = inp, *otr = out;
|
unsigned char *itr = inp, *otr = out;
|
||||||
|
|
||||||
memcpy(out, inp, iw*ih);
|
memcpy(out, inp, iw*ih);
|
||||||
|
|
||||||
/* for true pixels. kill pixel if there is at least one false neighbor */
|
/* for true pixels. kill pixel if there is at least one false neighbor */
|
||||||
for ( row = 0 ; row < ih ; row++ )
|
for ( row = 0 ; row < ih ; row++ )
|
||||||
for ( col = 0 ; col < iw ; col++ )
|
for ( col = 0 ; col < iw ; col++ )
|
||||||
{
|
{
|
||||||
if (*itr) /* erode only operates on true pixels */
|
if (*itr) /* erode only operates on true pixels */
|
||||||
{
|
{
|
||||||
/* more efficient with C's left to right evaluation of */
|
/* more efficient with C's left to right evaluation of */
|
||||||
|
@ -87,7 +108,7 @@ void erode_charimage_2(unsigned char *inp, unsigned char *out,
|
||||||
*otr = 0;
|
*otr = 0;
|
||||||
}
|
}
|
||||||
itr++ ; otr++;
|
itr++ ; otr++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
|
@ -109,13 +130,13 @@ void dilate_charimage_2(unsigned char *inp, unsigned char *out,
|
||||||
{
|
{
|
||||||
int row, col;
|
int row, col;
|
||||||
unsigned char *itr = inp, *otr = out;
|
unsigned char *itr = inp, *otr = out;
|
||||||
|
|
||||||
memcpy(out, inp, iw*ih);
|
memcpy(out, inp, iw*ih);
|
||||||
|
|
||||||
/* for all pixels. set pixel if there is at least one true neighbor */
|
/* for all pixels. set pixel if there is at least one true neighbor */
|
||||||
for ( row = 0 ; row < ih ; row++ )
|
for ( row = 0 ; row < ih ; row++ )
|
||||||
for ( col = 0 ; col < iw ; col++ )
|
for ( col = 0 ; col < iw ; col++ )
|
||||||
{
|
{
|
||||||
if (!*itr) /* pixel is already true, neighbors irrelevant */
|
if (!*itr) /* pixel is already true, neighbors irrelevant */
|
||||||
{
|
{
|
||||||
/* more efficient with C's left to right evaluation of */
|
/* more efficient with C's left to right evaluation of */
|
||||||
|
@ -127,7 +148,7 @@ void dilate_charimage_2(unsigned char *inp, unsigned char *out,
|
||||||
*otr = 1;
|
*otr = 1;
|
||||||
}
|
}
|
||||||
itr++ ; otr++;
|
itr++ ; otr++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
|
@ -151,7 +172,7 @@ char get_south8_2(char *ptr, const int row, const int iw, const int ih,
|
||||||
{
|
{
|
||||||
if (row >= ih-1) /* catch case where image is undefined southwards */
|
if (row >= ih-1) /* catch case where image is undefined southwards */
|
||||||
return failcode; /* use plane geometry and return code. */
|
return failcode; /* use plane geometry and return code. */
|
||||||
else
|
|
||||||
return *(ptr+iw);
|
return *(ptr+iw);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -175,7 +196,7 @@ char get_north8_2(char *ptr, const int row, const int iw,
|
||||||
{
|
{
|
||||||
if (row < 1) /* catch case where image is undefined northwards */
|
if (row < 1) /* catch case where image is undefined northwards */
|
||||||
return failcode; /* use plane geometry and return code. */
|
return failcode; /* use plane geometry and return code. */
|
||||||
else
|
|
||||||
return *(ptr-iw);
|
return *(ptr-iw);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -199,7 +220,7 @@ char get_east8_2(char *ptr, const int col, const int iw,
|
||||||
{
|
{
|
||||||
if (col >= iw-1) /* catch case where image is undefined eastwards */
|
if (col >= iw-1) /* catch case where image is undefined eastwards */
|
||||||
return failcode; /* use plane geometry and return code. */
|
return failcode; /* use plane geometry and return code. */
|
||||||
else
|
|
||||||
return *(ptr+ 1);
|
return *(ptr+ 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -221,6 +242,6 @@ char get_west8_2(char *ptr, const int col, const int failcode)
|
||||||
{
|
{
|
||||||
if (col < 1) /* catch case where image is undefined westwards */
|
if (col < 1) /* catch case where image is undefined westwards */
|
||||||
return failcode; /* use plane geometry and return code. */
|
return failcode; /* use plane geometry and return code. */
|
||||||
else
|
|
||||||
return *(ptr- 1);
|
return *(ptr- 1);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,26 +1,47 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
|
|
||||||
License:
|
License:
|
||||||
This software was developed at the National Institute of Standards and
|
This software and/or related materials was developed at the National Institute
|
||||||
Technology (NIST) by employees of the Federal Government in the course
|
of Standards and Technology (NIST) by employees of the Federal Government
|
||||||
of their official duties. Pursuant to title 17 Section 105 of the
|
in the course of their official duties. Pursuant to title 17 Section 105
|
||||||
United States Code, this software is not subject to copyright protection
|
of the United States Code, this software is not subject to copyright
|
||||||
and is in the public domain. NIST assumes no responsibility whatsoever for
|
protection and is in the public domain.
|
||||||
its use by other parties, and makes no guarantees, expressed or implied,
|
|
||||||
about its quality, reliability, or any other characteristic.
|
|
||||||
|
|
||||||
Disclaimer:
|
This software and/or related materials have been determined to be not subject
|
||||||
This software was developed to promote biometric standards and biometric
|
to the EAR (see Part 734.3 of the EAR for exact details) because it is
|
||||||
technology testing for the Federal Government in accordance with the USA
|
a publicly available technology and software, and is freely distributed
|
||||||
PATRIOT Act and the Enhanced Border Security and Visa Entry Reform Act.
|
to any interested party with no licensing requirements. Therefore, it is
|
||||||
Specific hardware and software products identified in this software were used
|
permissible to distribute this software as a free download from the internet.
|
||||||
in order to perform the software development. In no case does such
|
|
||||||
identification imply recommendation or endorsement by the National Institute
|
Disclaimer:
|
||||||
of Standards and Technology, nor does it imply that the products and equipment
|
This software and/or related materials was developed to promote biometric
|
||||||
identified are necessarily the best available for the purpose.
|
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.
|
||||||
|
|
||||||
|
This software and/or related materials are provided "AS-IS" without warranty
|
||||||
|
of any kind including NO WARRANTY OF PERFORMANCE, MERCHANTABILITY,
|
||||||
|
NO WARRANTY OF NON-INFRINGEMENT OF ANY 3RD PARTY INTELLECTUAL PROPERTY
|
||||||
|
or FITNESS FOR A PARTICULAR PURPOSE or for any purpose whatsoever, for the
|
||||||
|
licensed product, however used. In no event shall NIST be liable for any
|
||||||
|
damages and/or costs, including but not limited to incidental or consequential
|
||||||
|
damages of any kind, including economic damage or injury to property and lost
|
||||||
|
profits, regardless of whether NIST shall be advised, have reason to know,
|
||||||
|
or in fact shall know of the possibility.
|
||||||
|
|
||||||
|
By using this software, you agree to bear all risk relating to quality,
|
||||||
|
use and performance of the software and/or related materials. You agree
|
||||||
|
to hold the Government harmless from any claim arising from your use
|
||||||
|
of the software.
|
||||||
|
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
LIBRARY: LFS - NIST Latent Fingerprint System
|
LIBRARY: LFS - NIST Latent Fingerprint System
|
||||||
|
|
||||||
|
@ -39,12 +60,11 @@ identified are necessarily the best available for the purpose.
|
||||||
combined_minutia_quality()
|
combined_minutia_quality()
|
||||||
grayscale_reliability()
|
grayscale_reliability()
|
||||||
get_neighborhood_stats()
|
get_neighborhood_stats()
|
||||||
|
reliability_fr_quality_map()
|
||||||
|
|
||||||
***********************************************************************/
|
***********************************************************************/
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include <lfs.h>
|
#include <lfs.h>
|
||||||
|
|
||||||
|
@ -172,120 +192,6 @@ int gen_quality_map(int **oqmap, int *direction_map, int *low_contrast_map,
|
||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/***********************************************************************
|
|
||||||
************************************************************************
|
|
||||||
#cat: get_neighborhood_stats - Given a minutia point, computes the mean
|
|
||||||
#cat: and stdev of the 8-bit grayscale pixels values in a
|
|
||||||
#cat: surrounding neighborhood with specified radius.
|
|
||||||
|
|
||||||
Code originally written by Austin Hicklin for FBI ATU
|
|
||||||
Modified by Michael D. Garris (NIST) Sept. 25, 2000
|
|
||||||
|
|
||||||
Input:
|
|
||||||
minutia - structure containing detected minutia
|
|
||||||
idata - 8-bit grayscale fingerprint image
|
|
||||||
iw - width (in pixels) of the image
|
|
||||||
ih - height (in pixels) of the image
|
|
||||||
radius_pix - pixel radius of surrounding neighborhood
|
|
||||||
Output:
|
|
||||||
mean - mean of neighboring pixels
|
|
||||||
stdev - standard deviation of neighboring pixels
|
|
||||||
************************************************************************/
|
|
||||||
static void get_neighborhood_stats(double *mean, double *stdev, MINUTIA *minutia,
|
|
||||||
unsigned char *idata, const int iw, const int ih,
|
|
||||||
const int radius_pix)
|
|
||||||
{
|
|
||||||
int i, x, y, rows, cols;
|
|
||||||
int n = 0, sumX = 0, sumXX = 0;
|
|
||||||
int histogram[256];
|
|
||||||
|
|
||||||
/* Zero out histogram. */
|
|
||||||
memset(histogram, 0, 256 * sizeof(int));
|
|
||||||
|
|
||||||
/* Set minutia's coordinate variables. */
|
|
||||||
x = minutia->x;
|
|
||||||
y = minutia->y;
|
|
||||||
|
|
||||||
|
|
||||||
/* If minutiae point is within sampleboxsize distance of image border, */
|
|
||||||
/* a value of 0 reliability is returned. */
|
|
||||||
if ((x < radius_pix) || (x > iw-radius_pix-1) ||
|
|
||||||
(y < radius_pix) || (y > ih-radius_pix-1)) {
|
|
||||||
*mean = 0.0;
|
|
||||||
*stdev = 0.0;
|
|
||||||
return;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Foreach row in neighborhood ... */
|
|
||||||
for(rows = y - radius_pix;
|
|
||||||
rows <= y + radius_pix;
|
|
||||||
rows++){
|
|
||||||
/* Foreach column in neighborhood ... */
|
|
||||||
for(cols = x - radius_pix;
|
|
||||||
cols <= x + radius_pix;
|
|
||||||
cols++){
|
|
||||||
/* Bump neighbor's pixel value bin in histogram. */
|
|
||||||
histogram[*(idata+(rows * iw)+cols)]++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Foreach grayscale pixel bin ... */
|
|
||||||
for(i = 0; i < 256; i++){
|
|
||||||
if(histogram[i]){
|
|
||||||
/* Accumulate Sum(X[i]) */
|
|
||||||
sumX += (i * histogram[i]);
|
|
||||||
/* Accumulate Sum(X[i]^2) */
|
|
||||||
sumXX += (i * i * histogram[i]);
|
|
||||||
/* Accumulate N samples */
|
|
||||||
n += histogram[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Mean = Sum(X[i])/N */
|
|
||||||
*mean = sumX/(double)n;
|
|
||||||
/* Stdev = sqrt((Sum(X[i]^2)/N) - Mean^2) */
|
|
||||||
*stdev = sqrt((sumXX/(double)n) - ((*mean)*(*mean)));
|
|
||||||
}
|
|
||||||
|
|
||||||
/***********************************************************************
|
|
||||||
************************************************************************
|
|
||||||
#cat: grayscale_reliability - Given a minutia point, computes a reliability
|
|
||||||
#cat: measure from the stdev and mean of its pixel neighborhood.
|
|
||||||
|
|
||||||
Code originally written by Austin Hicklin for FBI ATU
|
|
||||||
Modified by Michael D. Garris (NIST) Sept. 25, 2000
|
|
||||||
|
|
||||||
GrayScaleReliability - reasonable reliability heuristic, returns
|
|
||||||
0.0 .. 1.0 based on stdev and Mean of a localized histogram where
|
|
||||||
"ideal" stdev is >=64; "ideal" Mean is 127. In a 1 ridge radius
|
|
||||||
(11 pixels), if the bytevalue (shade of gray) in the image has a
|
|
||||||
stdev of >= 64 & a mean of 127, returns 1.0 (well defined
|
|
||||||
light & dark areas in equal proportions).
|
|
||||||
|
|
||||||
Input:
|
|
||||||
minutia - structure containing detected minutia
|
|
||||||
idata - 8-bit grayscale fingerprint image
|
|
||||||
iw - width (in pixels) of the image
|
|
||||||
ih - height (in pixels) of the image
|
|
||||||
radius_pix - pixel radius of surrounding neighborhood
|
|
||||||
Return Value:
|
|
||||||
reliability - computed reliability measure
|
|
||||||
************************************************************************/
|
|
||||||
static double grayscale_reliability(MINUTIA *minutia, unsigned char *idata,
|
|
||||||
const int iw, const int ih, const int radius_pix)
|
|
||||||
{
|
|
||||||
double mean, stdev;
|
|
||||||
double reliability;
|
|
||||||
|
|
||||||
get_neighborhood_stats(&mean, &stdev, minutia, idata, iw, ih, radius_pix);
|
|
||||||
|
|
||||||
reliability = min((stdev>IDEALSTDEV ? 1.0 : stdev/(double)IDEALSTDEV),
|
|
||||||
(1.0-(fabs(mean-IDEALMEAN)/(double)IDEALMEAN)));
|
|
||||||
|
|
||||||
return(reliability);
|
|
||||||
}
|
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
************************************************************************
|
************************************************************************
|
||||||
#cat: combined_minutia_quality - Combines quality measures derived from
|
#cat: combined_minutia_quality - Combines quality measures derived from
|
||||||
|
@ -391,3 +297,137 @@ int combined_minutia_quality(MINUTIAE *minutiae,
|
||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
************************************************************************
|
||||||
|
#cat: grayscale_reliability - Given a minutia point, computes a reliability
|
||||||
|
#cat: measure from the stdev and mean of its pixel neighborhood.
|
||||||
|
|
||||||
|
Code originally written by Austin Hicklin for FBI ATU
|
||||||
|
Modified by Michael D. Garris (NIST) Sept. 25, 2000
|
||||||
|
|
||||||
|
GrayScaleReliability - reasonable reliability heuristic, returns
|
||||||
|
0.0 .. 1.0 based on stdev and Mean of a localized histogram where
|
||||||
|
"ideal" stdev is >=64; "ideal" Mean is 127. In a 1 ridge radius
|
||||||
|
(11 pixels), if the bytevalue (shade of gray) in the image has a
|
||||||
|
stdev of >= 64 & a mean of 127, returns 1.0 (well defined
|
||||||
|
light & dark areas in equal proportions).
|
||||||
|
|
||||||
|
Input:
|
||||||
|
minutia - structure containing detected minutia
|
||||||
|
idata - 8-bit grayscale fingerprint image
|
||||||
|
iw - width (in pixels) of the image
|
||||||
|
ih - height (in pixels) of the image
|
||||||
|
radius_pix - pixel radius of surrounding neighborhood
|
||||||
|
Return Value:
|
||||||
|
reliability - computed reliability measure
|
||||||
|
************************************************************************/
|
||||||
|
double grayscale_reliability(MINUTIA *minutia, unsigned char *idata,
|
||||||
|
const int iw, const int ih, const int radius_pix)
|
||||||
|
{
|
||||||
|
double mean, stdev;
|
||||||
|
double reliability;
|
||||||
|
|
||||||
|
get_neighborhood_stats(&mean, &stdev, minutia, idata, iw, ih, radius_pix);
|
||||||
|
|
||||||
|
reliability = min((stdev>IDEALSTDEV ? 1.0 : stdev/(double)IDEALSTDEV),
|
||||||
|
(1.0-(fabs(mean-IDEALMEAN)/(double)IDEALMEAN)));
|
||||||
|
|
||||||
|
return(reliability);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
************************************************************************
|
||||||
|
#cat: get_neighborhood_stats - Given a minutia point, computes the mean
|
||||||
|
#cat: and stdev of the 8-bit grayscale pixels values in a
|
||||||
|
#cat: surrounding neighborhood with specified radius.
|
||||||
|
|
||||||
|
Code originally written by Austin Hicklin for FBI ATU
|
||||||
|
Modified by Michael D. Garris (NIST) Sept. 25, 2000
|
||||||
|
|
||||||
|
Input:
|
||||||
|
minutia - structure containing detected minutia
|
||||||
|
idata - 8-bit grayscale fingerprint image
|
||||||
|
iw - width (in pixels) of the image
|
||||||
|
ih - height (in pixels) of the image
|
||||||
|
radius_pix - pixel radius of surrounding neighborhood
|
||||||
|
Output:
|
||||||
|
mean - mean of neighboring pixels
|
||||||
|
stdev - standard deviation of neighboring pixels
|
||||||
|
************************************************************************/
|
||||||
|
void get_neighborhood_stats(double *mean, double *stdev, MINUTIA *minutia,
|
||||||
|
unsigned char *idata, const int iw, const int ih,
|
||||||
|
const int radius_pix)
|
||||||
|
{
|
||||||
|
int i, x, y, rows, cols;
|
||||||
|
int n = 0, sumX = 0, sumXX = 0;
|
||||||
|
int histogram[256];
|
||||||
|
|
||||||
|
/* Zero out histogram. */
|
||||||
|
memset(histogram, 0, 256 * sizeof(int));
|
||||||
|
|
||||||
|
/* Set minutia's coordinate variables. */
|
||||||
|
x = minutia->x;
|
||||||
|
y = minutia->y;
|
||||||
|
|
||||||
|
|
||||||
|
/* If minutiae point is within sampleboxsize distance of image border, */
|
||||||
|
/* a value of 0 reliability is returned. */
|
||||||
|
if ((x < radius_pix) || (x > iw-radius_pix-1) ||
|
||||||
|
(y < radius_pix) || (y > ih-radius_pix-1)) {
|
||||||
|
*mean = 0.0;
|
||||||
|
*stdev = 0.0;
|
||||||
|
return;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Foreach row in neighborhood ... */
|
||||||
|
for(rows = y - radius_pix;
|
||||||
|
rows <= y + radius_pix;
|
||||||
|
rows++){
|
||||||
|
/* Foreach column in neighborhood ... */
|
||||||
|
for(cols = x - radius_pix;
|
||||||
|
cols <= x + radius_pix;
|
||||||
|
cols++){
|
||||||
|
/* Bump neighbor's pixel value bin in histogram. */
|
||||||
|
histogram[*(idata+(rows * iw)+cols)]++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Foreach grayscale pixel bin ... */
|
||||||
|
for(i = 0; i < 256; i++){
|
||||||
|
if(histogram[i]){
|
||||||
|
/* Accumulate Sum(X[i]) */
|
||||||
|
sumX += (i * histogram[i]);
|
||||||
|
/* Accumulate Sum(X[i]^2) */
|
||||||
|
sumXX += (i * i * histogram[i]);
|
||||||
|
/* Accumulate N samples */
|
||||||
|
n += histogram[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Mean = Sum(X[i])/N */
|
||||||
|
*mean = sumX/(double)n;
|
||||||
|
/* Stdev = sqrt((Sum(X[i]^2)/N) - Mean^2) */
|
||||||
|
*stdev = sqrt((sumXX/(double)n) - ((*mean)*(*mean)));
|
||||||
|
}
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
************************************************************************
|
||||||
|
#cat: reliability_fr_quality_map - Takes a set of minutiae and assigns
|
||||||
|
#cat: each one a reliability measure based on 1 of 5 possible
|
||||||
|
#cat: quality levels from its location in a quality map.
|
||||||
|
|
||||||
|
Input:
|
||||||
|
minutiae - structure contining the detected minutia
|
||||||
|
quality_map - map with blocks assigned 1 of 5 quality levels
|
||||||
|
map_w - width (in blocks) of the map
|
||||||
|
map_h - height (in blocks) of the map
|
||||||
|
blocksize - size (in pixels) of each block in the map
|
||||||
|
Output:
|
||||||
|
minutiae - updated reliability members
|
||||||
|
Return Code:
|
||||||
|
Zero - successful completion
|
||||||
|
Negative - system error
|
||||||
|
************************************************************************/
|
||||||
|
|
|
@ -1,26 +1,47 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
|
|
||||||
License:
|
License:
|
||||||
This software was developed at the National Institute of Standards and
|
This software and/or related materials was developed at the National Institute
|
||||||
Technology (NIST) by employees of the Federal Government in the course
|
of Standards and Technology (NIST) by employees of the Federal Government
|
||||||
of their official duties. Pursuant to title 17 Section 105 of the
|
in the course of their official duties. Pursuant to title 17 Section 105
|
||||||
United States Code, this software is not subject to copyright protection
|
of the United States Code, this software is not subject to copyright
|
||||||
and is in the public domain. NIST assumes no responsibility whatsoever for
|
protection and is in the public domain.
|
||||||
its use by other parties, and makes no guarantees, expressed or implied,
|
|
||||||
about its quality, reliability, or any other characteristic.
|
|
||||||
|
|
||||||
Disclaimer:
|
This software and/or related materials have been determined to be not subject
|
||||||
This software was developed to promote biometric standards and biometric
|
to the EAR (see Part 734.3 of the EAR for exact details) because it is
|
||||||
technology testing for the Federal Government in accordance with the USA
|
a publicly available technology and software, and is freely distributed
|
||||||
PATRIOT Act and the Enhanced Border Security and Visa Entry Reform Act.
|
to any interested party with no licensing requirements. Therefore, it is
|
||||||
Specific hardware and software products identified in this software were used
|
permissible to distribute this software as a free download from the internet.
|
||||||
in order to perform the software development. In no case does such
|
|
||||||
identification imply recommendation or endorsement by the National Institute
|
Disclaimer:
|
||||||
of Standards and Technology, nor does it imply that the products and equipment
|
This software and/or related materials was developed to promote biometric
|
||||||
identified are necessarily the best available for the purpose.
|
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.
|
||||||
|
|
||||||
|
This software and/or related materials are provided "AS-IS" without warranty
|
||||||
|
of any kind including NO WARRANTY OF PERFORMANCE, MERCHANTABILITY,
|
||||||
|
NO WARRANTY OF NON-INFRINGEMENT OF ANY 3RD PARTY INTELLECTUAL PROPERTY
|
||||||
|
or FITNESS FOR A PARTICULAR PURPOSE or for any purpose whatsoever, for the
|
||||||
|
licensed product, however used. In no event shall NIST be liable for any
|
||||||
|
damages and/or costs, including but not limited to incidental or consequential
|
||||||
|
damages of any kind, including economic damage or injury to property and lost
|
||||||
|
profits, regardless of whether NIST shall be advised, have reason to know,
|
||||||
|
or in fact shall know of the possibility.
|
||||||
|
|
||||||
|
By using this software, you agree to bear all risk relating to quality,
|
||||||
|
use and performance of the software and/or related materials. You agree
|
||||||
|
to hold the Government harmless from any claim arising from your use
|
||||||
|
of the software.
|
||||||
|
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
LIBRARY: LFS - NIST Latent Fingerprint System
|
LIBRARY: LFS - NIST Latent Fingerprint System
|
||||||
|
|
||||||
|
@ -35,15 +56,21 @@ identified are necessarily the best available for the purpose.
|
||||||
|
|
||||||
***********************************************************************
|
***********************************************************************
|
||||||
ROUTINES:
|
ROUTINES:
|
||||||
|
remove_false_minutia()
|
||||||
remove_false_minutia_V2()
|
remove_false_minutia_V2()
|
||||||
remove_holes()
|
remove_holes()
|
||||||
remove_hooks()
|
remove_hooks()
|
||||||
|
remove_hooks_islands_overlaps()
|
||||||
remove_islands_and_lakes()
|
remove_islands_and_lakes()
|
||||||
remove_malformations()
|
remove_malformations()
|
||||||
remove_near_invblock_V2()
|
remove_near_invblocks()
|
||||||
|
remove_near_invblocks_V2()
|
||||||
|
remove_pointing_invblock()
|
||||||
remove_pointing_invblock_V2()
|
remove_pointing_invblock_V2()
|
||||||
remove_overlaps()
|
remove_overlaps()
|
||||||
|
remove_pores()
|
||||||
remove_pores_V2()
|
remove_pores_V2()
|
||||||
|
remove_or_adjust_side_minutiae()
|
||||||
remove_or_adjust_side_minutiae_V2()
|
remove_or_adjust_side_minutiae_V2()
|
||||||
|
|
||||||
***********************************************************************/
|
***********************************************************************/
|
||||||
|
@ -52,6 +79,125 @@ identified are necessarily the best available for the purpose.
|
||||||
#include <lfs.h>
|
#include <lfs.h>
|
||||||
#include <log.h>
|
#include <log.h>
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
#cat: remove_false_minutia - Takes a list of true and false minutiae and
|
||||||
|
#cat: attempts to detect and remove the false minutiae based
|
||||||
|
#cat: on a series of tests.
|
||||||
|
|
||||||
|
Input:
|
||||||
|
minutiae - list of true and false minutiae
|
||||||
|
bdata - binary image data (0==while & 1==black)
|
||||||
|
iw - width (in pixels) of image
|
||||||
|
ih - height (in pixels) of image
|
||||||
|
nmap - IMAP ridge flow matrix with invalid, high-curvature,
|
||||||
|
and no-valid-neighbor regions identified
|
||||||
|
mw - width in blocks of the NMAP
|
||||||
|
mh - height in blocks of the NMAP
|
||||||
|
lfsparms - parameters and thresholds for controlling LFS
|
||||||
|
Output:
|
||||||
|
minutiae - list of pruned minutiae
|
||||||
|
Return Code:
|
||||||
|
Zero - successful completion
|
||||||
|
Negative - system error
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
#cat: remove_false_minutia_V2 - Takes a list of true and false minutiae and
|
||||||
|
#cat: attempts to detect and remove the false minutiae based
|
||||||
|
#cat: on a series of tests.
|
||||||
|
|
||||||
|
Input:
|
||||||
|
minutiae - list of true and false minutiae
|
||||||
|
bdata - binary image data (0==while & 1==black)
|
||||||
|
iw - width (in pixels) of image
|
||||||
|
ih - height (in pixels) of image
|
||||||
|
direction_map - map of image blocks containing directional ridge flow
|
||||||
|
low_flow_map - map of image blocks flagged as LOW RIDGE FLOW
|
||||||
|
high_curve_map - map of image blocks flagged as HIGH CURVATURE
|
||||||
|
mw - width in blocks of the maps
|
||||||
|
mh - height in blocks of the maps
|
||||||
|
lfsparms - parameters and thresholds for controlling LFS
|
||||||
|
Output:
|
||||||
|
minutiae - list of pruned minutiae
|
||||||
|
Return Code:
|
||||||
|
Zero - successful completion
|
||||||
|
Negative - system error
|
||||||
|
**************************************************************************/
|
||||||
|
int remove_false_minutia_V2(MINUTIAE *minutiae,
|
||||||
|
unsigned char *bdata, const int iw, const int ih,
|
||||||
|
int *direction_map, int *low_flow_map, int *high_curve_map,
|
||||||
|
const int mw, const int mh, const LFSPARMS *lfsparms)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
/* 1. Sort minutiae points top-to-bottom and left-to-right. */
|
||||||
|
if((ret = sort_minutiae_y_x(minutiae, iw, ih))){
|
||||||
|
return(ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 2. Remove minutiae on lakes (filled with white pixels) and */
|
||||||
|
/* islands (filled with black pixels), both defined by a pair of */
|
||||||
|
/* minutia points. */
|
||||||
|
if((ret = remove_islands_and_lakes(minutiae, bdata, iw, ih, lfsparms))){
|
||||||
|
return(ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 3. Remove minutiae on holes in the binary image defined by a */
|
||||||
|
/* single point. */
|
||||||
|
if((ret = remove_holes(minutiae, bdata, iw, ih, lfsparms))){
|
||||||
|
return(ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 4. Remove minutiae that point sufficiently close to a block with */
|
||||||
|
/* INVALID direction. */
|
||||||
|
if((ret = remove_pointing_invblock_V2(minutiae, direction_map, mw, mh,
|
||||||
|
lfsparms))){
|
||||||
|
return(ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 5. Remove minutiae that are sufficiently close to a block with */
|
||||||
|
/* INVALID direction. */
|
||||||
|
if((ret = remove_near_invblock_V2(minutiae, direction_map, mw, mh,
|
||||||
|
lfsparms))){
|
||||||
|
return(ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 6. Remove or adjust minutiae that reside on the side of a ridge */
|
||||||
|
/* or valley. */
|
||||||
|
if((ret = remove_or_adjust_side_minutiae_V2(minutiae, bdata, iw, ih,
|
||||||
|
direction_map, mw, mh, lfsparms))){
|
||||||
|
return(ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 7. Remove minutiae that form a hook on the side of a ridge or valley. */
|
||||||
|
if((ret = remove_hooks(minutiae, bdata, iw, ih, lfsparms))){
|
||||||
|
return(ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 8. Remove minutiae that are on opposite sides of an overlap. */
|
||||||
|
if((ret = remove_overlaps(minutiae, bdata, iw, ih, lfsparms))){
|
||||||
|
return(ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 9. Remove minutiae that are "irregularly" shaped. */
|
||||||
|
if((ret = remove_malformations(minutiae, bdata, iw, ih,
|
||||||
|
low_flow_map, mw, mh, lfsparms))){
|
||||||
|
return(ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 10. Remove minutiae that form long, narrow, loops in the */
|
||||||
|
/* "unreliable" regions in the binary image. */
|
||||||
|
if((ret = remove_pores_V2(minutiae, bdata, iw, ih,
|
||||||
|
direction_map, low_flow_map, high_curve_map,
|
||||||
|
mw, mh, lfsparms))){
|
||||||
|
return(ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
**************************************************************************
|
**************************************************************************
|
||||||
#cat: remove_holes - Removes minutia points on small loops around valleys.
|
#cat: remove_holes - Removes minutia points on small loops around valleys.
|
||||||
|
@ -68,7 +214,7 @@ identified are necessarily the best available for the purpose.
|
||||||
Zero - successful completion
|
Zero - successful completion
|
||||||
Negative - system error
|
Negative - system error
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
static int remove_holes(MINUTIAE *minutiae,
|
int remove_holes(MINUTIAE *minutiae,
|
||||||
unsigned char *bdata, const int iw, const int ih,
|
unsigned char *bdata, const int iw, const int ih,
|
||||||
const LFSPARMS *lfsparms)
|
const LFSPARMS *lfsparms)
|
||||||
{
|
{
|
||||||
|
@ -139,7 +285,7 @@ static int remove_holes(MINUTIAE *minutiae,
|
||||||
Zero - successful completion
|
Zero - successful completion
|
||||||
Negative - system error
|
Negative - system error
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
static int remove_hooks(MINUTIAE *minutiae,
|
int remove_hooks(MINUTIAE *minutiae,
|
||||||
unsigned char *bdata, const int iw, const int ih,
|
unsigned char *bdata, const int iw, const int ih,
|
||||||
const LFSPARMS *lfsparms)
|
const LFSPARMS *lfsparms)
|
||||||
{
|
{
|
||||||
|
@ -341,6 +487,29 @@ static int remove_hooks(MINUTIAE *minutiae,
|
||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
#cat: remove_hooks_islands_lakes_overlaps - Removes minutia points on hooks,
|
||||||
|
#cat: islands, lakes, and overlaps and fills in small small
|
||||||
|
#cat: loops in the binary image and joins minutia features in
|
||||||
|
#cat: the image on opposite sides of an overlap. So, this
|
||||||
|
#cat: routine not only prunes minutia points but it edits the
|
||||||
|
#cat: binary input image as well.
|
||||||
|
|
||||||
|
Input:
|
||||||
|
minutiae - list of true and false minutiae
|
||||||
|
bdata - binary image data (0==while & 1==black)
|
||||||
|
iw - width (in pixels) of image
|
||||||
|
ih - height (in pixels) of image
|
||||||
|
lfsparms - parameters and thresholds for controlling LFS
|
||||||
|
Output:
|
||||||
|
minutiae - list of pruned minutiae
|
||||||
|
bdata - edited binary image with loops filled and overlaps removed
|
||||||
|
Return Code:
|
||||||
|
Zero - successful completion
|
||||||
|
Negative - system error
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
**************************************************************************
|
**************************************************************************
|
||||||
#cat: remove_islands_and_lakes - Takes a list of true and false minutiae and
|
#cat: remove_islands_and_lakes - Takes a list of true and false minutiae and
|
||||||
|
@ -362,7 +531,7 @@ static int remove_hooks(MINUTIAE *minutiae,
|
||||||
Zero - successful completion
|
Zero - successful completion
|
||||||
Negative - system error
|
Negative - system error
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
static int remove_islands_and_lakes(MINUTIAE *minutiae,
|
int remove_islands_and_lakes(MINUTIAE *minutiae,
|
||||||
unsigned char *bdata, const int iw, const int ih,
|
unsigned char *bdata, const int iw, const int ih,
|
||||||
const LFSPARMS *lfsparms)
|
const LFSPARMS *lfsparms)
|
||||||
{
|
{
|
||||||
|
@ -616,7 +785,7 @@ static int remove_islands_and_lakes(MINUTIAE *minutiae,
|
||||||
Zero - successful completion
|
Zero - successful completion
|
||||||
Negative - system error
|
Negative - system error
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
static int remove_malformations(MINUTIAE *minutiae,
|
int remove_malformations(MINUTIAE *minutiae,
|
||||||
unsigned char *bdata, const int iw, const int ih,
|
unsigned char *bdata, const int iw, const int ih,
|
||||||
int *low_flow_map, const int mw, const int mh,
|
int *low_flow_map, const int mw, const int mh,
|
||||||
const LFSPARMS *lfsparms)
|
const LFSPARMS *lfsparms)
|
||||||
|
@ -647,7 +816,7 @@ static int remove_malformations(MINUTIAE *minutiae,
|
||||||
/* Return error code. */
|
/* Return error code. */
|
||||||
return(ret);
|
return(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If trace was not possible OR loop found OR */
|
/* If trace was not possible OR loop found OR */
|
||||||
/* contour is incomplete ... */
|
/* contour is incomplete ... */
|
||||||
if((ret == IGNORE) ||
|
if((ret == IGNORE) ||
|
||||||
|
@ -803,6 +972,26 @@ static int remove_malformations(MINUTIAE *minutiae,
|
||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
#cat: remove_near_invblocks - Removes minutia points from the given list
|
||||||
|
#cat: that are sufficiently close to a block with invalid
|
||||||
|
#cat: ridge flow or to the edge of the image.
|
||||||
|
|
||||||
|
Input:
|
||||||
|
minutiae - list of true and false minutiae
|
||||||
|
nmap - IMAP ridge flow matrix with invalid, high-curvature,
|
||||||
|
and no-valid-neighbor regions identified
|
||||||
|
mw - width in blocks of the NMAP
|
||||||
|
mh - height in blocks of the NMAP
|
||||||
|
lfsparms - parameters and thresholds for controlling LFS
|
||||||
|
Output:
|
||||||
|
minutiae - list of pruned minutiae
|
||||||
|
Return Code:
|
||||||
|
Zero - successful completion
|
||||||
|
Negative - system error
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
**************************************************************************
|
**************************************************************************
|
||||||
#cat: remove_near_invblocks_V2 - Removes minutia points from the given list
|
#cat: remove_near_invblocks_V2 - Removes minutia points from the given list
|
||||||
|
@ -821,7 +1010,7 @@ static int remove_malformations(MINUTIAE *minutiae,
|
||||||
Zero - successful completion
|
Zero - successful completion
|
||||||
Negative - system error
|
Negative - system error
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
static int remove_near_invblock_V2(MINUTIAE *minutiae, int *direction_map,
|
int remove_near_invblock_V2(MINUTIAE *minutiae, int *direction_map,
|
||||||
const int mw, const int mh, const LFSPARMS *lfsparms)
|
const int mw, const int mh, const LFSPARMS *lfsparms)
|
||||||
{
|
{
|
||||||
int i, ret;
|
int i, ret;
|
||||||
|
@ -1032,6 +1221,26 @@ static int remove_near_invblock_V2(MINUTIAE *minutiae, int *direction_map,
|
||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
#cat: remove_pointing_invblock - Removes minutia points that are relatively
|
||||||
|
#cat: close in the direction opposite the minutia to an NMAP
|
||||||
|
#cat: block with invalid ridge flow.
|
||||||
|
|
||||||
|
Input:
|
||||||
|
minutiae - list of true and false minutiae
|
||||||
|
nmap - IMAP ridge flow matrix with invalid, high-curvature,
|
||||||
|
and no-valid-neighbor regions identified
|
||||||
|
mw - width in blocks of the NMAP
|
||||||
|
mh - height in blocks of the NMAP
|
||||||
|
lfsparms - parameters and thresholds for controlling LFS
|
||||||
|
Output:
|
||||||
|
minutiae - list of pruned minutiae
|
||||||
|
Return Code:
|
||||||
|
Zero - successful completion
|
||||||
|
Negative - system error
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
**************************************************************************
|
**************************************************************************
|
||||||
#cat: remove_pointing_invblock_V2 - Removes minutia points that are relatively
|
#cat: remove_pointing_invblock_V2 - Removes minutia points that are relatively
|
||||||
|
@ -1050,7 +1259,7 @@ static int remove_near_invblock_V2(MINUTIAE *minutiae, int *direction_map,
|
||||||
Zero - successful completion
|
Zero - successful completion
|
||||||
Negative - system error
|
Negative - system error
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
static int remove_pointing_invblock_V2(MINUTIAE *minutiae,
|
int remove_pointing_invblock_V2(MINUTIAE *minutiae,
|
||||||
int *direction_map, const int mw, const int mh,
|
int *direction_map, const int mw, const int mh,
|
||||||
const LFSPARMS *lfsparms)
|
const LFSPARMS *lfsparms)
|
||||||
{
|
{
|
||||||
|
@ -1140,7 +1349,7 @@ static int remove_pointing_invblock_V2(MINUTIAE *minutiae,
|
||||||
Zero - successful completion
|
Zero - successful completion
|
||||||
Negative - system error
|
Negative - system error
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
static int remove_overlaps(MINUTIAE *minutiae,
|
int remove_overlaps(MINUTIAE *minutiae,
|
||||||
unsigned char *bdata, const int iw, const int ih,
|
unsigned char *bdata, const int iw, const int ih,
|
||||||
const LFSPARMS *lfsparms)
|
const LFSPARMS *lfsparms)
|
||||||
{
|
{
|
||||||
|
@ -1350,32 +1559,20 @@ static int remove_overlaps(MINUTIAE *minutiae,
|
||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void mark_minutiae_in_range(MINUTIAE *minutiae, int *to_remove, int x, int y,
|
|
||||||
const LFSPARMS *lfsparms)
|
|
||||||
{
|
|
||||||
int i, dist;
|
|
||||||
for (i = 0; i < minutiae->num; i++) {
|
|
||||||
if (to_remove[i])
|
|
||||||
continue;
|
|
||||||
dist = (int)sqrt((x - minutiae->list[i]->x) * (x - minutiae->list[i]->x) +
|
|
||||||
(y - minutiae->list[i]->y) * (y - minutiae->list[i]->y));
|
|
||||||
if (dist < lfsparms->min_pp_distance) {
|
|
||||||
to_remove[i] = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
**************************************************************************
|
**************************************************************************
|
||||||
#cat: remove_perimeter_pts - Takes a list of true and false minutiae and
|
#cat: remove_pores - Attempts to detect and remove minutia points located on
|
||||||
#cat: attempts to detect and remove those false minutiae that
|
#cat: pore-shaped valleys.
|
||||||
#cat: belong to image edge
|
|
||||||
|
|
||||||
Input:
|
Input:
|
||||||
minutiae - list of true and false minutiae
|
minutiae - list of true and false minutiae
|
||||||
bdata - binary image data (0==while & 1==black)
|
bdata - binary image data (0==while & 1==black)
|
||||||
iw - width (in pixels) of image
|
iw - width (in pixels) of image
|
||||||
ih - height (in pixels) of image
|
ih - height (in pixels) of image
|
||||||
|
nmap - IMAP ridge flow matrix with invalid, high-curvature,
|
||||||
|
and no-valid-neighbor regions identified
|
||||||
|
mw - width in blocks of the NMAP
|
||||||
|
mh - height in blocks of the NMAP
|
||||||
lfsparms - parameters and thresholds for controlling LFS
|
lfsparms - parameters and thresholds for controlling LFS
|
||||||
Output:
|
Output:
|
||||||
minutiae - list of pruned minutiae
|
minutiae - list of pruned minutiae
|
||||||
|
@ -1383,125 +1580,6 @@ static void mark_minutiae_in_range(MINUTIAE *minutiae, int *to_remove, int x, in
|
||||||
Zero - successful completion
|
Zero - successful completion
|
||||||
Negative - system error
|
Negative - system error
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
static int remove_perimeter_pts(MINUTIAE *minutiae,
|
|
||||||
unsigned char *bdata, const int iw, const int ih,
|
|
||||||
const LFSPARMS *lfsparms)
|
|
||||||
{
|
|
||||||
int i, j, ret, *to_remove;
|
|
||||||
int *left, *left_up, *left_down;
|
|
||||||
int *right, *right_up, *right_down;
|
|
||||||
int removed = 0;
|
|
||||||
int left_min, right_max;
|
|
||||||
|
|
||||||
if (!lfsparms->remove_perimeter_pts)
|
|
||||||
return(0);
|
|
||||||
|
|
||||||
to_remove = calloc(minutiae->num, sizeof(int));
|
|
||||||
left = calloc(ih, sizeof(int));
|
|
||||||
left_up = calloc(ih, sizeof(int));
|
|
||||||
left_down = calloc(ih, sizeof(int));
|
|
||||||
right = calloc(ih, sizeof(int));
|
|
||||||
right_up = calloc(ih, sizeof(int));
|
|
||||||
right_down = calloc(ih, sizeof(int));
|
|
||||||
|
|
||||||
/* Pass downwards */
|
|
||||||
left_min = iw - 1;
|
|
||||||
right_max = 0;
|
|
||||||
for (i = 0; i < ih; i++) {
|
|
||||||
for (j = 0; j < left_min; j++) {
|
|
||||||
if ((bdata[i * iw + j] != 0)) {
|
|
||||||
left_min = j;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (left_min == (iw - 1))
|
|
||||||
left_down[i] = -1;
|
|
||||||
else
|
|
||||||
left_down[i] = left_min;
|
|
||||||
for (j = iw - 1; j >= right_max; j--) {
|
|
||||||
if ((bdata[i * iw + j] != 0)) {
|
|
||||||
right_max = j;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (right_max == 0)
|
|
||||||
right_down[i] = -1;
|
|
||||||
else
|
|
||||||
right_down[i] = right_max;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Pass upwards */
|
|
||||||
left_min = iw - 1;
|
|
||||||
right_max = 0;
|
|
||||||
for (i = ih - 1; i >= 0; i--) {
|
|
||||||
for (j = 0; j < left_min; j++) {
|
|
||||||
if ((bdata[i * iw + j] != 0)) {
|
|
||||||
left_min = j;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (left_min == (iw - 1))
|
|
||||||
left_up[i] = -1;
|
|
||||||
else
|
|
||||||
left_up[i] = left_min;
|
|
||||||
for (j = iw - 1; j >= right_max; j--) {
|
|
||||||
if ((bdata[i * iw + j] != 0)) {
|
|
||||||
right_max = j;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (right_max == 0)
|
|
||||||
right_up[i] = -1;
|
|
||||||
else
|
|
||||||
right_up[i] = right_max;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Merge */
|
|
||||||
left_min = left_down[ih - 1];
|
|
||||||
right_max = right_down[ih - 1];
|
|
||||||
for (i = 0; i < ih; i++) {
|
|
||||||
if (left_down[i] != left_min)
|
|
||||||
left[i] = left_down[i];
|
|
||||||
else
|
|
||||||
left[i] = left_up[i];
|
|
||||||
|
|
||||||
if (right_down[i] != right_max)
|
|
||||||
right[i] = right_down[i];
|
|
||||||
else
|
|
||||||
right[i] = right_up[i];
|
|
||||||
}
|
|
||||||
free(left_up);
|
|
||||||
free(left_down);
|
|
||||||
free(right_up);
|
|
||||||
free(right_down);
|
|
||||||
|
|
||||||
/* Mark minitiae close to the edge */
|
|
||||||
for (i = 0; i < ih; i++) {
|
|
||||||
if (left[i] != -1)
|
|
||||||
mark_minutiae_in_range(minutiae, to_remove, left[i], i, lfsparms);
|
|
||||||
if (right[i] != -1)
|
|
||||||
mark_minutiae_in_range(minutiae, to_remove, right[i], i, lfsparms);
|
|
||||||
}
|
|
||||||
|
|
||||||
free(left);
|
|
||||||
free(right);
|
|
||||||
|
|
||||||
for (i = minutiae->num - 1; i >= 0; i--) {
|
|
||||||
/* If the current minutia index is flagged for removal ... */
|
|
||||||
if (to_remove[i]){
|
|
||||||
removed ++;
|
|
||||||
/* Remove the minutia from the minutiae list. */
|
|
||||||
if((ret = remove_minutia(i, minutiae))){
|
|
||||||
free(to_remove);
|
|
||||||
return(ret);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
free(to_remove);
|
|
||||||
|
|
||||||
return (0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
**************************************************************************
|
**************************************************************************
|
||||||
|
@ -1527,7 +1605,7 @@ static int remove_perimeter_pts(MINUTIAE *minutiae,
|
||||||
Zero - successful completion
|
Zero - successful completion
|
||||||
Negative - system error
|
Negative - system error
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
static int remove_pores_V2(MINUTIAE *minutiae,
|
int remove_pores_V2(MINUTIAE *minutiae,
|
||||||
unsigned char *bdata, const int iw, const int ih,
|
unsigned char *bdata, const int iw, const int ih,
|
||||||
int *direction_map, int *low_flow_map,
|
int *direction_map, int *low_flow_map,
|
||||||
int *high_curve_map, const int mw, const int mh,
|
int *high_curve_map, const int mw, const int mh,
|
||||||
|
@ -1777,7 +1855,7 @@ static int remove_pores_V2(MINUTIAE *minutiae,
|
||||||
/* counter-clockwise scan and step along a */
|
/* counter-clockwise scan and step along a */
|
||||||
/* specified number of steps (ex. 8). */
|
/* specified number of steps (ex. 8). */
|
||||||
ret = trace_contour(&contour_x, &contour_y,
|
ret = trace_contour(&contour_x, &contour_y,
|
||||||
&contour_ex, &contour_ey, &ncontour,
|
&contour_ex, &contour_ey, &ncontour,
|
||||||
lfsparms->pores_steps_bwd,
|
lfsparms->pores_steps_bwd,
|
||||||
qx, qy, qx, qy, qex, qey,
|
qx, qy, qx, qy, qex, qey,
|
||||||
SCAN_COUNTER_CLOCKWISE, bdata, iw, ih);
|
SCAN_COUNTER_CLOCKWISE, bdata, iw, ih);
|
||||||
|
@ -1896,6 +1974,26 @@ static int remove_pores_V2(MINUTIAE *minutiae,
|
||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
#cat: remove_or_adjust_side_minutiae - Removes loops or minutia points that
|
||||||
|
#cat: are not on complete contours of specified length. If the
|
||||||
|
#cat: contour is complete, then the minutia is adjusted based
|
||||||
|
#cat: on a minmax analysis of the rotated y-coords of the contour.
|
||||||
|
|
||||||
|
Input:
|
||||||
|
minutiae - list of true and false minutiae
|
||||||
|
bdata - binary image data (0==while & 1==black)
|
||||||
|
iw - width (in pixels) of image
|
||||||
|
ih - height (in pixels) of image
|
||||||
|
lfsparms - parameters and thresholds for controlling LFS
|
||||||
|
Output:
|
||||||
|
minutiae - list of pruned minutiae
|
||||||
|
Return Code:
|
||||||
|
Zero - successful completion
|
||||||
|
Negative - system error
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
**************************************************************************
|
**************************************************************************
|
||||||
#cat: remove_or_adjust_side_minutiae_V2 - Removes loops or minutia points that
|
#cat: remove_or_adjust_side_minutiae_V2 - Removes loops or minutia points that
|
||||||
|
@ -1918,7 +2016,7 @@ static int remove_pores_V2(MINUTIAE *minutiae,
|
||||||
Zero - successful completion
|
Zero - successful completion
|
||||||
Negative - system error
|
Negative - system error
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
static int remove_or_adjust_side_minutiae_V2(MINUTIAE *minutiae,
|
int remove_or_adjust_side_minutiae_V2(MINUTIAE *minutiae,
|
||||||
unsigned char *bdata, const int iw, const int ih,
|
unsigned char *bdata, const int iw, const int ih,
|
||||||
int *direction_map, const int mw, const int mh,
|
int *direction_map, const int mw, const int mh,
|
||||||
const LFSPARMS *lfsparms)
|
const LFSPARMS *lfsparms)
|
||||||
|
@ -2164,104 +2262,3 @@ static int remove_or_adjust_side_minutiae_V2(MINUTIAE *minutiae,
|
||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
#cat: remove_false_minutia_V2 - Takes a list of true and false minutiae and
|
|
||||||
#cat: attempts to detect and remove the false minutiae based
|
|
||||||
#cat: on a series of tests.
|
|
||||||
|
|
||||||
Input:
|
|
||||||
minutiae - list of true and false minutiae
|
|
||||||
bdata - binary image data (0==while & 1==black)
|
|
||||||
iw - width (in pixels) of image
|
|
||||||
ih - height (in pixels) of image
|
|
||||||
direction_map - map of image blocks containing directional ridge flow
|
|
||||||
low_flow_map - map of image blocks flagged as LOW RIDGE FLOW
|
|
||||||
high_curve_map - map of image blocks flagged as HIGH CURVATURE
|
|
||||||
mw - width in blocks of the maps
|
|
||||||
mh - height in blocks of the maps
|
|
||||||
lfsparms - parameters and thresholds for controlling LFS
|
|
||||||
Output:
|
|
||||||
minutiae - list of pruned minutiae
|
|
||||||
Return Code:
|
|
||||||
Zero - successful completion
|
|
||||||
Negative - system error
|
|
||||||
**************************************************************************/
|
|
||||||
int remove_false_minutia_V2(MINUTIAE *minutiae,
|
|
||||||
unsigned char *bdata, const int iw, const int ih,
|
|
||||||
int *direction_map, int *low_flow_map, int *high_curve_map,
|
|
||||||
const int mw, const int mh, const LFSPARMS *lfsparms)
|
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
/* 1. Sort minutiae points top-to-bottom and left-to-right. */
|
|
||||||
if((ret = sort_minutiae_y_x(minutiae, iw, ih))){
|
|
||||||
return(ret);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 2. Remove minutiae on lakes (filled with white pixels) and */
|
|
||||||
/* islands (filled with black pixels), both defined by a pair of */
|
|
||||||
/* minutia points. */
|
|
||||||
if((ret = remove_islands_and_lakes(minutiae, bdata, iw, ih, lfsparms))){
|
|
||||||
return(ret);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 3. Remove minutiae on holes in the binary image defined by a */
|
|
||||||
/* single point. */
|
|
||||||
if((ret = remove_holes(minutiae, bdata, iw, ih, lfsparms))){
|
|
||||||
return(ret);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 4. Remove minutiae that point sufficiently close to a block with */
|
|
||||||
/* INVALID direction. */
|
|
||||||
if((ret = remove_pointing_invblock_V2(minutiae, direction_map, mw, mh,
|
|
||||||
lfsparms))){
|
|
||||||
return(ret);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 5. Remove minutiae that are sufficiently close to a block with */
|
|
||||||
/* INVALID direction. */
|
|
||||||
if((ret = remove_near_invblock_V2(minutiae, direction_map, mw, mh,
|
|
||||||
lfsparms))){
|
|
||||||
return(ret);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 6. Remove or adjust minutiae that reside on the side of a ridge */
|
|
||||||
/* or valley. */
|
|
||||||
if((ret = remove_or_adjust_side_minutiae_V2(minutiae, bdata, iw, ih,
|
|
||||||
direction_map, mw, mh, lfsparms))){
|
|
||||||
return(ret);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 7. Remove minutiae that form a hook on the side of a ridge or valley. */
|
|
||||||
if((ret = remove_hooks(minutiae, bdata, iw, ih, lfsparms))){
|
|
||||||
return(ret);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 8. Remove minutiae that are on opposite sides of an overlap. */
|
|
||||||
if((ret = remove_overlaps(minutiae, bdata, iw, ih, lfsparms))){
|
|
||||||
return(ret);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 9. Remove minutiae that are "irregularly" shaped. */
|
|
||||||
if((ret = remove_malformations(minutiae, bdata, iw, ih,
|
|
||||||
low_flow_map, mw, mh, lfsparms))){
|
|
||||||
return(ret);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 10. Remove minutiae that form long, narrow, loops in the */
|
|
||||||
/* "unreliable" regions in the binary image. */
|
|
||||||
if((ret = remove_pores_V2(minutiae, bdata, iw, ih,
|
|
||||||
direction_map, low_flow_map, high_curve_map,
|
|
||||||
mw, mh, lfsparms))){
|
|
||||||
return(ret);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 11. Remove minutiae on image edge */
|
|
||||||
if((ret = remove_perimeter_pts(minutiae, bdata, iw, ih, lfsparms))) {
|
|
||||||
return (ret);
|
|
||||||
}
|
|
||||||
|
|
||||||
return(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
|
@ -1,26 +1,47 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
|
|
||||||
License:
|
License:
|
||||||
This software was developed at the National Institute of Standards and
|
This software and/or related materials was developed at the National Institute
|
||||||
Technology (NIST) by employees of the Federal Government in the course
|
of Standards and Technology (NIST) by employees of the Federal Government
|
||||||
of their official duties. Pursuant to title 17 Section 105 of the
|
in the course of their official duties. Pursuant to title 17 Section 105
|
||||||
United States Code, this software is not subject to copyright protection
|
of the United States Code, this software is not subject to copyright
|
||||||
and is in the public domain. NIST assumes no responsibility whatsoever for
|
protection and is in the public domain.
|
||||||
its use by other parties, and makes no guarantees, expressed or implied,
|
|
||||||
about its quality, reliability, or any other characteristic.
|
|
||||||
|
|
||||||
Disclaimer:
|
This software and/or related materials have been determined to be not subject
|
||||||
This software was developed to promote biometric standards and biometric
|
to the EAR (see Part 734.3 of the EAR for exact details) because it is
|
||||||
technology testing for the Federal Government in accordance with the USA
|
a publicly available technology and software, and is freely distributed
|
||||||
PATRIOT Act and the Enhanced Border Security and Visa Entry Reform Act.
|
to any interested party with no licensing requirements. Therefore, it is
|
||||||
Specific hardware and software products identified in this software were used
|
permissible to distribute this software as a free download from the internet.
|
||||||
in order to perform the software development. In no case does such
|
|
||||||
identification imply recommendation or endorsement by the National Institute
|
Disclaimer:
|
||||||
of Standards and Technology, nor does it imply that the products and equipment
|
This software and/or related materials was developed to promote biometric
|
||||||
identified are necessarily the best available for the purpose.
|
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.
|
||||||
|
|
||||||
|
This software and/or related materials are provided "AS-IS" without warranty
|
||||||
|
of any kind including NO WARRANTY OF PERFORMANCE, MERCHANTABILITY,
|
||||||
|
NO WARRANTY OF NON-INFRINGEMENT OF ANY 3RD PARTY INTELLECTUAL PROPERTY
|
||||||
|
or FITNESS FOR A PARTICULAR PURPOSE or for any purpose whatsoever, for the
|
||||||
|
licensed product, however used. In no event shall NIST be liable for any
|
||||||
|
damages and/or costs, including but not limited to incidental or consequential
|
||||||
|
damages of any kind, including economic damage or injury to property and lost
|
||||||
|
profits, regardless of whether NIST shall be advised, have reason to know,
|
||||||
|
or in fact shall know of the possibility.
|
||||||
|
|
||||||
|
By using this software, you agree to bear all risk relating to quality,
|
||||||
|
use and performance of the software and/or related materials. You agree
|
||||||
|
to hold the Government harmless from any claim arising from your use
|
||||||
|
of the software.
|
||||||
|
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
LIBRARY: LFS - NIST Latent Fingerprint System
|
LIBRARY: LFS - NIST Latent Fingerprint System
|
||||||
|
|
||||||
|
@ -52,156 +73,135 @@ identified are necessarily the best available for the purpose.
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
**************************************************************************
|
**************************************************************************
|
||||||
#cat: insert_neighbor - Takes a minutia index and its squared distance to a
|
#cat: count_minutiae_ridges - Takes a list of minutiae, and for each one,
|
||||||
#cat: primary minutia point, and inserts them in the specified
|
#cat: determines its closest neighbors and counts the number
|
||||||
#cat: position of their respective lists, shifting previously
|
#cat: of interveining ridges between the minutia point and
|
||||||
#cat: stored values down and off the lists as necessary.
|
#cat: each of its neighbors.
|
||||||
|
|
||||||
Input:
|
Input:
|
||||||
pos - postions where values are to be inserted in lists
|
minutiae - list of minutiae
|
||||||
nbr_index - index of minutia being inserted
|
bdata - binary image data (0==while & 1==black)
|
||||||
nbr_dist2 - squared distance of minutia to its primary point
|
iw - width (in pixels) of image
|
||||||
nbr_list - current list of nearest neighbor minutia indices
|
ih - height (in pixels) of image
|
||||||
nbr_sqr_dists - corresponding squared euclidean distance of each
|
lfsparms - parameters and thresholds for controlling LFS
|
||||||
neighbor to the primary minutia point
|
|
||||||
nnbrs - number of neighbors currently in the list
|
|
||||||
max_nbrs - maximum number of closest neighbors to be returned
|
|
||||||
Output:
|
Output:
|
||||||
nbr_list - updated list of nearest neighbor indices
|
minutiae - list of minutiae augmented with neighbors and ridge counts
|
||||||
nbr_sqr_dists - updated list of nearest neighbor distances
|
|
||||||
nnbrs - number of neighbors in the update lists
|
|
||||||
Return Code:
|
Return Code:
|
||||||
Zero - successful completion
|
Zero - successful completion
|
||||||
Negative - system error
|
Negative - system error
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
static int insert_neighbor(const int pos, const int nbr_index, const double nbr_dist2,
|
int count_minutiae_ridges(MINUTIAE *minutiae,
|
||||||
int *nbr_list, double *nbr_sqr_dists,
|
unsigned char *bdata, const int iw, const int ih,
|
||||||
int *nnbrs, const int max_nbrs)
|
const LFSPARMS *lfsparms)
|
||||||
{
|
{
|
||||||
|
int ret;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
/* If the desired insertion position is beyond one passed the last */
|
print2log("\nFINDING NBRS AND COUNTING RIDGES:\n");
|
||||||
/* neighbor in the lists OR greater than equal to the maximum ... */
|
|
||||||
/* NOTE: pos is zero-oriented while nnbrs and max_nbrs are 1-oriented. */
|
/* Sort minutia points on x then y (column-oriented). */
|
||||||
if((pos > *nnbrs) ||
|
if((ret = sort_minutiae_x_y(minutiae, iw, ih))){
|
||||||
(pos >= max_nbrs)){
|
return(ret);
|
||||||
fprintf(stderr,
|
|
||||||
"ERROR : insert_neighbor : insertion point exceeds lists\n");
|
|
||||||
return(-480);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If the neighbor lists are NOT full ... */
|
/* Remove any duplicate minutia points from the list. */
|
||||||
if(*nnbrs < max_nbrs){
|
if((ret = rm_dup_minutiae(minutiae))){
|
||||||
/* Then we have room to shift everything down to make room for new */
|
return(ret);
|
||||||
/* neighbor and increase the number of neighbors stored by 1. */
|
|
||||||
i = *nnbrs-1;
|
|
||||||
(*nnbrs)++;
|
|
||||||
}
|
|
||||||
/* Otherwise, the neighbors lists are full ... */
|
|
||||||
else if(*nnbrs == max_nbrs)
|
|
||||||
/* So, we must bump the last neighbor in the lists off to make */
|
|
||||||
/* room for the new neighbor (ignore last neighbor in lists). */
|
|
||||||
i = *nnbrs-2;
|
|
||||||
/* Otherwise, there is a list overflow error condition */
|
|
||||||
/* (shouldn't ever happen, but just in case) ... */
|
|
||||||
else{
|
|
||||||
fprintf(stderr,
|
|
||||||
"ERROR : insert_neighbor : overflow in neighbor lists\n");
|
|
||||||
return(-481);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* While we havn't reached the desired insertion point ... */
|
/* Foreach remaining sorted minutia in list ... */
|
||||||
while(i >= pos){
|
for(i = 0; i < minutiae->num-1; i++){
|
||||||
/* Shift the current neighbor down the list 1 positon. */
|
/* Located neighbors and count number of ridges in between. */
|
||||||
nbr_list[i+1] = nbr_list[i];
|
/* NOTE: neighbor and ridge count results are stored in */
|
||||||
nbr_sqr_dists[i+1] = nbr_sqr_dists[i];
|
/* minutiae->list[i]. */
|
||||||
i--;
|
if((ret = count_minutia_ridges(i, minutiae, bdata, iw, ih, lfsparms))){
|
||||||
|
return(ret);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* We are now ready to put our new neighbor in the position where */
|
|
||||||
/* we shifted everything down from to make room. */
|
|
||||||
nbr_list[pos] = nbr_index;
|
|
||||||
nbr_sqr_dists[pos] = nbr_dist2;
|
|
||||||
|
|
||||||
/* Return normally. */
|
/* Return normally. */
|
||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
**************************************************************************
|
**************************************************************************
|
||||||
#cat: update_nbr_dists - Takes the current list of neighbors along with a
|
#cat: count_minutia_ridges - Takes a minutia, and determines its closest
|
||||||
#cat: primary minutia and a potential new neighbor, and
|
#cat: neighbors and counts the number of interveining ridges
|
||||||
#cat: determines if the new neighbor is sufficiently close
|
#cat: between the minutia point and each of its neighbors.
|
||||||
#cat: to be added to the list of nearest neighbors. If added,
|
|
||||||
#cat: it is placed in the list in its proper order based on
|
|
||||||
#cat: squared distance to the primary point.
|
|
||||||
|
|
||||||
Input:
|
Input:
|
||||||
nbr_list - current list of nearest neighbor minutia indices
|
minutia - input minutia
|
||||||
nbr_sqr_dists - corresponding squared euclidean distance of each
|
bdata - binary image data (0==while & 1==black)
|
||||||
neighbor to the primary minutia point
|
iw - width (in pixels) of image
|
||||||
nnbrs - number of neighbors currently in the list
|
ih - height (in pixels) of image
|
||||||
max_nbrs - maximum number of closest neighbors to be returned
|
lfsparms - parameters and thresholds for controlling LFS
|
||||||
first - index of the primary minutia point
|
|
||||||
second - index of the secondary (new neighbor) point
|
|
||||||
minutiae - list of minutiae
|
|
||||||
Output:
|
Output:
|
||||||
nbr_list - updated list of nearest neighbor indices
|
minutiae - minutia augmented with neighbors and ridge counts
|
||||||
nbr_sqr_dists - updated list of nearest neighbor distances
|
|
||||||
nnbrs - number of neighbors in the update lists
|
|
||||||
Return Code:
|
Return Code:
|
||||||
Zero - successful completion
|
Zero - successful completion
|
||||||
Negative - system error
|
Negative - system error
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
static int update_nbr_dists(int *nbr_list, double *nbr_sqr_dists,
|
int count_minutia_ridges(const int first, MINUTIAE *minutiae,
|
||||||
int *nnbrs, const int max_nbrs,
|
unsigned char *bdata, const int iw, const int ih,
|
||||||
const int first, const int second, MINUTIAE *minutiae)
|
const LFSPARMS *lfsparms)
|
||||||
{
|
{
|
||||||
double dist2;
|
int i, ret, *nbr_list, *nbr_nridges, nnbrs;
|
||||||
MINUTIA *minutia1, *minutia2;
|
|
||||||
int pos, last_nbr;
|
|
||||||
|
|
||||||
/* Compute position of maximum last neighbor stored. */
|
/* Find up to the maximum number of qualifying neighbors. */
|
||||||
last_nbr = max_nbrs - 1;
|
if((ret = find_neighbors(&nbr_list, &nnbrs, lfsparms->max_nbrs,
|
||||||
|
first, minutiae))){
|
||||||
|
free(nbr_list);
|
||||||
|
return(ret);
|
||||||
|
}
|
||||||
|
|
||||||
/* Assigne temporary minutia pointers. */
|
print2log("NBRS FOUND: %d,%d = %d\n", minutiae->list[first]->x,
|
||||||
minutia1 = minutiae->list[first];
|
minutiae->list[first]->y, nnbrs);
|
||||||
minutia2 = minutiae->list[second];
|
|
||||||
|
|
||||||
/* Compute squared euclidean distance between minutia pair. */
|
/* If no neighors found ... */
|
||||||
dist2 = squared_distance(minutia1->x, minutia1->y,
|
if(nnbrs == 0){
|
||||||
minutia2->x, minutia2->y);
|
/* Then no list returned and no ridges to count. */
|
||||||
|
|
||||||
/* If maximum number of neighbors not yet stored in lists OR */
|
|
||||||
/* if the squared distance to current secondary is less */
|
|
||||||
/* than the largest stored neighbor distance ... */
|
|
||||||
if((*nnbrs < max_nbrs) ||
|
|
||||||
(dist2 < nbr_sqr_dists[last_nbr])){
|
|
||||||
|
|
||||||
/* Find insertion point in neighbor lists. */
|
|
||||||
pos = find_incr_position_dbl(dist2, nbr_sqr_dists, *nnbrs);
|
|
||||||
/* If the position returned is >= maximum list length (this should */
|
|
||||||
/* never happen, but just in case) ... */
|
|
||||||
if(pos >= max_nbrs){
|
|
||||||
fprintf(stderr,
|
|
||||||
"ERROR : update_nbr_dists : illegal position for new neighbor\n");
|
|
||||||
return(-470);
|
|
||||||
}
|
|
||||||
/* Insert the new neighbor into the neighbor lists at the */
|
|
||||||
/* specified location. */
|
|
||||||
if(insert_neighbor(pos, second, dist2,
|
|
||||||
nbr_list, nbr_sqr_dists, nnbrs, max_nbrs))
|
|
||||||
return(-471);
|
|
||||||
|
|
||||||
/* Otherwise, neighbor inserted successfully, so return normally. */
|
|
||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
/* Otherwise, the new neighbor is not sufficiently close to be */
|
|
||||||
/* added or inserted into the neighbor lists, so ignore the neighbor */
|
|
||||||
/* and return normally. */
|
|
||||||
else
|
|
||||||
return(0);
|
|
||||||
|
|
||||||
|
/* Sort neighbors on delta dirs. */
|
||||||
|
if((ret = sort_neighbors(nbr_list, nnbrs, first, minutiae))){
|
||||||
|
free(nbr_list);
|
||||||
|
return(ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Count ridges between first and neighbors. */
|
||||||
|
/* List of ridge counts, one for each neighbor stored. */
|
||||||
|
nbr_nridges = (int *)malloc(nnbrs * sizeof(int));
|
||||||
|
if(nbr_nridges == (int *)NULL){
|
||||||
|
free(nbr_list);
|
||||||
|
fprintf(stderr, "ERROR : count_minutia_ridges : malloc : nbr_nridges\n");
|
||||||
|
return(-450);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Foreach neighbor found and sorted in list ... */
|
||||||
|
for(i = 0; i < nnbrs; i++){
|
||||||
|
/* Count the ridges between the primary minutia and the neighbor. */
|
||||||
|
ret = ridge_count(first, nbr_list[i], minutiae, bdata, iw, ih, lfsparms);
|
||||||
|
/* If system error ... */
|
||||||
|
if(ret < 0){
|
||||||
|
/* Deallocate working memories. */
|
||||||
|
free(nbr_list);
|
||||||
|
free(nbr_nridges);
|
||||||
|
/* Return error code. */
|
||||||
|
return(ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Otherwise, ridge count successful, so store ridge count to list. */
|
||||||
|
nbr_nridges[i] = ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Assign neighbor indices and ridge counts to primary minutia. */
|
||||||
|
minutiae->list[first]->nbrs = nbr_list;
|
||||||
|
minutiae->list[first]->ridge_counts = nbr_nridges;
|
||||||
|
minutiae->list[first]->num_nbrs = nnbrs;
|
||||||
|
|
||||||
|
/* Return normally. */
|
||||||
|
return(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
|
@ -224,7 +224,7 @@ static int update_nbr_dists(int *nbr_list, double *nbr_sqr_dists,
|
||||||
Zero - successful completion
|
Zero - successful completion
|
||||||
Negative - system error
|
Negative - system error
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
static int find_neighbors(int **onbr_list, int *onnbrs, const int max_nbrs,
|
int find_neighbors(int **onbr_list, int *onnbrs, const int max_nbrs,
|
||||||
const int first, MINUTIAE *minutiae)
|
const int first, MINUTIAE *minutiae)
|
||||||
{
|
{
|
||||||
int ret, second, last_nbr;
|
int ret, second, last_nbr;
|
||||||
|
@ -312,6 +312,160 @@ static int find_neighbors(int **onbr_list, int *onnbrs, const int max_nbrs,
|
||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
#cat: update_nbr_dists - Takes the current list of neighbors along with a
|
||||||
|
#cat: primary minutia and a potential new neighbor, and
|
||||||
|
#cat: determines if the new neighbor is sufficiently close
|
||||||
|
#cat: to be added to the list of nearest neighbors. If added,
|
||||||
|
#cat: it is placed in the list in its proper order based on
|
||||||
|
#cat: squared distance to the primary point.
|
||||||
|
|
||||||
|
Input:
|
||||||
|
nbr_list - current list of nearest neighbor minutia indices
|
||||||
|
nbr_sqr_dists - corresponding squared euclidean distance of each
|
||||||
|
neighbor to the primary minutia point
|
||||||
|
nnbrs - number of neighbors currently in the list
|
||||||
|
max_nbrs - maximum number of closest neighbors to be returned
|
||||||
|
first - index of the primary minutia point
|
||||||
|
second - index of the secondary (new neighbor) point
|
||||||
|
minutiae - list of minutiae
|
||||||
|
Output:
|
||||||
|
nbr_list - updated list of nearest neighbor indices
|
||||||
|
nbr_sqr_dists - updated list of nearest neighbor distances
|
||||||
|
nnbrs - number of neighbors in the update lists
|
||||||
|
Return Code:
|
||||||
|
Zero - successful completion
|
||||||
|
Negative - system error
|
||||||
|
**************************************************************************/
|
||||||
|
int update_nbr_dists(int *nbr_list, double *nbr_sqr_dists,
|
||||||
|
int *nnbrs, const int max_nbrs,
|
||||||
|
const int first, const int second, MINUTIAE *minutiae)
|
||||||
|
{
|
||||||
|
double dist2;
|
||||||
|
MINUTIA *minutia1, *minutia2;
|
||||||
|
int pos, last_nbr;
|
||||||
|
|
||||||
|
/* Compute position of maximum last neighbor stored. */
|
||||||
|
last_nbr = max_nbrs - 1;
|
||||||
|
|
||||||
|
/* Assigne temporary minutia pointers. */
|
||||||
|
minutia1 = minutiae->list[first];
|
||||||
|
minutia2 = minutiae->list[second];
|
||||||
|
|
||||||
|
/* Compute squared euclidean distance between minutia pair. */
|
||||||
|
dist2 = squared_distance(minutia1->x, minutia1->y,
|
||||||
|
minutia2->x, minutia2->y);
|
||||||
|
|
||||||
|
/* If maximum number of neighbors not yet stored in lists OR */
|
||||||
|
/* if the squared distance to current secondary is less */
|
||||||
|
/* than the largest stored neighbor distance ... */
|
||||||
|
if((*nnbrs < max_nbrs) ||
|
||||||
|
(dist2 < nbr_sqr_dists[last_nbr])){
|
||||||
|
|
||||||
|
/* Find insertion point in neighbor lists. */
|
||||||
|
pos = find_incr_position_dbl(dist2, nbr_sqr_dists, *nnbrs);
|
||||||
|
/* If the position returned is >= maximum list length (this should */
|
||||||
|
/* never happen, but just in case) ... */
|
||||||
|
if(pos >= max_nbrs){
|
||||||
|
fprintf(stderr,
|
||||||
|
"ERROR : update_nbr_dists : illegal position for new neighbor\n");
|
||||||
|
return(-470);
|
||||||
|
}
|
||||||
|
/* Insert the new neighbor into the neighbor lists at the */
|
||||||
|
/* specified location. */
|
||||||
|
if(insert_neighbor(pos, second, dist2,
|
||||||
|
nbr_list, nbr_sqr_dists, nnbrs, max_nbrs))
|
||||||
|
return(-471);
|
||||||
|
|
||||||
|
/* Otherwise, neighbor inserted successfully, so return normally. */
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
/* Otherwise, the new neighbor is not sufficiently close to be */
|
||||||
|
/* added or inserted into the neighbor lists, so ignore the neighbor */
|
||||||
|
/* and return normally. */
|
||||||
|
else
|
||||||
|
return(0);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
#cat: insert_neighbor - Takes a minutia index and its squared distance to a
|
||||||
|
#cat: primary minutia point, and inserts them in the specified
|
||||||
|
#cat: position of their respective lists, shifting previously
|
||||||
|
#cat: stored values down and off the lists as necessary.
|
||||||
|
|
||||||
|
Input:
|
||||||
|
pos - postions where values are to be inserted in lists
|
||||||
|
nbr_index - index of minutia being inserted
|
||||||
|
nbr_dist2 - squared distance of minutia to its primary point
|
||||||
|
nbr_list - current list of nearest neighbor minutia indices
|
||||||
|
nbr_sqr_dists - corresponding squared euclidean distance of each
|
||||||
|
neighbor to the primary minutia point
|
||||||
|
nnbrs - number of neighbors currently in the list
|
||||||
|
max_nbrs - maximum number of closest neighbors to be returned
|
||||||
|
Output:
|
||||||
|
nbr_list - updated list of nearest neighbor indices
|
||||||
|
nbr_sqr_dists - updated list of nearest neighbor distances
|
||||||
|
nnbrs - number of neighbors in the update lists
|
||||||
|
Return Code:
|
||||||
|
Zero - successful completion
|
||||||
|
Negative - system error
|
||||||
|
**************************************************************************/
|
||||||
|
int insert_neighbor(const int pos, const int nbr_index, const double nbr_dist2,
|
||||||
|
int *nbr_list, double *nbr_sqr_dists,
|
||||||
|
int *nnbrs, const int max_nbrs)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
/* If the desired insertion position is beyond one passed the last */
|
||||||
|
/* neighbor in the lists OR greater than equal to the maximum ... */
|
||||||
|
/* NOTE: pos is zero-oriented while nnbrs and max_nbrs are 1-oriented. */
|
||||||
|
if((pos > *nnbrs) ||
|
||||||
|
(pos >= max_nbrs)){
|
||||||
|
fprintf(stderr,
|
||||||
|
"ERROR : insert_neighbor : insertion point exceeds lists\n");
|
||||||
|
return(-480);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If the neighbor lists are NOT full ... */
|
||||||
|
if(*nnbrs < max_nbrs){
|
||||||
|
/* Then we have room to shift everything down to make room for new */
|
||||||
|
/* neighbor and increase the number of neighbors stored by 1. */
|
||||||
|
i = *nnbrs-1;
|
||||||
|
(*nnbrs)++;
|
||||||
|
}
|
||||||
|
/* Otherwise, the neighbors lists are full ... */
|
||||||
|
else if(*nnbrs == max_nbrs)
|
||||||
|
/* So, we must bump the last neighbor in the lists off to make */
|
||||||
|
/* room for the new neighbor (ignore last neighbor in lists). */
|
||||||
|
i = *nnbrs-2;
|
||||||
|
/* Otherwise, there is a list overflow error condition */
|
||||||
|
/* (shouldn't ever happen, but just in case) ... */
|
||||||
|
else{
|
||||||
|
fprintf(stderr,
|
||||||
|
"ERROR : insert_neighbor : overflow in neighbor lists\n");
|
||||||
|
return(-481);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* While we havn't reached the desired insertion point ... */
|
||||||
|
while(i >= pos){
|
||||||
|
/* Shift the current neighbor down the list 1 positon. */
|
||||||
|
nbr_list[i+1] = nbr_list[i];
|
||||||
|
nbr_sqr_dists[i+1] = nbr_sqr_dists[i];
|
||||||
|
i--;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* We are now ready to put our new neighbor in the position where */
|
||||||
|
/* we shifted everything down from to make room. */
|
||||||
|
nbr_list[pos] = nbr_index;
|
||||||
|
nbr_sqr_dists[pos] = nbr_dist2;
|
||||||
|
|
||||||
|
/* Return normally. */
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
**************************************************************************
|
**************************************************************************
|
||||||
#cat: sort_neighbors - Takes a list of primary minutia and its neighboring
|
#cat: sort_neighbors - Takes a list of primary minutia and its neighboring
|
||||||
|
@ -331,7 +485,7 @@ static int find_neighbors(int **onbr_list, int *onnbrs, const int max_nbrs,
|
||||||
Zero - successful completion
|
Zero - successful completion
|
||||||
Negative - system error
|
Negative - system error
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
static int sort_neighbors(int *nbr_list, const int nnbrs, const int first,
|
int sort_neighbors(int *nbr_list, const int nnbrs, const int first,
|
||||||
MINUTIAE *minutiae)
|
MINUTIAE *minutiae)
|
||||||
{
|
{
|
||||||
double *join_thetas, theta;
|
double *join_thetas, theta;
|
||||||
|
@ -369,7 +523,164 @@ static int sort_neighbors(int *nbr_list, const int nnbrs, const int first,
|
||||||
free(join_thetas);
|
free(join_thetas);
|
||||||
|
|
||||||
/* Return normally. */
|
/* Return normally. */
|
||||||
return(0);
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
#cat: ridge_count - Takes a pair of minutiae, and counts the number of
|
||||||
|
#cat: ridges crossed along the linear trajectory connecting
|
||||||
|
#cat: the 2 points in the image.
|
||||||
|
|
||||||
|
Input:
|
||||||
|
first - index of primary minutia
|
||||||
|
second - index of secondary (neighbor) minutia
|
||||||
|
minutiae - list of minutiae
|
||||||
|
bdata - binary image data (0==while & 1==black)
|
||||||
|
iw - width (in pixels) of image
|
||||||
|
ih - height (in pixels) of image
|
||||||
|
lfsparms - parameters and thresholds for controlling LFS
|
||||||
|
Return Code:
|
||||||
|
Zero or Positive - number of ridges counted
|
||||||
|
Negative - system error
|
||||||
|
**************************************************************************/
|
||||||
|
int ridge_count(const int first, const int second, MINUTIAE *minutiae,
|
||||||
|
unsigned char *bdata, const int iw, const int ih,
|
||||||
|
const LFSPARMS *lfsparms)
|
||||||
|
{
|
||||||
|
MINUTIA *minutia1, *minutia2;
|
||||||
|
int i, ret, found;
|
||||||
|
int *xlist, *ylist, num;
|
||||||
|
int ridge_count, ridge_start, ridge_end;
|
||||||
|
int prevpix, curpix;
|
||||||
|
|
||||||
|
minutia1 = minutiae->list[first];
|
||||||
|
minutia2 = minutiae->list[second];
|
||||||
|
|
||||||
|
/* If the 2 mintuia have identical pixel coords ... */
|
||||||
|
if((minutia1->x == minutia2->x) &&
|
||||||
|
(minutia1->y == minutia2->y))
|
||||||
|
/* Then zero ridges between points. */
|
||||||
|
return(0);
|
||||||
|
|
||||||
|
/* Compute linear trajectory of contiguous pixels between first */
|
||||||
|
/* and second minutia points. */
|
||||||
|
if((ret = line_points(&xlist, &ylist, &num,
|
||||||
|
minutia1->x, minutia1->y, minutia2->x, minutia2->y))){
|
||||||
|
return(ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* It there are no points on the line trajectory, then no ridges */
|
||||||
|
/* to count (this should not happen, but just in case) ... */
|
||||||
|
if(num == 0){
|
||||||
|
free(xlist);
|
||||||
|
free(ylist);
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Find first pixel opposite type along linear trajectory from */
|
||||||
|
/* first minutia. */
|
||||||
|
prevpix = *(bdata+(ylist[0]*iw)+xlist[0]);
|
||||||
|
i = 1;
|
||||||
|
found = FALSE;
|
||||||
|
while(i < num){
|
||||||
|
curpix = *(bdata+(ylist[i]*iw)+xlist[i]);
|
||||||
|
if(curpix != prevpix){
|
||||||
|
found = TRUE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If opposite pixel not found ... then no ridges to count */
|
||||||
|
if(!found){
|
||||||
|
free(xlist);
|
||||||
|
free(ylist);
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Ready to count ridges, so initialize counter to 0. */
|
||||||
|
ridge_count = 0;
|
||||||
|
|
||||||
|
print2log("RIDGE COUNT: %d,%d to %d,%d ", minutia1->x, minutia1->y,
|
||||||
|
minutia2->x, minutia2->y);
|
||||||
|
|
||||||
|
/* While not at the end of the trajectory ... */
|
||||||
|
while(i < num){
|
||||||
|
/* If 0-to-1 transition not found ... */
|
||||||
|
if(!find_transition(&i, 0, 1, xlist, ylist, num, bdata, iw, ih)){
|
||||||
|
/* Then we are done looking for ridges. */
|
||||||
|
free(xlist);
|
||||||
|
free(ylist);
|
||||||
|
|
||||||
|
print2log("\n");
|
||||||
|
|
||||||
|
/* Return number of ridges counted to this point. */
|
||||||
|
return(ridge_count);
|
||||||
|
}
|
||||||
|
/* Otherwise, we found a new ridge start transition, so store */
|
||||||
|
/* its location (the location of the 1 in 0-to-1 transition). */
|
||||||
|
ridge_start = i;
|
||||||
|
|
||||||
|
print2log(": RS %d,%d ", xlist[i], ylist[i]);
|
||||||
|
|
||||||
|
/* If 1-to-0 transition not found ... */
|
||||||
|
if(!find_transition(&i, 1, 0, xlist, ylist, num, bdata, iw, ih)){
|
||||||
|
/* Then we are done looking for ridges. */
|
||||||
|
free(xlist);
|
||||||
|
free(ylist);
|
||||||
|
|
||||||
|
print2log("\n");
|
||||||
|
|
||||||
|
/* Return number of ridges counted to this point. */
|
||||||
|
return(ridge_count);
|
||||||
|
}
|
||||||
|
/* Otherwise, we found a new ridge end transition, so store */
|
||||||
|
/* its location (the location of the 0 in 1-to-0 transition). */
|
||||||
|
ridge_end = i;
|
||||||
|
|
||||||
|
print2log("; RE %d,%d ", xlist[i], ylist[i]);
|
||||||
|
|
||||||
|
/* Conduct the validation, tracing the contour of the ridge */
|
||||||
|
/* from the ridge ending point a specified number of steps */
|
||||||
|
/* scanning for neighbors clockwise and counter-clockwise. */
|
||||||
|
/* If the ridge starting point is encounted during the trace */
|
||||||
|
/* then we can assume we do not have a valid ridge crossing */
|
||||||
|
/* and instead we are walking on and off the edge of the */
|
||||||
|
/* side of a ridge. */
|
||||||
|
ret = validate_ridge_crossing(ridge_start, ridge_end,
|
||||||
|
xlist, ylist, num, bdata, iw, ih,
|
||||||
|
lfsparms->max_ridge_steps);
|
||||||
|
|
||||||
|
/* If system error ... */
|
||||||
|
if(ret < 0){
|
||||||
|
free(xlist);
|
||||||
|
free(ylist);
|
||||||
|
/* Return the error code. */
|
||||||
|
return(ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
print2log("; V%d ", ret);
|
||||||
|
|
||||||
|
/* If validation result is TRUE ... */
|
||||||
|
if(ret){
|
||||||
|
/* Then assume we have found a valid ridge crossing and bump */
|
||||||
|
/* the ridge counter. */
|
||||||
|
ridge_count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Otherwise, ignore the current ridge start and end transitions */
|
||||||
|
/* and go back and search for new ridge start. */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Deallocate working memories. */
|
||||||
|
free(xlist);
|
||||||
|
free(ylist);
|
||||||
|
|
||||||
|
print2log("\n");
|
||||||
|
|
||||||
|
/* Return the number of ridges counted. */
|
||||||
|
return(ridge_count);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
|
@ -395,7 +706,7 @@ static int sort_neighbors(int *nbr_list, const int nnbrs, const int first,
|
||||||
TRUE - pixel pair transition found
|
TRUE - pixel pair transition found
|
||||||
FALSE - pixel pair transition not found
|
FALSE - pixel pair transition not found
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
static int find_transition(int *iptr, const int pix1, const int pix2,
|
int find_transition(int *iptr, const int pix1, const int pix2,
|
||||||
const int *xlist, const int *ylist, const int num,
|
const int *xlist, const int *ylist, const int num,
|
||||||
unsigned char *bdata, const int iw, const int ih)
|
unsigned char *bdata, const int iw, const int ih)
|
||||||
{
|
{
|
||||||
|
@ -456,7 +767,7 @@ static int find_transition(int *iptr, const int pix1, const int pix2,
|
||||||
FALSE - ridge corssing INVALID
|
FALSE - ridge corssing INVALID
|
||||||
Negative - system error
|
Negative - system error
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
static int validate_ridge_crossing(const int ridge_start, const int ridge_end,
|
int validate_ridge_crossing(const int ridge_start, const int ridge_end,
|
||||||
const int *xlist, const int *ylist, const int num,
|
const int *xlist, const int *ylist, const int num,
|
||||||
unsigned char *bdata, const int iw, const int ih,
|
unsigned char *bdata, const int iw, const int ih,
|
||||||
const int max_ridge_steps)
|
const int max_ridge_steps)
|
||||||
|
@ -482,7 +793,7 @@ static int validate_ridge_crossing(const int ridge_start, const int ridge_end,
|
||||||
/* position is on the white (of a black to white transition) and */
|
/* position is on the white (of a black to white transition) and */
|
||||||
/* the ridge start is on the black (of a black to white trans), */
|
/* the ridge start is on the black (of a black to white trans), */
|
||||||
/* so the edge trace needs to look for the what pixel (not the */
|
/* so the edge trace needs to look for the what pixel (not the */
|
||||||
/* black one) of the ridge start transition. */
|
/* black one) of the ridge start transition. */
|
||||||
ret = trace_contour(&contour_x, &contour_y,
|
ret = trace_contour(&contour_x, &contour_y,
|
||||||
&contour_ex, &contour_ey, &ncontour,
|
&contour_ex, &contour_ey, &ncontour,
|
||||||
max_ridge_steps,
|
max_ridge_steps,
|
||||||
|
@ -535,298 +846,7 @@ static int validate_ridge_crossing(const int ridge_start, const int ridge_end,
|
||||||
/* Otherwise, second trace returned IGNORE or ridge start found. */
|
/* Otherwise, second trace returned IGNORE or ridge start found. */
|
||||||
}
|
}
|
||||||
/* Otherwise, first trace returned IGNORE or ridge start found. */
|
/* Otherwise, first trace returned IGNORE or ridge start found. */
|
||||||
|
|
||||||
/* If we get here, then we failed to validate a ridge crossing. */
|
/* If we get here, then we failed to validate a ridge crossing. */
|
||||||
return(FALSE);
|
return(FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
#cat: ridge_count - Takes a pair of minutiae, and counts the number of
|
|
||||||
#cat: ridges crossed along the linear trajectory connecting
|
|
||||||
#cat: the 2 points in the image.
|
|
||||||
|
|
||||||
Input:
|
|
||||||
first - index of primary minutia
|
|
||||||
second - index of secondary (neighbor) minutia
|
|
||||||
minutiae - list of minutiae
|
|
||||||
bdata - binary image data (0==while & 1==black)
|
|
||||||
iw - width (in pixels) of image
|
|
||||||
ih - height (in pixels) of image
|
|
||||||
lfsparms - parameters and thresholds for controlling LFS
|
|
||||||
Return Code:
|
|
||||||
Zero or Positive - number of ridges counted
|
|
||||||
Negative - system error
|
|
||||||
**************************************************************************/
|
|
||||||
static int ridge_count(const int first, const int second, MINUTIAE *minutiae,
|
|
||||||
unsigned char *bdata, const int iw, const int ih,
|
|
||||||
const LFSPARMS *lfsparms)
|
|
||||||
{
|
|
||||||
MINUTIA *minutia1, *minutia2;
|
|
||||||
int i, ret, found;
|
|
||||||
int *xlist, *ylist, num;
|
|
||||||
int ridge_cnt, ridge_start, ridge_end;
|
|
||||||
int prevpix, curpix;
|
|
||||||
|
|
||||||
minutia1 = minutiae->list[first];
|
|
||||||
minutia2 = minutiae->list[second];
|
|
||||||
|
|
||||||
/* If the 2 mintuia have identical pixel coords ... */
|
|
||||||
if((minutia1->x == minutia2->x) &&
|
|
||||||
(minutia1->y == minutia2->y))
|
|
||||||
/* Then zero ridges between points. */
|
|
||||||
return(0);
|
|
||||||
|
|
||||||
/* Compute linear trajectory of contiguous pixels between first */
|
|
||||||
/* and second minutia points. */
|
|
||||||
if((ret = line_points(&xlist, &ylist, &num,
|
|
||||||
minutia1->x, minutia1->y, minutia2->x, minutia2->y))){
|
|
||||||
return(ret);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* It there are no points on the line trajectory, then no ridges */
|
|
||||||
/* to count (this should not happen, but just in case) ... */
|
|
||||||
if(num == 0){
|
|
||||||
free(xlist);
|
|
||||||
free(ylist);
|
|
||||||
return(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Find first pixel opposite type along linear trajectory from */
|
|
||||||
/* first minutia. */
|
|
||||||
prevpix = *(bdata+(ylist[0]*iw)+xlist[0]);
|
|
||||||
i = 1;
|
|
||||||
found = FALSE;
|
|
||||||
while(i < num){
|
|
||||||
curpix = *(bdata+(ylist[i]*iw)+xlist[i]);
|
|
||||||
if(curpix != prevpix){
|
|
||||||
found = TRUE;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* If opposite pixel not found ... then no ridges to count */
|
|
||||||
if(!found){
|
|
||||||
free(xlist);
|
|
||||||
free(ylist);
|
|
||||||
return(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Ready to count ridges, so initialize counter to 0. */
|
|
||||||
ridge_cnt = 0;
|
|
||||||
|
|
||||||
print2log("RIDGE COUNT: %d,%d to %d,%d ", minutia1->x, minutia1->y,
|
|
||||||
minutia2->x, minutia2->y);
|
|
||||||
|
|
||||||
/* While not at the end of the trajectory ... */
|
|
||||||
while(i < num){
|
|
||||||
/* If 0-to-1 transition not found ... */
|
|
||||||
if(!find_transition(&i, 0, 1, xlist, ylist, num, bdata, iw, ih)){
|
|
||||||
/* Then we are done looking for ridges. */
|
|
||||||
free(xlist);
|
|
||||||
free(ylist);
|
|
||||||
|
|
||||||
print2log("\n");
|
|
||||||
|
|
||||||
/* Return number of ridges counted to this point. */
|
|
||||||
return(ridge_cnt);
|
|
||||||
}
|
|
||||||
/* Otherwise, we found a new ridge start transition, so store */
|
|
||||||
/* its location (the location of the 1 in 0-to-1 transition). */
|
|
||||||
ridge_start = i;
|
|
||||||
|
|
||||||
print2log(": RS %d,%d ", xlist[i], ylist[i]);
|
|
||||||
|
|
||||||
/* If 1-to-0 transition not found ... */
|
|
||||||
if(!find_transition(&i, 1, 0, xlist, ylist, num, bdata, iw, ih)){
|
|
||||||
/* Then we are done looking for ridges. */
|
|
||||||
free(xlist);
|
|
||||||
free(ylist);
|
|
||||||
|
|
||||||
print2log("\n");
|
|
||||||
|
|
||||||
/* Return number of ridges counted to this point. */
|
|
||||||
return(ridge_cnt);
|
|
||||||
}
|
|
||||||
/* Otherwise, we found a new ridge end transition, so store */
|
|
||||||
/* its location (the location of the 0 in 1-to-0 transition). */
|
|
||||||
ridge_end = i;
|
|
||||||
|
|
||||||
print2log("; RE %d,%d ", xlist[i], ylist[i]);
|
|
||||||
|
|
||||||
/* Conduct the validation, tracing the contour of the ridge */
|
|
||||||
/* from the ridge ending point a specified number of steps */
|
|
||||||
/* scanning for neighbors clockwise and counter-clockwise. */
|
|
||||||
/* If the ridge starting point is encounted during the trace */
|
|
||||||
/* then we can assume we do not have a valid ridge crossing */
|
|
||||||
/* and instead we are walking on and off the edge of the */
|
|
||||||
/* side of a ridge. */
|
|
||||||
ret = validate_ridge_crossing(ridge_start, ridge_end,
|
|
||||||
xlist, ylist, num, bdata, iw, ih,
|
|
||||||
lfsparms->max_ridge_steps);
|
|
||||||
|
|
||||||
/* If system error ... */
|
|
||||||
if(ret < 0){
|
|
||||||
free(xlist);
|
|
||||||
free(ylist);
|
|
||||||
/* Return the error code. */
|
|
||||||
return(ret);
|
|
||||||
}
|
|
||||||
|
|
||||||
print2log("; V%d ", ret);
|
|
||||||
|
|
||||||
/* If validation result is TRUE ... */
|
|
||||||
if(ret){
|
|
||||||
/* Then assume we have found a valid ridge crossing and bump */
|
|
||||||
/* the ridge counter. */
|
|
||||||
ridge_cnt++;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Otherwise, ignore the current ridge start and end transitions */
|
|
||||||
/* and go back and search for new ridge start. */
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Deallocate working memories. */
|
|
||||||
free(xlist);
|
|
||||||
free(ylist);
|
|
||||||
|
|
||||||
print2log("\n");
|
|
||||||
|
|
||||||
/* Return the number of ridges counted. */
|
|
||||||
return(ridge_cnt);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
#cat: count_minutia_ridges - Takes a minutia, and determines its closest
|
|
||||||
#cat: neighbors and counts the number of interveining ridges
|
|
||||||
#cat: between the minutia point and each of its neighbors.
|
|
||||||
|
|
||||||
Input:
|
|
||||||
minutia - input minutia
|
|
||||||
bdata - binary image data (0==while & 1==black)
|
|
||||||
iw - width (in pixels) of image
|
|
||||||
ih - height (in pixels) of image
|
|
||||||
lfsparms - parameters and thresholds for controlling LFS
|
|
||||||
Output:
|
|
||||||
minutiae - minutia augmented with neighbors and ridge counts
|
|
||||||
Return Code:
|
|
||||||
Zero - successful completion
|
|
||||||
Negative - system error
|
|
||||||
**************************************************************************/
|
|
||||||
static int count_minutia_ridges(const int first, MINUTIAE *minutiae,
|
|
||||||
unsigned char *bdata, const int iw, const int ih,
|
|
||||||
const LFSPARMS *lfsparms)
|
|
||||||
{
|
|
||||||
int i, ret, *nbr_list = NULL, *nbr_nridges, nnbrs;
|
|
||||||
|
|
||||||
/* Find up to the maximum number of qualifying neighbors. */
|
|
||||||
if((ret = find_neighbors(&nbr_list, &nnbrs, lfsparms->max_nbrs,
|
|
||||||
first, minutiae))){
|
|
||||||
free(nbr_list);
|
|
||||||
return(ret);
|
|
||||||
}
|
|
||||||
|
|
||||||
print2log("NBRS FOUND: %d,%d = %d\n", minutiae->list[first]->x,
|
|
||||||
minutiae->list[first]->y, nnbrs);
|
|
||||||
|
|
||||||
/* If no neighors found ... */
|
|
||||||
if(nnbrs == 0){
|
|
||||||
/* Then no list returned and no ridges to count. */
|
|
||||||
return(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Sort neighbors on delta dirs. */
|
|
||||||
if((ret = sort_neighbors(nbr_list, nnbrs, first, minutiae))){
|
|
||||||
free(nbr_list);
|
|
||||||
return(ret);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Count ridges between first and neighbors. */
|
|
||||||
/* List of ridge counts, one for each neighbor stored. */
|
|
||||||
nbr_nridges = (int *)malloc(nnbrs * sizeof(int));
|
|
||||||
if(nbr_nridges == (int *)NULL){
|
|
||||||
free(nbr_list);
|
|
||||||
fprintf(stderr, "ERROR : count_minutia_ridges : malloc : nbr_nridges\n");
|
|
||||||
return(-450);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Foreach neighbor found and sorted in list ... */
|
|
||||||
for(i = 0; i < nnbrs; i++){
|
|
||||||
/* Count the ridges between the primary minutia and the neighbor. */
|
|
||||||
ret = ridge_count(first, nbr_list[i], minutiae, bdata, iw, ih, lfsparms);
|
|
||||||
/* If system error ... */
|
|
||||||
if(ret < 0){
|
|
||||||
/* Deallocate working memories. */
|
|
||||||
free(nbr_list);
|
|
||||||
free(nbr_nridges);
|
|
||||||
/* Return error code. */
|
|
||||||
return(ret);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Otherwise, ridge count successful, so store ridge count to list. */
|
|
||||||
nbr_nridges[i] = ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Assign neighbor indices and ridge counts to primary minutia. */
|
|
||||||
minutiae->list[first]->nbrs = nbr_list;
|
|
||||||
minutiae->list[first]->ridge_counts = nbr_nridges;
|
|
||||||
minutiae->list[first]->num_nbrs = nnbrs;
|
|
||||||
|
|
||||||
/* Return normally. */
|
|
||||||
return(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
#cat: count_minutiae_ridges - Takes a list of minutiae, and for each one,
|
|
||||||
#cat: determines its closest neighbors and counts the number
|
|
||||||
#cat: of interveining ridges between the minutia point and
|
|
||||||
#cat: each of its neighbors.
|
|
||||||
|
|
||||||
Input:
|
|
||||||
minutiae - list of minutiae
|
|
||||||
bdata - binary image data (0==while & 1==black)
|
|
||||||
iw - width (in pixels) of image
|
|
||||||
ih - height (in pixels) of image
|
|
||||||
lfsparms - parameters and thresholds for controlling LFS
|
|
||||||
Output:
|
|
||||||
minutiae - list of minutiae augmented with neighbors and ridge counts
|
|
||||||
Return Code:
|
|
||||||
Zero - successful completion
|
|
||||||
Negative - system error
|
|
||||||
**************************************************************************/
|
|
||||||
int count_minutiae_ridges(MINUTIAE *minutiae,
|
|
||||||
unsigned char *bdata, const int iw, const int ih,
|
|
||||||
const LFSPARMS *lfsparms)
|
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
print2log("\nFINDING NBRS AND COUNTING RIDGES:\n");
|
|
||||||
|
|
||||||
/* Sort minutia points on x then y (column-oriented). */
|
|
||||||
if((ret = sort_minutiae_x_y(minutiae, iw, ih))){
|
|
||||||
return(ret);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Remove any duplicate minutia points from the list. */
|
|
||||||
if((ret = rm_dup_minutiae(minutiae))){
|
|
||||||
return(ret);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Foreach remaining sorted minutia in list ... */
|
|
||||||
for(i = 0; i < minutiae->num-1; i++){
|
|
||||||
/* Located neighbors and count number of ridges in between. */
|
|
||||||
/* NOTE: neighbor and ridge count results are stored in */
|
|
||||||
/* minutiae->list[i]. */
|
|
||||||
if((ret = count_minutia_ridges(i, minutiae, bdata, iw, ih, lfsparms))){
|
|
||||||
return(ret);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Return normally. */
|
|
||||||
return(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
|
@ -1,26 +1,47 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
|
|
||||||
License:
|
License:
|
||||||
This software was developed at the National Institute of Standards and
|
This software and/or related materials was developed at the National Institute
|
||||||
Technology (NIST) by employees of the Federal Government in the course
|
of Standards and Technology (NIST) by employees of the Federal Government
|
||||||
of their official duties. Pursuant to title 17 Section 105 of the
|
in the course of their official duties. Pursuant to title 17 Section 105
|
||||||
United States Code, this software is not subject to copyright protection
|
of the United States Code, this software is not subject to copyright
|
||||||
and is in the public domain. NIST assumes no responsibility whatsoever for
|
protection and is in the public domain.
|
||||||
its use by other parties, and makes no guarantees, expressed or implied,
|
|
||||||
about its quality, reliability, or any other characteristic.
|
|
||||||
|
|
||||||
Disclaimer:
|
This software and/or related materials have been determined to be not subject
|
||||||
This software was developed to promote biometric standards and biometric
|
to the EAR (see Part 734.3 of the EAR for exact details) because it is
|
||||||
technology testing for the Federal Government in accordance with the USA
|
a publicly available technology and software, and is freely distributed
|
||||||
PATRIOT Act and the Enhanced Border Security and Visa Entry Reform Act.
|
to any interested party with no licensing requirements. Therefore, it is
|
||||||
Specific hardware and software products identified in this software were used
|
permissible to distribute this software as a free download from the internet.
|
||||||
in order to perform the software development. In no case does such
|
|
||||||
identification imply recommendation or endorsement by the National Institute
|
Disclaimer:
|
||||||
of Standards and Technology, nor does it imply that the products and equipment
|
This software and/or related materials was developed to promote biometric
|
||||||
identified are necessarily the best available for the purpose.
|
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.
|
||||||
|
|
||||||
|
This software and/or related materials are provided "AS-IS" without warranty
|
||||||
|
of any kind including NO WARRANTY OF PERFORMANCE, MERCHANTABILITY,
|
||||||
|
NO WARRANTY OF NON-INFRINGEMENT OF ANY 3RD PARTY INTELLECTUAL PROPERTY
|
||||||
|
or FITNESS FOR A PARTICULAR PURPOSE or for any purpose whatsoever, for the
|
||||||
|
licensed product, however used. In no event shall NIST be liable for any
|
||||||
|
damages and/or costs, including but not limited to incidental or consequential
|
||||||
|
damages of any kind, including economic damage or injury to property and lost
|
||||||
|
profits, regardless of whether NIST shall be advised, have reason to know,
|
||||||
|
or in fact shall know of the possibility.
|
||||||
|
|
||||||
|
By using this software, you agree to bear all risk relating to quality,
|
||||||
|
use and performance of the software and/or related materials. You agree
|
||||||
|
to hold the Government harmless from any claim arising from your use
|
||||||
|
of the software.
|
||||||
|
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
LIBRARY: LFS - NIST Latent Fingerprint System
|
LIBRARY: LFS - NIST Latent Fingerprint System
|
||||||
|
|
||||||
|
@ -36,12 +57,12 @@ identified are necessarily the best available for the purpose.
|
||||||
ROUTINES:
|
ROUTINES:
|
||||||
alloc_shape()
|
alloc_shape()
|
||||||
free_shape()
|
free_shape()
|
||||||
|
dump_shape()
|
||||||
shape_from_contour()
|
shape_from_contour()
|
||||||
sort_row_on_x()
|
sort_row_on_x()
|
||||||
***********************************************************************/
|
***********************************************************************/
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
|
||||||
#include <lfs.h>
|
#include <lfs.h>
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
|
@ -60,7 +81,7 @@ identified are necessarily the best available for the purpose.
|
||||||
Zero - Shape successfully allocated and initialized
|
Zero - Shape successfully allocated and initialized
|
||||||
Negative - System error
|
Negative - System error
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
static int alloc_shape(SHAPE **oshape, const int xmin, const int ymin,
|
int alloc_shape(SHAPE **oshape, const int xmin, const int ymin,
|
||||||
const int xmax, const int ymax)
|
const int xmax, const int ymax)
|
||||||
{
|
{
|
||||||
SHAPE *shape;
|
SHAPE *shape;
|
||||||
|
@ -180,21 +201,14 @@ void free_shape(SHAPE *shape)
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
**************************************************************************
|
**************************************************************************
|
||||||
#cat: sort_row_on_x - Takes a row structure and sorts its points left-to-
|
#cat: dump_shape - Takes an initialized shape structure and dumps its contents
|
||||||
#cat: right on X.
|
#cat: as formatted text to the specified open file pointer.
|
||||||
|
|
||||||
Input:
|
Input:
|
||||||
row - row structure to be sorted
|
shape - shape structure to be dumped
|
||||||
Output:
|
Output:
|
||||||
row - row structure with points in sorted order
|
fpout - open file pointer to be written to
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
static void sort_row_on_x(ROW *row)
|
|
||||||
{
|
|
||||||
/* Conduct a simple increasing bubble sort on the x-coords */
|
|
||||||
/* in the given row. A bubble sort is satisfactory as the */
|
|
||||||
/* number of points will be relatively small. */
|
|
||||||
bubble_sort_int_inc(row->xs, row->npts);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
**************************************************************************
|
**************************************************************************
|
||||||
|
@ -270,3 +284,21 @@ int shape_from_contour(SHAPE **oshape, const int *contour_x,
|
||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
#cat: sort_row_on_x - Takes a row structure and sorts its points left-to-
|
||||||
|
#cat: right on X.
|
||||||
|
|
||||||
|
Input:
|
||||||
|
row - row structure to be sorted
|
||||||
|
Output:
|
||||||
|
row - row structure with points in sorted order
|
||||||
|
**************************************************************************/
|
||||||
|
void sort_row_on_x(ROW *row)
|
||||||
|
{
|
||||||
|
/* Conduct a simple increasing bubble sort on the x-coords */
|
||||||
|
/* in the given row. A bubble sort is satisfactory as the */
|
||||||
|
/* number of points will be relatively small. */
|
||||||
|
bubble_sort_int_inc(row->xs, row->npts);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,26 +1,47 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
|
|
||||||
License:
|
License:
|
||||||
This software was developed at the National Institute of Standards and
|
This software and/or related materials was developed at the National Institute
|
||||||
Technology (NIST) by employees of the Federal Government in the course
|
of Standards and Technology (NIST) by employees of the Federal Government
|
||||||
of their official duties. Pursuant to title 17 Section 105 of the
|
in the course of their official duties. Pursuant to title 17 Section 105
|
||||||
United States Code, this software is not subject to copyright protection
|
of the United States Code, this software is not subject to copyright
|
||||||
and is in the public domain. NIST assumes no responsibility whatsoever for
|
protection and is in the public domain.
|
||||||
its use by other parties, and makes no guarantees, expressed or implied,
|
|
||||||
about its quality, reliability, or any other characteristic.
|
|
||||||
|
|
||||||
Disclaimer:
|
This software and/or related materials have been determined to be not subject
|
||||||
This software was developed to promote biometric standards and biometric
|
to the EAR (see Part 734.3 of the EAR for exact details) because it is
|
||||||
technology testing for the Federal Government in accordance with the USA
|
a publicly available technology and software, and is freely distributed
|
||||||
PATRIOT Act and the Enhanced Border Security and Visa Entry Reform Act.
|
to any interested party with no licensing requirements. Therefore, it is
|
||||||
Specific hardware and software products identified in this software were used
|
permissible to distribute this software as a free download from the internet.
|
||||||
in order to perform the software development. In no case does such
|
|
||||||
identification imply recommendation or endorsement by the National Institute
|
Disclaimer:
|
||||||
of Standards and Technology, nor does it imply that the products and equipment
|
This software and/or related materials was developed to promote biometric
|
||||||
identified are necessarily the best available for the purpose.
|
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.
|
||||||
|
|
||||||
|
This software and/or related materials are provided "AS-IS" without warranty
|
||||||
|
of any kind including NO WARRANTY OF PERFORMANCE, MERCHANTABILITY,
|
||||||
|
NO WARRANTY OF NON-INFRINGEMENT OF ANY 3RD PARTY INTELLECTUAL PROPERTY
|
||||||
|
or FITNESS FOR A PARTICULAR PURPOSE or for any purpose whatsoever, for the
|
||||||
|
licensed product, however used. In no event shall NIST be liable for any
|
||||||
|
damages and/or costs, including but not limited to incidental or consequential
|
||||||
|
damages of any kind, including economic damage or injury to property and lost
|
||||||
|
profits, regardless of whether NIST shall be advised, have reason to know,
|
||||||
|
or in fact shall know of the possibility.
|
||||||
|
|
||||||
|
By using this software, you agree to bear all risk relating to quality,
|
||||||
|
use and performance of the software and/or related materials. You agree
|
||||||
|
to hold the Government harmless from any claim arising from your use
|
||||||
|
of the software.
|
||||||
|
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
LIBRARY: LFS - NIST Latent Fingerprint System
|
LIBRARY: LFS - NIST Latent Fingerprint System
|
||||||
|
|
||||||
|
@ -43,7 +64,6 @@ identified are necessarily the best available for the purpose.
|
||||||
***********************************************************************/
|
***********************************************************************/
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
|
||||||
#include <lfs.h>
|
#include <lfs.h>
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
|
@ -104,29 +124,6 @@ int sort_indices_int_inc(int **optr, int *ranks, const int num)
|
||||||
Zero - successful completion
|
Zero - successful completion
|
||||||
Negative - system error
|
Negative - system error
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
int sort_indices_double_inc(int **optr, double *ranks, const int num)
|
|
||||||
{
|
|
||||||
int *order;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
/* Allocate list of sequential indices. */
|
|
||||||
order = (int *)malloc(num * sizeof(int));
|
|
||||||
if(order == (int *)NULL){
|
|
||||||
fprintf(stderr, "ERROR : sort_indices_double_inc : malloc : order\n");
|
|
||||||
return(-400);
|
|
||||||
}
|
|
||||||
/* Initialize list of sequential indices. */
|
|
||||||
for(i = 0; i < num; i++)
|
|
||||||
order[i] = i;
|
|
||||||
|
|
||||||
/* Sort the indicies into rank order. */
|
|
||||||
bubble_sort_double_inc_2(ranks, order, num);
|
|
||||||
|
|
||||||
/* Set output pointer to the resulting order of sorted indices. */
|
|
||||||
*optr = order;
|
|
||||||
/* Return normally. */
|
|
||||||
return(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
**************************************************************************
|
**************************************************************************
|
||||||
|
@ -176,7 +173,7 @@ void bubble_sort_int_inc_2(int *ranks, int *items, const int len)
|
||||||
}
|
}
|
||||||
/* Decrement the ending index. */
|
/* Decrement the ending index. */
|
||||||
n--;
|
n--;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
|
@ -228,7 +225,7 @@ void bubble_sort_double_inc_2(double *ranks, int *items, const int len)
|
||||||
}
|
}
|
||||||
/* Decrement the ending index. */
|
/* Decrement the ending index. */
|
||||||
n--;
|
n--;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/***************************************************************************
|
/***************************************************************************
|
||||||
|
@ -271,7 +268,7 @@ void bubble_sort_double_dec_2(double *ranks, int *items, const int len)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
n--;
|
n--;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
|
@ -315,6 +312,6 @@ void bubble_sort_int_inc(int *ranks, const int len)
|
||||||
}
|
}
|
||||||
/* Decrement the ending index. */
|
/* Decrement the ending index. */
|
||||||
n--;
|
n--;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,26 +1,47 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
|
|
||||||
License:
|
License:
|
||||||
This software was developed at the National Institute of Standards and
|
This software and/or related materials was developed at the National Institute
|
||||||
Technology (NIST) by employees of the Federal Government in the course
|
of Standards and Technology (NIST) by employees of the Federal Government
|
||||||
of their official duties. Pursuant to title 17 Section 105 of the
|
in the course of their official duties. Pursuant to title 17 Section 105
|
||||||
United States Code, this software is not subject to copyright protection
|
of the United States Code, this software is not subject to copyright
|
||||||
and is in the public domain. NIST assumes no responsibility whatsoever for
|
protection and is in the public domain.
|
||||||
its use by other parties, and makes no guarantees, expressed or implied,
|
|
||||||
about its quality, reliability, or any other characteristic.
|
|
||||||
|
|
||||||
Disclaimer:
|
This software and/or related materials have been determined to be not subject
|
||||||
This software was developed to promote biometric standards and biometric
|
to the EAR (see Part 734.3 of the EAR for exact details) because it is
|
||||||
technology testing for the Federal Government in accordance with the USA
|
a publicly available technology and software, and is freely distributed
|
||||||
PATRIOT Act and the Enhanced Border Security and Visa Entry Reform Act.
|
to any interested party with no licensing requirements. Therefore, it is
|
||||||
Specific hardware and software products identified in this software were used
|
permissible to distribute this software as a free download from the internet.
|
||||||
in order to perform the software development. In no case does such
|
|
||||||
identification imply recommendation or endorsement by the National Institute
|
Disclaimer:
|
||||||
of Standards and Technology, nor does it imply that the products and equipment
|
This software and/or related materials was developed to promote biometric
|
||||||
identified are necessarily the best available for the purpose.
|
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.
|
||||||
|
|
||||||
|
This software and/or related materials are provided "AS-IS" without warranty
|
||||||
|
of any kind including NO WARRANTY OF PERFORMANCE, MERCHANTABILITY,
|
||||||
|
NO WARRANTY OF NON-INFRINGEMENT OF ANY 3RD PARTY INTELLECTUAL PROPERTY
|
||||||
|
or FITNESS FOR A PARTICULAR PURPOSE or for any purpose whatsoever, for the
|
||||||
|
licensed product, however used. In no event shall NIST be liable for any
|
||||||
|
damages and/or costs, including but not limited to incidental or consequential
|
||||||
|
damages of any kind, including economic damage or injury to property and lost
|
||||||
|
profits, regardless of whether NIST shall be advised, have reason to know,
|
||||||
|
or in fact shall know of the possibility.
|
||||||
|
|
||||||
|
By using this software, you agree to bear all risk relating to quality,
|
||||||
|
use and performance of the software and/or related materials. You agree
|
||||||
|
to hold the Government harmless from any claim arising from your use
|
||||||
|
of the software.
|
||||||
|
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
LIBRARY: LFS - NIST Latent Fingerprint System
|
LIBRARY: LFS - NIST Latent Fingerprint System
|
||||||
|
|
||||||
|
@ -47,7 +68,6 @@ identified are necessarily the best available for the purpose.
|
||||||
***********************************************************************/
|
***********************************************************************/
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
|
||||||
#include <lfs.h>
|
#include <lfs.h>
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
|
@ -142,7 +162,7 @@ int minmaxs(int **ominmax_val, int **ominmax_type, int **ominmax_i,
|
||||||
int i, diff, state, start, loc;
|
int i, diff, state, start, loc;
|
||||||
int *minmax_val, *minmax_type, *minmax_i, minmax_alloc, minmax_num;
|
int *minmax_val, *minmax_type, *minmax_i, minmax_alloc, minmax_num;
|
||||||
|
|
||||||
|
|
||||||
/* Determine maximum length for allocation of buffers. */
|
/* Determine maximum length for allocation of buffers. */
|
||||||
/* If there are fewer than 3 items ... */
|
/* If there are fewer than 3 items ... */
|
||||||
if(num < 3){
|
if(num < 3){
|
||||||
|
@ -427,27 +447,6 @@ int in_int_list(const int item, const int *list, const int len)
|
||||||
Zero - successful completion
|
Zero - successful completion
|
||||||
Negative - system error
|
Negative - system error
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
int remove_from_int_list(const int index, int *list, const int num)
|
|
||||||
{
|
|
||||||
int fr, to;
|
|
||||||
|
|
||||||
/* Make sure the requested index is within range. */
|
|
||||||
if((index < 0) && (index >= num)){
|
|
||||||
fprintf(stderr, "ERROR : remove_from_int_list : index out of range\n");
|
|
||||||
return(-370);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Slide the remaining list of integers up over top of the */
|
|
||||||
/* position of the integer being removed. */
|
|
||||||
for(to = index, fr = index+1; fr < num; to++, fr++)
|
|
||||||
list[to] = list[fr];
|
|
||||||
|
|
||||||
/* NOTE: Decrementing the number of integers remaining in the list is */
|
|
||||||
/* the responsibility of the caller! */
|
|
||||||
|
|
||||||
/* Return normally. */
|
|
||||||
return(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
**************************************************************************
|
**************************************************************************
|
||||||
|
@ -561,7 +560,7 @@ int line2direction(const int fx, const int fy,
|
||||||
/* Make sure on range [0..(ndirsX2)]. */
|
/* Make sure on range [0..(ndirsX2)]. */
|
||||||
idir %= full_ndirs;
|
idir %= full_ndirs;
|
||||||
|
|
||||||
/* Return the integer direction. */
|
/* Return the integer direction. */
|
||||||
return(idir);
|
return(idir);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
136
libfprint/nbis/mindtct/xytreps.c
Normal file
136
libfprint/nbis/mindtct/xytreps.c
Normal file
|
@ -0,0 +1,136 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
|
||||||
|
License:
|
||||||
|
This software and/or related materials 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.
|
||||||
|
|
||||||
|
This software and/or related materials have been determined to be not subject
|
||||||
|
to the EAR (see Part 734.3 of the EAR for exact details) because it is
|
||||||
|
a publicly available technology and software, and is freely distributed
|
||||||
|
to any interested party with no licensing requirements. Therefore, it is
|
||||||
|
permissible to distribute this software as a free download from the internet.
|
||||||
|
|
||||||
|
Disclaimer:
|
||||||
|
This software and/or related materials 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.
|
||||||
|
|
||||||
|
This software and/or related materials are provided "AS-IS" without warranty
|
||||||
|
of any kind including NO WARRANTY OF PERFORMANCE, MERCHANTABILITY,
|
||||||
|
NO WARRANTY OF NON-INFRINGEMENT OF ANY 3RD PARTY INTELLECTUAL PROPERTY
|
||||||
|
or FITNESS FOR A PARTICULAR PURPOSE or for any purpose whatsoever, for the
|
||||||
|
licensed product, however used. In no event shall NIST be liable for any
|
||||||
|
damages and/or costs, including but not limited to incidental or consequential
|
||||||
|
damages of any kind, including economic damage or injury to property and lost
|
||||||
|
profits, regardless of whether NIST shall be advised, have reason to know,
|
||||||
|
or in fact shall know of the possibility.
|
||||||
|
|
||||||
|
By using this software, you agree to bear all risk relating to quality,
|
||||||
|
use and performance of the software and/or related materials. You agree
|
||||||
|
to hold the Government harmless from any claim arising from your use
|
||||||
|
of the software.
|
||||||
|
|
||||||
|
*******************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
LIBRARY: LFS - NIST Latent Fingerprint System
|
||||||
|
|
||||||
|
FILE: XYTREPS.C
|
||||||
|
AUTHOR: Michael D. Garris
|
||||||
|
DATE: 09/16/2004
|
||||||
|
UPDATED: 01/11/2012
|
||||||
|
|
||||||
|
Contains routines useful in converting minutiae in LFS "native"
|
||||||
|
representation into other representations, such as
|
||||||
|
M1 (ANSI INCITS 378-2004) & NIST internal representations.
|
||||||
|
|
||||||
|
***********************************************************************
|
||||||
|
ROUTINES:
|
||||||
|
lfs2nist_minutia_XTY()
|
||||||
|
lfs2m1_minutia_XTY()
|
||||||
|
lfs2nist_format()
|
||||||
|
|
||||||
|
***********************************************************************/
|
||||||
|
|
||||||
|
#include <lfs.h>
|
||||||
|
#include <defs.h>
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
#cat: lfs2nist_minutia_XYT - Converts XYT minutiae attributes in LFS native
|
||||||
|
#cat: representation to NIST internal representation
|
||||||
|
|
||||||
|
Input:
|
||||||
|
minutia - LFS minutia structure containing attributes to be converted
|
||||||
|
Output:
|
||||||
|
ox - NIST internal based x-pixel coordinate
|
||||||
|
oy - NIST internal based y-pixel coordinate
|
||||||
|
ot - NIST internal based minutia direction/orientation
|
||||||
|
**************************************************************************/
|
||||||
|
void lfs2nist_minutia_XYT(int *ox, int *oy, int *ot,
|
||||||
|
const MINUTIA *minutia, const int iw, const int ih)
|
||||||
|
{
|
||||||
|
int x, y, t;
|
||||||
|
float degrees_per_unit;
|
||||||
|
|
||||||
|
/* XYT's according to NIST internal rep: */
|
||||||
|
/* 1. pixel coordinates with origin bottom-left */
|
||||||
|
/* 2. orientation in degrees on range [0..360] */
|
||||||
|
/* with 0 pointing east and increasing counter */
|
||||||
|
/* clockwise (same as M1) */
|
||||||
|
/* 3. direction pointing out and away from the */
|
||||||
|
/* ridge ending or bifurcation valley */
|
||||||
|
/* (opposite direction from M1) */
|
||||||
|
|
||||||
|
x = minutia->x;
|
||||||
|
y = ih - minutia->y;
|
||||||
|
|
||||||
|
degrees_per_unit = 180 / (float)NUM_DIRECTIONS;
|
||||||
|
|
||||||
|
t = (270 - sround(minutia->direction * degrees_per_unit)) % 360;
|
||||||
|
if(t < 0){
|
||||||
|
t += 360;
|
||||||
|
}
|
||||||
|
|
||||||
|
*ox = x;
|
||||||
|
*oy = y;
|
||||||
|
*ot = t;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
#cat: lfs2m1_minutia_XYT - Converts XYT minutiae attributes in LFS native
|
||||||
|
#cat: representation to M1 (ANSI INCITS 378-2004) representation
|
||||||
|
|
||||||
|
Input:
|
||||||
|
minutia - LFS minutia structure containing attributes to be converted
|
||||||
|
Output:
|
||||||
|
ox - M1 based x-pixel coordinate
|
||||||
|
oy - M1 based y-pixel coordinate
|
||||||
|
ot - M1 based minutia direction/orientation
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
#cat: lfs2nist_format - Takes a minutiae data structure and converts
|
||||||
|
#cat: the XYT minutiae attributes in LFS native
|
||||||
|
#cat: representation to NIST internal representation
|
||||||
|
Input:
|
||||||
|
iminutiae - minutiae data structure
|
||||||
|
iw - width (in pixels) of the grayscale image
|
||||||
|
ih - height (in pixels) of the grayscale image
|
||||||
|
Output:
|
||||||
|
iminutiae - overwrite each minutia element in the minutiae data
|
||||||
|
sturcture convernt to nist internal minutiae format
|
||||||
|
**************************************************************************/
|
||||||
|
|
Loading…
Reference in a new issue