📄 feret_neighbor.c
字号:
/*--------------------------------------------------------------- PROGRAM : neighbor.c DATE : 8/3/94 AUTHOR : Wasiuddin Wahid, wasi@media.mit.edu ______________________________________________________________ PROGRAM DESCRIPTION HERE ---------------------------------------------------------------*/#include <stdio.h>#include <stdlib.h>#include <string.h>#include <math.h>#define OPTIONS "m:x:k:l:o:n:t:w:u:c:a:b:f"#define MAX_CHARS 256char *usage = "\t-m dir_known_faces -x dir_test_faces\n\t\\t\t-k list_known_faces -l list_test_faces\n\t\\t\t-o output_file -t threshold -w weights\n\t\\t\t-u biases [-c conf] [-n top_n_matches] [-a lower coeff]\n\t\\t\t[-b upper coeff] -f [read on fs of Probe]";char *help = " Nearest Neighbor Pattern Matching\n-m dir_known_faces \t directory of known faces \n\-x dir_test_faces \t directory of test faces \n\-k list_known_faces \t list file of known faces \n\-l list_test_faces \t list file of test faces\n\-o output_file \t output file\n\-n top_n_matches \t print out top N matches only(default 10) \n\-t threshold \t found flag threshold\n\-w weights \t weights file\n\-u biases \t bias file\n\-c conf \t confidence factor (default: 1000)\n\-a lower coeff \t lower coefficient (default: first)\n\-b upper coeff \t upper coefficient (default: last)\n\-f \t read only fs of Probe\n\n";extern int optind;extern char *optarg;/*------- command line defaults ------- */float conf_factor = 1e3;/* ---------------------DEFINITIONS OF STRUCTURES------------------------*//* A tface(test_face) consists of the name of the file containing the test face and a pointer to the structure "match". A match is a structure containing the name of the file to which the test_face is similar, the distance from that face and a pointer to the next matched face A kface(known_face) on the other hand is a structure containing it's name and four float arrays for the four sets of coefficients f, q, h and p. A test is basically a structure containing four float arrays for the four set of coefficients f, q, h and p. These are for storing the coefficients for each test_face as you read them in one at a time. -------------------------------------------------------------------------*/typedef struct match *Matchptr;typedef struct match { char *name; float distance; Matchptr next;} Match;typedef struct tface{ char *name; Matchptr similar;} Tface;typedef struct kface{ char *name; float *fcoeffs; float *qcoeffs; float *hcoeffs; float *pcoeffs;} Kface;typedef struct test{ float *fcoeffs; float *qcoeffs; float *hcoeffs; float *pcoeffs;} Test;int number_files(char list[]);Matchptr add_match(Matchptr root, Matchptr new, int n);float find_distance(float *test, float *known, int no);int number_points(char descriptor[]);void read_gcoeffs(char dir[], char list[], int no_points, Kface *kfaces);void read_pcoeffs(char dir[], char line[], Test artest, int no_points, int f_flag);void read_weights(char weight_file[], float *weights);void print_match(Tface *faces, int n,int no_files, char out[], float thres, char comline[]);int print_file(Tface faces, int n, FILE *fout, float thres, int count);void kill_list(Matchptr list);int empty_list(Matchptr list);/* char *strdup(char *s); *//*---------------------------- MAIN ----------------------------------*/main(int argc, char **argv){ int no_files, no_kfiles, no_points, file_no, point, i, c, n=10, rec, a=1, b=0, slength, interval, k, j, count =0; char *progname, comline[MAX_CHARS], ktype, ttype; char known_dir[MAX_CHARS]; char test_dir[MAX_CHARS]; char klist[MAX_CHARS]; char tlist[MAX_CHARS]; char out_file[MAX_CHARS]; char line[MAX_CHARS]; char kfile[MAX_CHARS]; char tfile[MAX_CHARS]; char the_kfile[MAX_CHARS]; char descriptor[MAX_CHARS]; char weight_file[MAX_CHARS]; char bias_file[MAX_CHARS]; FILE *fknown, *ftest, *ftlist, *fklist, *fp, *fout; Tface tfaces; Kface *kfaces; Test artest; Matchptr a_match; float a_point, dist, thres, weights[16], weight, biases[16]; /* These are to use the read_descriptor in Baback's files */ int nframe, sets, bytes_pixel, ydim; /* Required Input flags */ int errflag = 0; int inflag = 0; int testflag = 0; int kflag = 0; int tflag = 0; int outflag = 0; int nflag = 0; int thresflag = 0; int weight_flag = 0; int bias_flag = 0; int f_flag = 0; progname = argv[0]; for (i=0; i<argc; i++){ strcat(comline, argv[i]), strcat(comline, " "); } while ( (c = getopt(argc, argv, OPTIONS)) != EOF) switch(c){ case 'm': strcpy(known_dir, optarg); inflag = 1; break; case 'x': strcpy(test_dir, optarg); testflag = 1; break; case 'k': strcpy(klist, optarg); kflag = 1; break; case 'l': strcpy(tlist, optarg); tflag = 1; break; case 'o': strcpy(out_file, optarg); outflag = 1; break; case 'n': n = atoi(optarg); nflag = 1; break; case 't': thres = atof(optarg); thresflag = 1; break; case 'w': strcpy(weight_file, optarg); weight_flag = 1; break; case 'u': strcpy(bias_file, optarg); bias_flag = 1; break; case 'c': conf_factor = atof(optarg); break; case 'a': a = atoi(optarg); break; case 'b': b = atoi(optarg); break; case 'f': f_flag = 1; break; case '?': errflag = 1; break; } /* switch (c){ */ /* Command line check */ if (errflag || !inflag || !testflag || !thresflag || !kflag || !tflag || !outflag || !weight_flag || !bias_flag){ fprintf(stderr, "\nUSAGE: %s %s\n %s\n\n", progname, usage, help); exit(1); } /* Calculate the no. of test and known faces and allocate memory for the arrays to store them */ no_files = number_files(tlist); no_kfiles = number_files(klist); /* Wasi's Mistake: kfaces = (Kface *) calloc(no_files, sizeof(Kface)); */ /* ----- baback's fix -------- */ kfaces = (Kface *) calloc(no_kfiles, sizeof(Kface)); if (kfaces == NULL){ fprintf(stderr, "\nERROR: Memory for kfaces cannot be allocated: \n\n"); exit(3); } /* Calculate the total no. of coefficients */ sprintf(descriptor, "%s/f", test_dir); read_descriptor(descriptor, &nframe, &sets, &bytes_pixel,&ydim, &no_points); /* Read in the weights and biases from the appropriate files */ read_weights(weight_file, weights); read_weights(bias_file, biases); /* Read in the no of coefficients for gallery */ read_gcoeffs(known_dir, klist, no_points, kfaces); if ( (ftlist = fopen(tlist, "r")) == NULL) { fprintf(stderr, "\nERROR: Input file %s cannot be opened\n\n", tlist); fprintf(stderr, "\nThis should be the list file for the Probe faces\n\n"); exit(2); } /* the interval relevant in the distance calculation is */ /* difference between a & b */ if (!b){ b = no_points; } interval = b - a + 1; a = a - 1; if (no_kfiles < n){ n = no_kfiles; } if ( (fout = fopen(out_file, "w")) == NULL){ fprintf(stderr, "\nERROR: output file %s cannot be opened\n", out_file); fprintf(stderr, "This is the output file to which results are to be written\n"); exit(2); } fprintf(stderr, "Command line : %s \n\n", comline); fprintf(fout, "Command Line: %s\n\n", comline); fprintf(fout, "<Probe number> <Match order> <Gallery Match Number> <Found Flag> <Confidence>\n\n"); file_no = 0; /* Loop over the input file list and calculate the nearest neigbors */ while ( (fscanf(ftlist, "%s", line)) != EOF){ if ( (strncmp(line, "#", 1) != 0) && strlen(line) > 1) { /* Read in coeffs in the appropriate positions */ artest.fcoeffs = (float *) calloc(no_points, sizeof(float)); artest.qcoeffs = (float *) calloc(no_points, sizeof(float)); artest.hcoeffs = (float *) calloc(no_points, sizeof(float)); artest.pcoeffs = (float *) calloc(no_points, sizeof(float)); if ( (artest.fcoeffs == NULL) || (artest.qcoeffs == NULL) || (artest.hcoeffs == NULL) || (artest.pcoeffs == NULL)){ fprintf(stderr, "\nERROR: memory cannot be allocated for artest"); exit(3); } read_pcoeffs(test_dir, line, artest, no_points, f_flag); tfaces.name = strdup(line); tfaces.similar = NULL; fprintf(stdout, "Matching probe: %s\n", line); /* find out what type of face it is: f, q, h or p */ slength = strlen(line); for (k=0; k<slength; k++){ if ( (line[k] >= 'a') && (line[k] <= 'z') ){ ttype = line[k]; break; } } /* loop through the array of Kfaces finding the nearest neighbor */ for (i=0; i < no_kfiles; i++){ /* find the type of known face */ slength = strlen( kfaces[i].name); for (k=0; k<slength; k++){ if ( (kfaces[i].name[k] >= 'a') && (kfaces[i].name[k] <= 'z')){ ktype = kfaces[i].name[k]; break; } } /* find out which coefficients and weights to use */ if (ttype == 'f'){ if (ktype == 'f'){ dist = find_distance(artest.fcoeffs+a,kfaces[i].fcoeffs+a, interval); dist = 100 * log(conf_factor)/log(dist + conf_factor); dist = weights[0] * dist + biases[0]; } else { if (ktype == 'q'){ dist = find_distance(artest.qcoeffs+a,kfaces[i].fcoeffs+a, interval); dist = 100 * log(conf_factor)/log(dist + conf_factor); dist = weights[1] * dist + biases[1]; } else { if (ktype == 'h'){ dist = find_distance(artest.hcoeffs+a,kfaces[i].fcoeffs+a, interval); dist = 100 * log(conf_factor)/log(dist + conf_factor); dist = weights[2] * dist + biases[2]; } else { if (ktype == 'p'){ dist = find_distance(artest.pcoeffs+a,kfaces[i].fcoeffs+a, interval); dist = 100 * log(conf_factor)/log(dist + conf_factor); dist = weights[3] * dist + biases[3]; } } } } } /* if (ttype = 'f') */ else { if (ttype == 'q'){ if (ktype == 'f'){ dist = find_distance(artest.fcoeffs+a,kfaces[i].qcoeffs+a, interval); dist = 100 * log(conf_factor)/log(dist + conf_factor); dist = weights[4] * dist + biases[4]; } else{ if (ktype == 'q'){ dist = find_distance(artest.qcoeffs+a,kfaces[i].qcoeffs+a, interval); dist = 100 * log(conf_factor)/log(dist + conf_factor); dist = weights[5] * dist + biases[5]; } else{ if (ktype == 'h'){ dist = find_distance(artest.hcoeffs+a,kfaces[i].qcoeffs+a, interval); dist = 100 * log(conf_factor)/log(dist + conf_factor); dist = weights[6] * dist + biases[6]; } else{ dist = find_distance(artest.pcoeffs+a, kfaces[i].qcoeffs, interval); dist = 100 * log(conf_factor)/log(dist + conf_factor); dist = weights[7] * dist + biases[7]; } } } } /* if (ttype == q)... */ else{ if ( ttype == 'h'){ if (ktype == 'f'){ dist = find_distance(artest.fcoeffs+a, kfaces[i].hcoeffs+a, interval); dist = 100 * log(conf_factor)/log(dist + conf_factor); dist = weights[8] * dist + biases[8]; } else{ if (ktype == 'q'){ dist = find_distance(artest.qcoeffs+a, kfaces[i].hcoeffs, interval); dist = 100 * log(conf_factor)/log(dist + conf_factor); dist = weights[9] * dist + biases[9]; } else { if (ktype == 'h'){ dist = find_distance(artest.hcoeffs+a, kfaces[i].hcoeffs+a, interval); dist = 100 * log(conf_factor)/log(dist + conf_factor); dist = weights[10] * dist + biases[10]; } else{ dist = find_distance(artest.pcoeffs+a, kfaces[i].hcoeffs+a, interval); dist = 100 * log(conf_factor)/log(dist + conf_factor); dist = weights[11] * dist + biases[11]; } } } }/* if (ttype == 'h').... */ else { if (ktype == 'f'){ dist = find_distance(artest.fcoeffs+a, kfaces[i].pcoeffs+a, interval); dist = 100 * log(conf_factor)/log(dist + conf_factor); dist = weights[12] * dist + biases[12]; } else{ if (ktype == 'q'){ dist = find_distance(artest.qcoeffs+a, kfaces[i].pcoeffs+a,interval); dist = 100 * log(conf_factor)/log(dist + conf_factor); dist = weights[13] * dist + biases[13]; } else{ if (ktype == 'h'){ dist = find_distance(artest.hcoeffs+a, kfaces[i].pcoeffs+a, interval); dist = 100 * log(conf_factor)/log(dist + conf_factor); dist = weights[14] * dist + biases[14]; } else{ dist = find_distance(artest.pcoeffs+a, kfaces[i].pcoeffs+a, interval); dist = 100 * log(conf_factor)/log(dist + conf_factor); dist = weights[15] * dist + biases[15]; } } } } /* third else....*/ } /* Second else ...*/ } /* first else... */ /* Create a match and add to the list of matches for that face */ /* Allocate memory for the struct a_match of type Match for later use */ a_match = (Matchptr) calloc(1, sizeof(Match)); if (a_match == NULL){ fprintf(stderr, "\nERROR: Memory cannot be allocated for a_match\n\n"); exit(3); } a_match->name = strdup(kfaces[i].name); a_match->distance = dist; a_match->next = NULL; tfaces.similar = add_match(tfaces.similar, a_match, n); } /* for (i= 0; i<no_kfiles; ....*/ file_no++; fprintf(fout, "\n"); count = print_file(tfaces, n, fout, thres, count); fprintf(fout, "\n"); fflush(fout); kill_list(tfaces.similar); } /* if ( (strncmp........ */ } /* while ( (fscanf(..... */ fclose(ftlist); fprintf(stdout, "%f\n", (float) count/no_files); fprintf(stderr, "\n\nThe recognition rate is %f (%d/%d)\n",
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -