コード例 #1
0
ファイル: img.c プロジェクト: FabriceSalvaire/libfprint-baspi
/** \ingroup img
 * Frees an image. Must be called when you are finished working with an image.
 * \param img the image to destroy. If NULL, function simply returns.
 */
API_EXPORTED void fp_img_free(struct fp_img *img)
{
	if (!img)
		return;

	if (img->minutiae)
		free_minutiae(img->minutiae);
	if (img->binarized)
		free(img->binarized);
	g_free(img);
}
コード例 #2
0
ファイル: detect.c プロジェクト: Booley/nbis
/*************************************************************************
#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
**************************************************************************/
int lfs_detect_minutiae(MINUTIAE **ominutiae,
                        int **oimap, int **onmap, int *omw, int *omh,
                        unsigned char **obdata, int *obw, int *obh,
                        unsigned char *idata, const int iw, const int ih,
                        const LFSPARMS *lfsparms)
{
   unsigned char *pdata, *bdata;
   int pw, ph, bw, bh;
   DIR2RAD *dir2rad;
   DFTWAVES *dftwaves;
   ROTGRIDS *dftgrids;
   ROTGRIDS *dirbingrids;
   int *imap, *nmap, mw, mh;
   int ret, maxpad;
   MINUTIAE *minutiae;

   set_timer(total_timer);

   /******************/
   /* INITIALIZATION */
   /******************/

   /* If LOG_REPORT defined, open log report file. */
   if((ret = open_logfile()))
      /* If system error, exit with error code. */
      return(ret);

   /* Determine the maximum amount of image padding required to support */
   /* LFS processes.                                                    */
   maxpad = get_max_padding(lfsparms->blocksize,
                            lfsparms->dirbin_grid_w, lfsparms->dirbin_grid_h,
                            lfsparms->isobin_grid_dim);

   /* Initialize lookup table for converting integer IMAP directions */
   /* to angles in radians.                                          */
   if((ret = init_dir2rad(&dir2rad, lfsparms->num_directions))){
      /* Free memory allocated to this point. */
      return(ret);
   }

   /* Initialize wave form lookup tables for DFT analyses. */
   /* used for direction binarization.                             */
   if((ret = init_dftwaves(&dftwaves, dft_coefs, lfsparms->num_dft_waves,
                        lfsparms->blocksize))){
      /* Free memory allocated to this point. */
      free_dir2rad(dir2rad);
      return(ret);
   }

   /* Initialize lookup table for pixel offsets to rotated grids */
   /* used for DFT analyses.                                     */
   if((ret = init_rotgrids(&dftgrids, iw, ih, maxpad,
                        lfsparms->start_dir_angle, lfsparms->num_directions,
                        lfsparms->blocksize, lfsparms->blocksize,
                        RELATIVE2ORIGIN))){
      /* Free memory allocated to this point. */
      free_dir2rad(dir2rad);
      free_dftwaves(dftwaves);
      return(ret);
   }

   /* Pad input image based on max padding. */
   if(maxpad > 0){   /* May not need to pad at all */
      if((ret = pad_uchar_image(&pdata, &pw, &ph, idata, iw, ih,
                             maxpad, lfsparms->pad_value))){
         /* Free memory allocated to this point. */
         free_dir2rad(dir2rad);
         free_dftwaves(dftwaves);
         free_rotgrids(dftgrids);
         return(ret);
      }
   }
   else{
      /* If padding is unnecessary, then copy the input image. */
      pdata = (unsigned char *)malloc(iw*ih);
      if(pdata == (unsigned char *)NULL){
         /* Free memory allocated to this point. */
         free_dir2rad(dir2rad);
         free_dftwaves(dftwaves);
         free_rotgrids(dftgrids);
         fprintf(stderr, "ERROR : lfs_detect_minutiae : malloc : pdata\n");
         return(-430);
      }
      memcpy(pdata, idata, iw*ih);
      pw = iw;
      ph = ih;
   }

   /* Scale input image to 6 bits [0..63] */
   /* !!! Would like to remove this dependency eventualy !!! */
   /* But, the DFT computations will need to be changed, and */
   /* could not get this work upon first attempt.            */
   bits_8to6(pdata, pw, ph);

   print2log("\nINITIALIZATION AND PADDING DONE\n");

   /******************/
   /*      IMAP      */
   /******************/
   set_timer(imap_timer);

   /* Generate IMAP for the input image. */
   if((ret = gen_imap(&imap, &mw, &mh, pdata, pw, ph, dir2rad,
                   dftwaves, dftgrids, lfsparms))){
      /* Free memory allocated to this point. */
      free_dir2rad(dir2rad);
      free_dftwaves(dftwaves);
      free_rotgrids(dftgrids);
      free(pdata);
      return(ret);
   }

   free_dir2rad(dir2rad);
   free_dftwaves(dftwaves);
   free_rotgrids(dftgrids);

   print2log("\nIMAP DONE\n");

   /* Generate NMAP from the IMAP of the input image. */
   if((ret = gen_nmap(&nmap, imap, mw, mh, lfsparms))){
      /* Free memory allocated to this point. */
      free(pdata);
      free(imap);
      return(ret);
   }

   print2log("\nNMAP DONE\n");

   time_accum(imap_timer, imap_time);

   /******************/
   /* BINARIZARION   */
   /******************/
   set_timer(bin_timer);

   /* Initialize lookup table for pixel offsets to rotated grids */
   /* used for directional binarization.                         */
   if((ret = init_rotgrids(&dirbingrids, iw, ih, maxpad,
                        lfsparms->start_dir_angle, lfsparms->num_directions,
                        lfsparms->dirbin_grid_w, lfsparms->dirbin_grid_h,
                        RELATIVE2CENTER))){
      /* Free memory allocated to this point. */
      free(pdata);
      free(imap);
      free(nmap);
      return(ret);
   }

   /* Binarize input image based on NMAP information. */
   if((ret = binarize(&bdata, &bw, &bh, pdata, pw, ph, nmap, mw, mh,
                   dirbingrids, lfsparms))){
      /* Free memory allocated to this point. */
      free(pdata);
      free(imap);
      free(nmap);
      free_rotgrids(dirbingrids);
      return(ret);
   }
   free_rotgrids(dirbingrids);

   /* Check dimension of binary image.  If they are different from */
   /* the input image, then ERROR.                                 */
   if((iw != bw) || (ih != bh)){
      /* Free memory allocated to this point. */
      free(pdata);
      free(imap);
      free(nmap);
      free(bdata);
      fprintf(stderr,
   "ERROR : lfs_detect_minutiae : binary image has bad dimensions : %d, %d\n",
              bw, bh);
      return(-431);
   }

   print2log("\nBINARIZATION DONE\n");

   time_accum(bin_timer, bin_time);

   /******************/
   /*   DETECTION    */
   /******************/
   set_timer(minutia_timer);

   /* Convert 8-bit grayscale binary image [0,255] to */
   /* 8-bit binary image [0,1].                       */
   gray2bin(1, 1, 0, bdata, iw, ih);

   /* Allocate list of maximum number of minutia pointers. */
   if((ret = alloc_minutiae(&minutiae, MAX_MINUTIAE))){
      return(ret);
   }

   /* Detect the minutiae in the binarized image. */
   if((ret = detect_minutiae(minutiae, bdata, iw, ih, imap, nmap, mw, mh,
                          lfsparms))){
      /* Free memory allocated to this point. */
      free(pdata);
      free(imap);
      free(nmap);
      free(bdata);
      return(ret);
   }

   time_accum(minutia_timer, minutia_time);

   set_timer(rm_minutia_timer);

   if((ret = remove_false_minutia(minutiae, bdata, iw, ih, nmap, mw, mh,
                               lfsparms))){
      /* Free memory allocated to this point. */
      free(pdata);
      free(imap);
      free(nmap);
      free(bdata);
      free_minutiae(minutiae);
      return(ret);
   }

   print2log("\nMINUTIA DETECTION DONE\n");

   time_accum(rm_minutia_timer, rm_minutia_time);

   /******************/
   /*  RIDGE COUNTS  */
   /******************/
   set_timer(ridge_count_timer);

   if((ret = count_minutiae_ridges(minutiae, bdata, iw, ih, lfsparms))){
      /* Free memory allocated to this point. */
      free(pdata);
      free(imap);
      free(nmap);
      free(bdata);
      free_minutiae(minutiae);
      return(ret);
   }


   print2log("\nNEIGHBOR RIDGE COUNT DONE\n");

   time_accum(ridge_count_timer, ridge_count_time);

   /******************/
   /*    WRAP-UP     */
   /******************/

   /* Convert 8-bit binary image [0,1] to 8-bit */
   /* grayscale binary image [0,255].           */
   gray2bin(1, 255, 0, bdata, iw, ih);

   /* Deallocate working memory. */
   free(pdata);

   /* Assign results to output pointers. */
   *oimap = imap;
   *onmap = nmap;
   *omw = mw;
   *omh = mh;
   *obdata = bdata;
   *obw = bw;
   *obh = bh;
   *ominutiae = minutiae;

   time_accum(total_timer, total_time);

   /******************/
   /* PRINT TIMINGS  */
   /******************/
   /* These Timings will print when TIMER is defined. */
   /* print IMAP generation timing statistics */
   print_time(stderr, "TIMER: IMAP 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((ret = close_logfile()))
      return(ret);

   return(0);
}