Beispiel #1
0
	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;
}
Beispiel #6
0
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);
}
Beispiel #8
0
/*
 * 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;
}
Beispiel #10
0
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;
}
Beispiel #11
0
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;
}
Beispiel #12
0
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;
}
Beispiel #13
0
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;
}
Beispiel #15
0
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__);
	}
}
Beispiel #16
0
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;
}
Beispiel #18
0
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;
}
Beispiel #21
0
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;
}
Beispiel #22
0
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;
}
Beispiel #23
0
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;
}