/** * Reads all of the names in a file into an array of * strings. Each element of the array is a char pointer. * * If nStrings is non-NULL, the number of strings is * returned in nStrings. * * The array is always one larger than nStrings elements * long and the last element is a NULL. * * @param fileName Name of file to read * @param nStrings Optional pointer to integer that will on return contain * the count of strings read from the file * @returns A NULL-terminated list of NULL-terminated strings */ ListOfStrings readListOfStrings (const char *fileName, int *nStrings) { Tokenizer tok; void *stringList = NULL; FILE *f; char *string; ListOfStrings array; size_t numStrings; f = fopen (fileName, "r"); DEBUG_CHECK (f, "Unable to read file"); tokenizerInit (&tok, tokenizerStreamReader, f); while (!tokenizerEndOfFile (&tok)) { string = strdup (tokenizerGetWord (&tok)); listAccumulate (&stringList, &string, sizeof (unsigned char *)); } fclose (f); /* Add a terminating NULL */ string = NULL; listAccumulate (&stringList, &string, sizeof (unsigned char *)); array = (ListOfStrings)listToArray (&stringList, sizeof (unsigned char *), &numStrings); if (nStrings) *nStrings = numStrings - 1; /* Don't count the NULL */ return array; }
void makeDifferenceImages (char *imageDirectory, char *imageList, char *distanceMatrix, int maxRank, int reqNIntra, int reqNExtra, Matrix *intrapersonal, Matrix *extrapersonal) { ImageList* imlist; void *nameList = NULL; char **nameArray; void *subjList = NULL; int *subjArray, *shuffledIndices, **sortedBySimilarityToProbe; int subjId, probeIdx, galleryIdx, idx, nIntrapersonal, nExtrapersonal, rank, i, numPixels; int nImages; /* size_t trash; */ Matrix sourceImages, intraImages, extraImages; ImageList *replicate, *subject; char *subjName; /* Read in a list of all the images */ imlist = getImageNames (imageList, &nImages); subjId = 0; for EACH_SUBJECT (imlist, subject) { for EACH_REPLICATE (subject, replicate) { subjName = strdup (replicate->filename); listAccumulate (&nameList, &subjName, sizeof (char *)); listAccumulate (&subjList, &subjId, sizeof (int)); writeProgress ("Reading subjects list", subjId, 0); } subjId++; }
void sortSubjectsBySimilarityToProbe (char *probe, ListOfStrings subjects, char *distanceMatrix, int *indices) { int i, j, nDistances; DistanceMeasure *distances = NULL; DistanceMeasure *toSort = NULL; int nSubjects = countStrings (subjects); /* If we are using a distance matrix, then we load up the * list of distances from the probe image. This allows us * to lookup the distances from the probe quickly */ if (distanceMatrix) { Tokenizer tok; FILE *f = fopen (makePath (distanceMatrix, probe), "r"); void *distanceList = NULL; DEBUG_CHECK_1ARG (f, "Unable to open file %s in scores directory", makePath (distanceMatrix, probe)); tokenizerInit (&tok, tokenizerStreamReader, f); while (!tokenizerEndOfFile (&tok)) { DistanceMeasure m; m.subject = strdup (tokenizerGetWord (&tok)); m.distance = atof (tokenizerGetWord (&tok)); listAccumulate (&distanceList, &m, sizeof (DistanceMeasure)); } fclose (f); distances = (DistanceMeasure*) listToArray (&distanceList, sizeof (DistanceMeasure), (size_t*)&nDistances); } /* Copy the list of names into the intermediate data structure that allows us to sort the * subjects by distance to the probe. */ toSort = (DistanceMeasure*) malloc (nSubjects * sizeof (DistanceMeasure)); for (j = 0; j < nSubjects; j++) { toSort[j].subject = subjects[j]; toSort[j].distance = 0.0; toSort[j].index = j; } /* Read distances between probe and every other image in the subject list. * As a special case, a subject is said to be infinitely far away from him/herself. * Random scores are used when a distanceMatrix is not provided */ for (j = 0; j < nSubjects; j++) { if (strcmp (subjects[j], probe) == 0) { /* Probe and subject are the same. Say they are far apart since * we don't want to treat an image and itself as being two replicates * of a person */ toSort[j].distance = HUGE; } else if (distanceMatrix != NULL) { /* Look for the subject in the list of distances and return assign the * score */ toSort[j].distance = HUGE; for (i = 0; i < nDistances; ++i) if (strcmp (distances[i].subject, toSort[j].subject) == 0) toSort[j].distance = distances[i].distance; } else { /* If we are not using a distance matrix, then choose * a random value */ toSort[j].distance = ((double) rand()) / RAND_MAX; } } /* Now sort the list by similarity to the probe */ qsort (toSort, nSubjects, sizeof (DistanceMeasure), distanceMeasureComparator); /* Copy the data back into the subject list or return the permuted indices */ if (indices == NULL) for (j = 0; j < nSubjects; j++) { subjects[j] = toSort[j].subject; } else for (j = 0; j < nSubjects; j++) { indices[j] = toSort[j].index; } /* Clean up */ if (distanceMatrix) { for (i = 0; i < nDistances; ++i) free (distances[i].subject); free (distances); } free (toSort); }