SPPoint spPointCreate(double* data, int dim, int index){ SPPoint point; int i; // check validation of parameters if (data == NULL || dim <= 0 || index < 0) { return NULL; } point = (SPPoint)malloc(sizeof(*point)); if (point == NULL){ spPointDestroy(point); return NULL; } // allocate memory for point->coordinates point->coordinates = (double*)malloc(dim*sizeof(double)); if (point->coordinates == NULL){ //Allocation failure - need to free(point) spPointDestroy(point); return NULL; } //get data for (i=0; i<dim; i++){ point->coordinates[i] = data[i]; } // initializing the rest of point arguments point->index = index; point->dim = dim; return point; }
//edge test case 1 knnTestCaseData initializeKnnEdgeTestCase1(){ //edge case 1 data SPKDTreeNode kNNedgeTestCase1Tree = NULL; SPBPQueue kNNedgeTestCase1Queue = NULL; SPPoint kNNedgeTestCase1QueryPoint = NULL; SPPoint* kNNedgeTestCase1Points = NULL; int kNNedgeTestCase1MaxDim = 1; int kNNedgeTestCase1Size = 1; SP_KDTREE_SPLIT_METHOD kNNedgeTestCase1SplitMethod = INCREMENTAL; int kNNedgeTestCase1K = 1; knnTestCaseData caseData = NULL; double data1[1] = {2}, queryData[1] = {0}; SPPoint p1; SPKDArray kdArr = NULL; spCalloc(caseData, knn_test_case_data, 1); kNNedgeTestCase1Points = (SPPoint*)calloc(sizeof(SPPoint),kNNedgeTestCase1Size); if (kNNedgeTestCase1Points == NULL){ spLoggerSafePrintError(ERROR_ALLOCATING_MEMORY,__FILE__,__FUNCTION__,__LINE__); return NULL; } caseData->points = kNNedgeTestCase1Points; caseData->size = kNNedgeTestCase1Size; p1 = spPointCreate(data1,kNNedgeTestCase1MaxDim,1); if (p1 == NULL){ spLoggerSafePrintError(ERROR_ALLOCATING_MEMORY,__FILE__,__FUNCTION__,__LINE__); return NULL; } kNNedgeTestCase1Points[0] = p1; kNNedgeTestCase1QueryPoint = spPointCreate(queryData,kNNedgeTestCase1MaxDim,2); if (kNNedgeTestCase1QueryPoint == NULL){ spPointDestroy(p1); spLoggerSafePrintError(ERROR_ALLOCATING_MEMORY,__FILE__,__FUNCTION__,__LINE__); return NULL; } caseData->queryPoint = kNNedgeTestCase1QueryPoint; kNNedgeTestCase1Queue = spBPQueueCreate(kNNedgeTestCase1K); if (kNNedgeTestCase1Queue == NULL){ spPointDestroy(p1); spLoggerSafePrintError(ERROR_ALLOCATING_MEMORY,__FILE__,__FUNCTION__,__LINE__); return NULL; } caseData->queue = kNNedgeTestCase1Queue; kdArr = Init(kNNedgeTestCase1Points,kNNedgeTestCase1Size); kNNedgeTestCase1Tree = InitKDTree(kdArr, kNNedgeTestCase1SplitMethod); spKDArrayDestroy(kdArr); caseData->k = kNNedgeTestCase1K; caseData->split_method = kNNedgeTestCase1SplitMethod; caseData->tree = kNNedgeTestCase1Tree; return caseData; }
bool pointDestroyTest() { double data1[3] = { 1.0, 1.0, 2.0 }; int dim1 = 3; int index1 = 1; SPPoint p = spPointCreate((double *)data1, dim1, index1); spPointDestroy(p); spPointDestroy(NULL); return true; }
//Checks if copy Works bool pointBasicCopyTest() { double data[2] = { 1.0, 1.0 }; int dim = 2; int index = 1; SPPoint p = spPointCreate(data, dim, index); SPPoint q = spPointCopy(p); ASSERT_TRUE(spPointGetIndex(p) == spPointGetIndex(q)); ASSERT_TRUE(spPointGetDimension(p) == spPointGetDimension(q)); int i; for (i = 0; i < spPointGetDimension(p); i++) { ASSERT_TRUE(spPointGetAxisCoor(p, i) == spPointGetAxisCoor(q, i)); } spPointDestroy(p); spPointDestroy(q); return true; }
bool pointBasicL2Distance() { double data1[2] = { 1.0, 1.0 }; double data2[2] = { 1.0, 0.0 }; int dim1 = 2; int dim2 = 2; int index1 = 1; int index2 = 1; SPPoint p = spPointCreate((double *)data1, dim1, index1); SPPoint q = spPointCreate((double *)data2, dim2, index2); ASSERT_TRUE(spPointL2SquaredDistance(p,p) == 0.0); ASSERT_TRUE(spPointL2SquaredDistance(q,q) == 0.0); ASSERT_FALSE(spPointL2SquaredDistance(p,q) == 0.0); spPointDestroy(p); spPointDestroy(q); return true; }
void destroyKDArray(SPKDArray KDArray){ int i; int n; //number of points int d; //number of dimensions //if KDArray==NULL returns if (KDArray==NULL){ return; } n = KDArray->n; d = KDArray->d; if (KDArray->array_of_points!=NULL){ for (i=0; i<n; i++){ spPointDestroy(KDArray->array_of_points[i]); } free(KDArray->array_of_points); } if (KDArray->matrix_of_sorted_indexes!=NULL){ for(i=0; i<d;i++){ if (KDArray->matrix_of_sorted_indexes[i]!=NULL){ free(KDArray->matrix_of_sorted_indexes[i]); } } free(KDArray->matrix_of_sorted_indexes); } free(KDArray); }
void destroyCaseData(SPKDTreeNode tree,SPKDArray kdArr,SPPoint* pointsArray,int size, SPBPQueue queue,SPPoint queryPoint){ if (tree) spKDTreeDestroy(tree, false); if (kdArr) spKDArrayDestroy(kdArr); if (pointsArray) destroyPointsArray(pointsArray,size); if (queue) spBPQueueDestroy(queue); if (queryPoint) spPointDestroy(queryPoint); }
/* * helper function for Init and split * function that allocates memory for a new SPKDArray with all its field * param: * KDArray: address to store the new SPKDArray * size: number of points to allocate * dim: number of dimentions * return: * -1 if an allocation error occurred * 1 otherwise */ int mallocForNewKdArray(SPKDArray* KDArray, int size, int dim){ int i; int j; //allocate memory for *KDArray if ((*KDArray = (SPKDArray)malloc(sizeof(**KDArray)))==NULL){ spLoggerPrintError(ALLOC_ERROR_MSG, __FILE__, __func__, __LINE__); return -1; } // allocate memory for *KDArray->array_of_points if ( ((*KDArray)->array_of_points = (SPPoint*)malloc(size*sizeof(SPPoint))) == NULL){ spLoggerPrintError(ALLOC_ERROR_MSG, __FILE__, __func__, __LINE__); free(*KDArray); return -1; } //allocate memory for *KDArray->matrix_of_sorted_indexes, this will be a d*n matrix, the i'th row is the indexes of the points in arr sorted according to their i'th dimension if ( ((*KDArray)->matrix_of_sorted_indexes = (int**)malloc(dim*sizeof(int*))) == NULL){ spLoggerPrintError(ALLOC_ERROR_MSG, __FILE__, __func__, __LINE__); for (i=0; i<size; i++){ spPointDestroy((*KDArray)->array_of_points[i]); } free((*KDArray)->array_of_points); free(*KDArray); return -1; } for (i=0; i<dim; i++){ if( ((*KDArray)->matrix_of_sorted_indexes[i]=(int*)malloc(size*sizeof(int))) == NULL){ spLoggerPrintError(ALLOC_ERROR_MSG, __FILE__, __func__, __LINE__); for (j=0; j<i; j++){ free((*KDArray)->matrix_of_sorted_indexes[j]); } free((*KDArray)->matrix_of_sorted_indexes); for (i=0; i<size; i++){ spPointDestroy((*KDArray)->array_of_points[j]); } free((*KDArray)->array_of_points); free(*KDArray); return -1; } } return 1; }
/** * Frees all memory resources associated with kdTreeNode. * If kdTreeNode == NULL nothig is done. */ void kdTreeNodeDestroy(KDTreeNode kdTreeNode) { if (kdTreeNode == NULL ) return; if (kdTreeNode->data != NULL ) spPointDestroy(kdTreeNode->data); kdTreeNodeDestroy(kdTreeNode->left); kdTreeNodeDestroy(kdTreeNode->right); free(kdTreeNode); return; }
SPPoint spPointCopy(SPPoint source){ SPPoint copy; assert (source != NULL); copy = spPointCreate(source->coords,source->dim,source->index); if (!copy){ spPointDestroy(source); return NULL; } return copy; }
void ArrayPointDestroy(SPPoint* ptrarr, int start_ind, int end_ind){ int i; if(ptrarr){ for(i=start_ind; i<end_ind; i++){ if(ptrarr[i]){ spPointDestroy(ptrarr[i]); }else{break;} } free(ptrarr); } return; }
SPPoint spPointCreate(double* data, int dim, int index){ int i; assert((dim > 0) && data && (index >= 0)); //Printdata(&data, dim); struct sp_point_t *point = (struct sp_point_t*) malloc(sizeof(struct sp_point_t)); if (point == NULL) { spPointDestroy(point); return NULL; } point->coords = (double *)calloc(dim, sizeof(double)); if(!(point->coords)){ spPointDestroy(point); return NULL; } for (i = 0; i < dim; i++) { (point->coords)[i] = data[i]; } point->dim = dim; point->index = index; return point; }
void SPKDTreeDestroy(SPKDTreeNode tree) { if (tree != NULL) { SPKDTreeDestroy(tree->left); SPKDTreeDestroy(tree->right); if (tree->data != NULL) spPointDestroy(*(tree->data)); free(tree->data); free(tree); } }
//null test bool runKnnNullTests(){ SPBPQueue tempQueue = NULL; SPPoint point = generateRandomPoint(4,1); tempQueue = spBPQueueCreate(4); kNearestNeighbors(NULL,tempQueue, point); ASSERT_TRUE(spBPQueueIsEmpty(tempQueue)); spPointDestroy(point); spBPQueueDestroy(tempQueue); return true; }
void freeFeatures(SPPoint* features, int numOfFeatures){ assert(numOfFeatures >= 0); int i; if (features != NULL){ for (i = 0 ; i < numOfFeatures ; i++){ spPointDestroy(features[i]); } } else { spLoggerSafePrintWarning(WARNING_IMAGE_DATA_POINTS_ARRAY_NULL, __FILE__,__FUNCTION__, __LINE__); } }
void SPKDArrayDestroy(SPKDArray kdArr) { int i; if (kdArr != NULL) { for (i = 0; i < kdArr->dims; i++) free(kdArr->pointsByCoors[i]); free(kdArr->pointsByCoors); for (i = 0; i < kdArr->size; i++) spPointDestroy(kdArr->points[i]); free(kdArr->points); free(kdArr); } }
bool pointGettersTest() { double data1[3] = { 1.0, 1.0, 2.0 }; int dim1 = 3; int index1 = 1; SPPoint p = spPointCreate((double *)data1, dim1, index1); ASSERT_TRUE(spPointGetAxisCoor(p, 0) == 1.0); ASSERT_TRUE(spPointGetAxisCoor(p, 1) == 1.0); ASSERT_FALSE(spPointGetAxisCoor(p, 2) == 1.0); ASSERT_TRUE(spPointGetAxisCoor(p, 2) == 2.0); ASSERT_TRUE(spPointGetIndex(p) == 1); ASSERT_TRUE(spPointGetDimension(p) == 3); spPointDestroy(p); return true; }
void spKDTreeDestroy(SPKDTreeNode node){ if(!node){ return; } if(node->dim == INVALID){ spPointDestroy(node->data); } if(node->left){ spKDTreeDestroy(node->left); } if(node->right){ spKDTreeDestroy(node->right); } free(node); }
//test case 2 knnTestCaseData initializeKnnTestCase2(){ //test case 2 data SPKDTreeNode kNNtestCase2Tree = NULL; SPBPQueue kNNtestCase2Queue = NULL; SPPoint kNNtestCase2QueryPoint = NULL; SPPoint* kNNtestCase2Points = NULL; int kNNtestCase2MaxDim = 2; int kNNtestCase2Size = 5; SP_KDTREE_SPLIT_METHOD kNNtestCase2SplitMethod = INCREMENTAL; int kNNtestCase2K = 3; knnTestCaseData caseData = NULL; double data1[2] = {1,2},data2[2] = {123,70},data3[2] = {2,7},data4[2] = {9,11}, data5[2] = {3,4}, queryData[2] = {0,0}; SPPoint p1,p2,p3,p4,p5; SPKDArray kdArr = NULL; spCalloc(caseData, knn_test_case_data, 1); kNNtestCase2Points = (SPPoint*)calloc(sizeof(SPPoint),kNNtestCase2Size); if (kNNtestCase2Points == NULL){ spLoggerSafePrintError(ERROR_ALLOCATING_MEMORY,__FILE__,__FUNCTION__,__LINE__); return NULL; } caseData->points = kNNtestCase2Points; caseData->size = kNNtestCase2Size; p1 = spPointCreate(data1,kNNtestCase2MaxDim,1); if (p1 == NULL){ spLoggerSafePrintError(ERROR_ALLOCATING_MEMORY,__FILE__,__FUNCTION__,__LINE__); return NULL; } p2 = spPointCreate(data2,kNNtestCase2MaxDim,2); if (p2 == NULL){ spPointDestroy(p1); spLoggerSafePrintError(ERROR_ALLOCATING_MEMORY,__FILE__,__FUNCTION__,__LINE__); return NULL; } p3 = spPointCreate(data3,kNNtestCase2MaxDim,3); if (p3 == NULL){ spPointDestroy(p1); spPointDestroy(p2); spLoggerSafePrintError(ERROR_ALLOCATING_MEMORY,__FILE__,__FUNCTION__,__LINE__); return NULL; } p4 = spPointCreate(data4,kNNtestCase2MaxDim,4); if (p4 == NULL){ spPointDestroy(p1); spPointDestroy(p2); spPointDestroy(p3); spLoggerSafePrintError(ERROR_ALLOCATING_MEMORY,__FILE__,__FUNCTION__,__LINE__); return NULL; } p5 = spPointCreate(data5,kNNtestCase2MaxDim,5); if (p5 == NULL){ spPointDestroy(p1); spPointDestroy(p2); spPointDestroy(p3); spPointDestroy(p4); spLoggerSafePrintError(ERROR_ALLOCATING_MEMORY,__FILE__,__FUNCTION__,__LINE__); return NULL; } kNNtestCase2Points[0] = p1; kNNtestCase2Points[1] = p2; kNNtestCase2Points[2] = p3; kNNtestCase2Points[3] = p4; kNNtestCase2Points[4] = p5; kNNtestCase2QueryPoint= spPointCreate(queryData,kNNtestCase2MaxDim,6); if (kNNtestCase2QueryPoint == NULL){ spPointDestroy(p1); spPointDestroy(p2); spPointDestroy(p3); spPointDestroy(p4); spPointDestroy(p5); spLoggerSafePrintError(ERROR_ALLOCATING_MEMORY,__FILE__,__FUNCTION__,__LINE__); return NULL; } caseData->queryPoint = kNNtestCase2QueryPoint; kNNtestCase2Queue = spBPQueueCreate(kNNtestCase2K); if (kNNtestCase2Queue == NULL){ spPointDestroy(p1); spPointDestroy(p2); spPointDestroy(p3); spPointDestroy(p4); spPointDestroy(p5); spLoggerSafePrintError(ERROR_ALLOCATING_MEMORY,__FILE__,__FUNCTION__,__LINE__); return NULL; } caseData->queue = kNNtestCase2Queue; kdArr = Init(kNNtestCase2Points,kNNtestCase2Size); kNNtestCase2Tree = InitKDTree(kdArr, kNNtestCase2SplitMethod); spKDArrayDestroy(kdArr); caseData->k = kNNtestCase2K; caseData->split_method = kNNtestCase2SplitMethod; caseData->tree = kNNtestCase2Tree; return caseData; }
//test case 1 knnTestCaseData initializeKnnTestCase1(){ //test case 1 data SPKDTreeNode kNNtestCase1Tree = NULL; SPBPQueue kNNtestCase1QueueKNN = NULL; SPPoint kNNtestCase1QueryPoint = NULL; SPPoint* kNNtestCase1Points = NULL; int kNNtestCase1MaxDim = 3; int kNNtestCase1Size = 2; SP_KDTREE_SPLIT_METHOD kNNtestCase1SplitMethod = MAX_SPREAD; int kNNtestCase1K = 1; knnTestCaseData caseData = NULL; double data1[3] = {1,2,3}, data2[3] = {5,-7,13}, queryData[3] = {0,0,0}; SPPoint p1,p2; SPKDArray kdArr = NULL; spCalloc(caseData, knn_test_case_data, 1); kNNtestCase1Points = (SPPoint*)calloc(sizeof(SPPoint),kNNtestCase1Size); if (kNNtestCase1Points == NULL){ spLoggerSafePrintError(ERROR_ALLOCATING_MEMORY,__FILE__,__FUNCTION__,__LINE__); return NULL; } caseData->points = kNNtestCase1Points; caseData->size = kNNtestCase1Size; p1 = spPointCreate(data1,kNNtestCase1MaxDim,1); if (p1 == NULL){ spLoggerSafePrintError(ERROR_ALLOCATING_MEMORY,__FILE__,__FUNCTION__,__LINE__); return NULL; } p2 = spPointCreate(data2,kNNtestCase1MaxDim,2); if (p2 == NULL){ spPointDestroy(p1); spLoggerSafePrintError(ERROR_ALLOCATING_MEMORY,__FILE__,__FUNCTION__,__LINE__); return NULL; } kNNtestCase1Points[0] = p1; kNNtestCase1Points[1] = p2; kNNtestCase1QueryPoint = spPointCreate(queryData, kNNtestCase1MaxDim, 3); if (kNNtestCase1QueryPoint == NULL){ spPointDestroy(p1); spPointDestroy(p2); spLoggerSafePrintError(ERROR_ALLOCATING_MEMORY,__FILE__,__FUNCTION__,__LINE__); return NULL; } caseData->queryPoint = kNNtestCase1QueryPoint; kNNtestCase1QueueKNN = spBPQueueCreate(kNNtestCase1K); if (kNNtestCase1QueueKNN == NULL){ spPointDestroy(p1); spPointDestroy(p2); spLoggerSafePrintError(ERROR_ALLOCATING_MEMORY,__FILE__,__FUNCTION__,__LINE__); return NULL; } caseData->queue = kNNtestCase1QueueKNN; kdArr = Init(kNNtestCase1Points,kNNtestCase1Size); kNNtestCase1Tree = InitKDTree(kdArr, kNNtestCase1SplitMethod); spKDArrayDestroy(kdArr); caseData->k = kNNtestCase1K; caseData->split_method = kNNtestCase1SplitMethod; caseData->tree = kNNtestCase1Tree; return caseData; }
SPKDArray SPKDArrayInit(SPPoint* arr, int size, int dims, SP_KDARRAY_MSG* msg) { SPKDArray kdArr; int i, j, k; SPSortingHelper* sorter; assert(msg != NULL); if (arr == NULL || size <= 0 || dims <= 0) { *msg = SP_KDARRAY_INVALID_ARGUMENT; return NULL; } kdArr = (SPKDArray)malloc(sizeof(*kdArr)); if (kdArr == NULL) { *msg = SP_KDARRAY_ALLOC_FAIL; return NULL; } // Set kdArr fields, allocate memory kdArr->dims = dims; kdArr->size = size; kdArr->points = (SPPoint*)malloc(size * sizeof(SPPoint)); kdArr->pointsByCoors = (int**)malloc(dims * sizeof(int*)); if (kdArr->points == NULL || kdArr->pointsByCoors == NULL) { *msg = SP_KDARRAY_ALLOC_FAIL; free(kdArr->points); free(kdArr); return NULL; } for (i = 0; i < dims; i++) { kdArr->pointsByCoors[i] = (int*)malloc(size * sizeof(int)); if (kdArr->pointsByCoors[i] == NULL) { *msg = SP_KDARRAY_ALLOC_FAIL; for (j = 0; j < i; j++) free(kdArr->pointsByCoors[j]); free(kdArr->pointsByCoors); free(kdArr->points); free(kdArr); return NULL; } } for (i = 0; i < size; i++) // Copy the points kdArr->points[i] = spPointCopy(arr[i]); for (k = 0; k < dims; k++) // Now we sort the points according to dimension k { // Allocate helper array sorter = (SPSortingHelper*)malloc(size * sizeof(SPSortingHelper)); if (sorter == NULL) { *msg = SP_KDARRAY_ALLOC_FAIL; SPKDArrayDestroy(kdArr); return NULL; } for (i = 0; i < size; i++) { // Allocate and initialize sorter[i] sorter[i] = (SPSortingHelper)malloc(sizeof(*sorter[i])); if (sorter[i] == NULL) { *msg = SP_KDARRAY_ALLOC_FAIL; for (j = 0; j < i; j++) free(sorter[j]); free(sorter); SPKDArrayDestroy(kdArr); return NULL; } sorter[i]->point = spPointCopy(kdArr->points[i]); sorter[i]->dim = k; sorter[i]->originalIndex = i; } qsort(sorter, size, sizeof(SPSortingHelper), SPSortingHelperCompare); // Now sort for (i = 0; i < size; i++) // And update the appropriate line of pointsByCoors { kdArr->pointsByCoors[k][i] = sorter[i]->originalIndex; spPointDestroy(sorter[i]->point); free(sorter[i]); } free(sorter); } // Done *msg = SP_KDARRAY_SUCCESS; return kdArr; }
int main(int argc, char *argv[]) { SPConfig config = NULL; // hold configuration parameters char config_filename[CONFIG_FILE_PATH_SIZE]; // the configuration file name int knn; // the number of similar features in each image to find (spKNN from configuration file) int num_of_similar_images_to_find; // the number of similar images (to the query) to find (from configuration file) int split_method; // holds an int representing the split method: 0=RANDOM, 1= MAX_SPREAD, 2=INCREMENTAL bool minGui = false; // value of the system variable MinimalGui bool extraction_mode; // indicates if extraction mode on or off int num_of_images = 0; // number of images in the directory given by the user in the configuration file char** all_images_paths = NULL; // array with the paths to all the images int last_extracted_feature = 0; // helper - holds the last feature extracted in order to free all extracted features on error SPPoint** features_per_image = NULL; // helper - holds the features for each images int* num_of_features_per_image = NULL; // holds number of features extracted for each image char query_image[CONFIG_FILE_PATH_SIZE]; // the query image SPPoint* query_features = NULL; // all query features int query_num_of_features; // number of features in query image KDTreeNode kd_tree = NULL; // array holds a KDTree for the images int* closest_images = NULL; // array holds the spNumOfSimilarImages indexes of the closest images to the query image int print_result; // holds the result of the call to PrintMinGuiFalse int retval = 0; // return value - default 0 on success char string_holder[CONFIG_FILE_PATH_SIZE]; // helper to hold strings sp::ImageProc *improc = NULL; SP_CONFIG_MSG msg; int i; int j; int n; // validate command line arguments: // cmd line arguments are ok if there was no arguments specified (argc == 1) or two arguments specified ( -c and filname) if (argc != 3 && argc != 1) { printf(INVALID_CMD_LINE_MSG); return -1; } if (argc == 1) { strcpy(config_filename, DEFAULT_CONFIG_FILENAME); config = spConfigCreate(config_filename, &msg); if (msg == SP_CONFIG_CANNOT_OPEN_FILE) { printf(ERROR_OPENING_DEFAULT_CONFIG_FILE_MSG, DEFAULT_CONFIG_FILENAME); } if (msg != SP_CONFIG_SUCCESS) { retval = -1; goto err; // error is printed inside spConfigCreate } } else { // argc == 3 // check that second argument is the -c flag if (strcmp(argv[1], CMD_LINE_CONFIG_FILENAME_FLAG) != 0) { printf(INVALID_CMD_LINE_MSG); retval = -1; goto err; } strcpy(config_filename, argv[2]); config = spConfigCreate(config_filename, &msg); if (msg == SP_CONFIG_CANNOT_OPEN_FILE) { printf(ERROR_OPENING_CONFIG_FILE_MSG, config_filename); } if (msg != SP_CONFIG_SUCCESS) { retval = -1; goto err; // error is printed inside spConfigCreate } } // initiate from config if (initFromConfig(config, &num_of_images, &num_of_similar_images_to_find, &knn, &split_method, &extraction_mode, &minGui, &all_images_paths) == -1 ) { retval = -1; goto err; // error is printed inside initFromConfig } // initiate image proc improc = new sp::ImageProc(config); // extract images features if ((num_of_features_per_image = (int*)malloc(sizeof(*num_of_features_per_image) * num_of_images)) == NULL) { spLoggerPrintError(ALLOCATION_FAILURE_MSG, __FILE__, __func__, __LINE__); retval = -1; goto err; } spLoggerPrintInfo(CHECK_EXTRACTION_MODE_INFO_LOG); if (extraction_mode) { // extraction mode is chosen spLoggerPrintMsg(USE_EXTRACTION_MODE_LOG); spLoggerPrintInfo(EXTRACT_IMAGES_FEATURES_INFO_LOG); if ((features_per_image = (SPPoint**)malloc(sizeof(*features_per_image) * num_of_images)) == NULL) { spLoggerPrintError(ALLOCATION_FAILURE_MSG, __FILE__, __func__, __LINE__); retval = -1; goto err; } // extract each image features and write them to file for (i=0; i < num_of_images; i++) { // extract image features if ((features_per_image[i] = improc->getImageFeatures(all_images_paths[i], i, &(num_of_features_per_image[i]))) == NULL) { last_extracted_feature = i; retval = -1; goto err; // error is printed inside getImageFeatures } } if (saveToDirectory(config, features_per_image, num_of_features_per_image, num_of_images) == -1) { retval = -1; goto err; // error is printed inside saveToDirectory } } else { // not extraction mode spLoggerPrintMsg(USE_NOT_EXTRACTION_MODE_LOG); spLoggerPrintInfo(READ_FEATURES_FROM_FILE_LOG); if ((features_per_image = extractFromFiles(config, num_of_features_per_image, num_of_images)) == NULL) { retval = -1; goto err; // error is printed inside extractFromFiles } } if ((kd_tree = initiateDataStructures(features_per_image, num_of_features_per_image, num_of_images, split_method)) == NULL) { retval = -1; goto err; // error is printed inside initiateDataStructures } query: while(1) { // get a query image from the user printf(ENTER_AN_IMAGE_MSG); fflush(NULL); scanf("%s",query_image); // exit if user asked if (strcmp (query_image,EXIT_SIGN) == 0) { printf(EXIT_MSG); fflush(NULL); goto err; // free memory and quit } if( access( query_image, F_OK ) == -1 ) { printf(FILE_DOESNT_EXIST, query_image); goto query; } // extract query image features spLoggerPrintMsg(EXTRACT_QUERY_IMAGE_FEATURES_LOG); if ((query_features = improc->getImageFeatures(query_image, num_of_images, &query_num_of_features)) == NULL) { retval = -1; goto err_inside_loop; // error log is printed inside getImageFeatures } // print debug log if ((n = sprintf(string_holder, NUM_OF_EXTRACTED_FEATURES_DEBUG_LOG, query_num_of_features)) < 0) { spLoggerPrintError(GENERAL_ERROR_MSG, __FILE__, __func__, __LINE__); retval = -1; goto err_inside_loop; } spLoggerPrintDebug(string_holder, __FILE__, __func__, __LINE__); // print log message if ((n = sprintf(string_holder, SEARCING_SIMILAR_IMAGES_MSG, num_of_similar_images_to_find)) < 0) { spLoggerPrintError(GENERAL_ERROR_MSG, __FILE__, __func__, __LINE__); retval = -1; goto err_inside_loop; } spLoggerPrintMsg(string_holder); // find similar images to the query image closest_images = getKClosestImages(num_of_similar_images_to_find, knn, query_features, kd_tree, query_num_of_features, num_of_images); if (closest_images == NULL) { retval = -1; goto err_inside_loop; // error is printed to inside getKClosestImages } // show (display) closest_images images //need to show images if (minGui==true){ for (i=0; i<num_of_similar_images_to_find; i++){ //get file path of the images by the indexes in closest_images improc->showImage(all_images_paths[closest_images[i]]); } } // i.e. minGui==false, just need to print images path else{ print_result = PrintMinGuiFalse(query_image, num_of_similar_images_to_find, all_images_paths, closest_images); if (print_result == 0) { retval = -1; goto err_inside_loop; // error is printed inside } } // free memory before entering the loop again free(closest_images); if (query_features != NULL) { for (i=0; i<query_num_of_features; i++) { spPointDestroy(query_features[i]); } free(query_features); } } err_inside_loop: free(closest_images); // free query_features if (query_features != NULL) { for (i=0; i<query_num_of_features; i++) { spPointDestroy(query_features[i]); } free(query_features); } // done - destroy logger and free everything err: spLoggerDestroy(); // free the kd tree DestroyKDTreeNode(kd_tree); spConfigDestroy(config); // free all images paths if (all_images_paths != NULL) { for (i = 0; i < num_of_images; i ++) { free(all_images_paths[i]); } free(all_images_paths); } if (features_per_image != NULL) { // free features_per_image for (i = 0; i < last_extracted_feature; i ++) { if (features_per_image[i] != NULL) { for (j = 0; j < num_of_features_per_image[i]; j++) { spPointDestroy(features_per_image[i][j]); } } } free(features_per_image); } free(num_of_features_per_image); // must be freed after features_per_image if (improc != NULL) { delete improc; } return retval; }
SPKDTreeNode SPKDTreeInitHelp(SPKDArray kdArr, int size, SP_KDTREE_SPLIT_METHOD splitMethod, int lastIndex, SP_KDTREE_MSG * msg) { int dim, dims, maxSpread, maxSpreadIndex, spread, i, minVal, maxVal; SP_KDARRAY_MSG kdArrMsg; SPKDArray* split; SPKDTreeNode ret; SPPoint workPoint; assert(msg != NULL); if (kdArr == NULL || size <= 0 || lastIndex < -1) { *msg = SP_KDTREE_INVALID_ARGUMENT; return NULL; } // Allocate memory ret = (SPKDTreeNode)malloc(sizeof(*ret)); if (ret == NULL) { *msg = SP_KDTREE_ALLOC_FAIL; return NULL; } if (size == 1) { // Returned node will be a leaf ret->dim = -1; ret->val = -1.0; ret->left = (ret->right = NULL); ret->data = (SPPoint*)malloc(sizeof(SPPoint)); if (ret->data == NULL) { *msg = SP_KDTREE_ALLOC_FAIL; free(ret); return NULL; } *(ret->data) = SPKDArrayGetPointByDim(kdArr, 0, -1, &kdArrMsg); // Gets the only point in the KD-Array } else { // Returned node is not a leaf dims = SPKDArrayGetDims(kdArr, &kdArrMsg); // Calculate the splitting dimension switch (splitMethod) { case SP_KDTREE_MAX_SPREAD: maxSpread = 0; maxSpreadIndex = 0; // calculate the maximum spread dimension for (i = 0; i < dims; i++) { workPoint = SPKDArrayGetPointByDim(kdArr, 0, i, &kdArrMsg); minVal = spPointGetAxisCoor(workPoint, i); spPointDestroy(workPoint); workPoint = SPKDArrayGetPointByDim(kdArr, size - 1, i, &kdArrMsg); maxVal = spPointGetAxisCoor(workPoint, i); spPointDestroy(workPoint); spread = maxVal - minVal; if (spread > maxSpread) { maxSpread = spread; maxSpreadIndex = i; } } dim = maxSpreadIndex; break; case SP_KDTREE_RANDOM: dim = rand() % dims; break; case SP_KDTREE_INCREMENTAL: dim = (lastIndex + 1) % dims; break; } split = SPKDArraySplit(kdArr, dim, &kdArrMsg); // Split the KD-Array according to the splitting dimension workPoint = SPKDArrayGetPointByDim(split[0], SPKDArrayGetSize(split[0], &kdArrMsg) - 1, dim, &kdArrMsg); ret->dim = dim; ret->val = spPointGetAxisCoor(workPoint, dim); // Employ recursion to calculate subtrees ret->left = SPKDTreeInitHelp(split[0], SPKDArrayGetSize(split[0], &kdArrMsg), splitMethod, lastIndex + 1, msg); ret->right = SPKDTreeInitHelp(split[1], SPKDArrayGetSize(split[1], &kdArrMsg), splitMethod, lastIndex + 1, msg); ret->data = NULL; // Get rid of unneeded memory SPKDArrayDestroy(split[0]); SPKDArrayDestroy(split[1]); free(split); spPointDestroy(workPoint); } // All done *msg = SP_KDTREE_SUCCESS; return ret; }