Beispiel #1
0
SP_CONFIG_MSG spConfigGetFeatsPath(char* imagePath, const SPConfig config,
		int index)
{
	int sprintfRes = 0;

	if (NULL == config || NULL == imagePath)
	{
		spLoggerPrintError(INVALID_ARGUMENT_ERROR_MSG, __FILE__, __func__, __LINE__);
		return SP_CONFIG_INVALID_ARGUMENT;
	}
	if (index >= config->spNumOfImages || 0 > index)
	{
		spLoggerPrintError(IMG_INDEX_OUT_OF_RANGE_ERROR_MSG, __FILE__, __func__, __LINE__);
		return SP_CONFIG_INDEX_OUT_OF_RANGE;
	}

	sprintfRes = sprintf(imagePath, FEATURS_PATH_TEMPLATE ,
								config->spImagesDirectory,
								config->spImagesPrefix,
								index);
	/* check failure */
	if (0 > sprintfRes)
	{
		spLoggerPrintError(SPRINTF_FAILED_ERROR_MSG, __FILE__, __func__, __LINE__);
		return SP_CONFIG_FAILED_CREATING_PATH;
	}

	return SP_CONFIG_SUCCESS;
}
int spFeatureCreateFeatureFile(SPPoint* pointArray, const char* filename, int numOfImages,int numOfFeatures, int numOfDim){
	FILE *featureFile = NULL;
	int i,j;
	char errorMsg[1025];

	spLoggerPrintInfo("Creating features file...");
	if(filename == NULL){
		spLoggerPrintError("filename is NULL", "main.cpp", "main", 182);//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
		return 1; //ERROR
	}
	//Opening the file
	featureFile = fopen(filename,"w");
	if (featureFile == NULL){
		sprintf(errorMsg, "The features file %s couldn’t be open", filename);
		spLoggerPrintError(errorMsg, "SPFeaturesFiles.c", "spFeatureCreateFeatureFile", 14);
		return 1; //ERROR
	}
	//Writing the file
	//First line - 1- number of images 2- overall number of features 3- number of dimensions of the features
	fprintf(featureFile,"%d;;%d;;%d\n",numOfImages,numOfFeatures,numOfDim);
	for (i = 0; i < numOfFeatures; ++i) {	//Feature line - First the matching index of the img and the each coordinate
		fprintf(featureFile,"%d;;",spPointGetIndex(pointArray[i]));
		for (j = 0; j < numOfDim; ++j) {
			fprintf(featureFile,"%f;;",spPointGetAxisCoor(pointArray[i],j));
		}
		fprintf(featureFile, "\n");
	}
	spLoggerPrintInfo("Done creating features file");
	fclose(featureFile);
	return 0;
}
Beispiel #3
0
SPKDTreeNode spKDTreeCreateFromArray(SPKDArray kdArr, int prevDim,
					SPConfig config, SP_CONFIG_MSG *msg, int* problem ){
    SPKDTreeNode res = NULL;
    SPKDArray *children;
    if (spKDArrayGetNumOfFeatures(kdArr)==1){
        res = spKDTreeCreateLeaf(spKDArrayGetPoint(kdArr, 0));
        if(!res){
        	spLoggerPrintError(ALLOC_FAIL, __FILE__, __FUNCTION__, __LINE__);
        	spKDArrayDestroy(kdArr, ALL_ROWS);
        	*problem = true;
        	return NULL;
        }
        spKDArrayDestroy(kdArr, ALL_ROWS);
        return res;
    }
    else{			//** KD Array is larger than 1 point **//
        res = spKDTreeCreateNode();
        if(!res){
        	spLoggerPrintError(ALLOC_FAIL, __FILE__, __FUNCTION__, __LINE__);
        	spKDArrayDestroy(kdArr, ALL_ROWS);
        	*problem = true;
        	return NULL;
        }
        res->dim = spKDArrayFindSplitDim(kdArr, prevDim, config, msg);
        children = spKDArraySplit(kdArr, res->dim);
        if(!children){
        	spKDTreeDestroy(res);
        	spKDArrayDestroy(kdArr, ALL_ROWS);
        	*problem = true;
        	return NULL;
        }
        res->val = spKDArrayGetMedianVal(children[LEFT], res->dim);
        spKDArrayDestroy(kdArr, ALL_ROWS);
        res->left = spKDTreeCreateFromArray(children[LEFT],
        		res->dim, config, msg, problem);
        if(!(res->left)){
        	spKDTreeDestroy(res);
        	spKDArrayDestroy(kdArr, ALL_ROWS);
			spKDMultiArrayDestroy(children, true, ALL_ROWS, true, ALL_ROWS);
			*problem = true;
			return NULL;
        }
        res->right  = spKDTreeCreateFromArray(children[RIGHT],
        		res->dim, config, msg, problem);
        if(!(res->right)){
        	spKDTreeDestroy(res);
        	spKDArrayDestroy(kdArr, ALL_ROWS);
			spKDMultiArrayDestroy(children, true, ALL_ROWS, true, ALL_ROWS);
			*problem = true;
			return NULL;
        }
        spKDMultiArrayDestroy(children, false, false, false, false);
        return res;
    }
}
Beispiel #4
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;
}
/*
 * @param config - the configs provider
 * @param imageIndex - index of the image
 * @param file - output parameter that will store the handler to feats file
 * @param mode - file open mode, as given to the OS
 *
 * The helper function is retrieving a handler to a matching feats file, for either reading or writing
 *
 * @return SP_CONFIG_SUCCESS on success
 * @return SP_CONFIG_UNKNOWN_ERROR on open failure
 */
SP_CONFIG_MSG getFeatsFile(SPConfig config, int imageIndex, FILE** file,
		const char* mode) {
	char featsPath[260];

	SP_CONFIG_MSG msg = spConfigGetImageFeatsPath(featsPath, config,
			imageIndex);
	if (msg != SP_CONFIG_SUCCESS) {
		spLoggerPrintError(featsPathErr, __FILE__, __func__, __LINE__);
		return msg;
	}

	*file = fopen(featsPath, mode);
	if (*file == NULL) {
		msg = SP_CONFIG_UNKNOWN_ERROR;
		spLoggerPrintError(featsFileErr, __FILE__, __func__, __LINE__);
		return msg;
	}

	return SP_CONFIG_SUCCESS;
}
Beispiel #6
0
/**
 *  Help method that allocates a regular KDTreeNode.
 *  the point is copied but not freed.
 *  node doesn't have default parameters.
 *  return a node unless allocation failed occurred then null is returned
 **/
SPKDTreeNode spKDTreeCreateNode(){
    SPKDTreeNode node = (SPKDTreeNode)malloc(sizeof(*node));
    if (!node){
        spLoggerPrintError(ALLOC_FAIL, __FILE__, __FUNCTION__, __LINE__);
        return NULL;
    }
    node->dim=INVALID;
    node->left = NULL;
	node->right = NULL;
	node->data = NULL;
    return node;
}
Beispiel #7
0
SP_CONFIG_MSG spConfigGetPCAPath(char* pcaPath, const SPConfig config)
{
	int sprintfRes = 0;

	if (NULL == config || NULL == pcaPath)
	{
		spLoggerPrintError(INVALID_ARGUMENT_ERROR_MSG, __FILE__, __func__, __LINE__);
		return SP_CONFIG_INVALID_ARGUMENT;
	}

	sprintfRes = sprintf(pcaPath, PCA_PATH_TEMPLATE,
								config->spImagesDirectory, config->spPCAFilename);
	/* check failure */
	if (0 > sprintfRes)
	{
		spLoggerPrintError(SPRINTF_FAILED_ERROR_MSG, __FILE__, __func__, __LINE__);
		return SP_CONFIG_FAILED_CREATING_PATH;
	}

	return SP_CONFIG_SUCCESS;
}
Beispiel #8
0
SPKDTreeNode spKDTreeCreateLeaf(SPPoint point){
    SPKDTreeNode leaf = (SPKDTreeNode)malloc(sizeof(*leaf));
    if (!leaf){
        spLoggerPrintError(ALLOC_FAIL, __FILE__, __FUNCTION__, __LINE__);
        return NULL;
    }
    leaf->dim = INVALID;
    leaf->val = INVALID;
    leaf->left = NULL;
    leaf->right = NULL;
    leaf->data = spPointCopy(point);
    return leaf;
}
Beispiel #9
0
bool spConfigMinimalGui(const SPConfig config, SP_CONFIG_MSG* msg)
{
	if (NULL == config)
	{
		spLoggerPrintError(INVALID_ARGUMENT_ERROR_MSG , __FILE__, __func__, __LINE__);

		*msg = SP_CONFIG_INVALID_ARGUMENT;
		return false;
	}

	*msg = SP_CONFIG_SUCCESS;
	return config->spMinimalGUI;
}
Beispiel #10
0
SP_CONFIG_MSG spConfigGetLoggerFilename(char* loggerFilename, const SPConfig config)
{
	if (NULL == config || NULL == loggerFilename)
	{
		spLoggerPrintError(INVALID_ARGUMENT_ERROR_MSG, __FILE__, __func__, __LINE__);

		return SP_CONFIG_INVALID_ARGUMENT;
	}

	strcpy(loggerFilename, config->spLoggerFilename);

	return SP_CONFIG_SUCCESS;
}
Beispiel #11
0
int spConfigGetKNN(const SPConfig config, SP_CONFIG_MSG* msg)
{
	if (NULL == config)
	{
		spLoggerPrintError(INVALID_ARGUMENT_ERROR_MSG, __FILE__, __func__, __LINE__);

		*msg = SP_CONFIG_INVALID_ARGUMENT;
		return NEGATIVE_VALUE_FOR_ERROR;
	}

	*msg = SP_CONFIG_SUCCESS;
	return config->spKNN;
}
Beispiel #12
0
SP_LOGGER_LEVEL spConfigGetLoggerLevel(const SPConfig config, SP_CONFIG_MSG* msg)
{
	if (NULL == config)
	{
		spLoggerPrintError(INVALID_ARGUMENT_ERROR_MSG, __FILE__, __func__, __LINE__);

		*msg = SP_CONFIG_INVALID_ARGUMENT;
		return SP_LOGGER_DEBUG_INFO_WARNING_ERROR_LEVEL;
	}

	*msg = SP_CONFIG_SUCCESS;
	return (SP_LOGGER_LEVEL) (config->spLoggerLevel - 1);
}
Beispiel #13
0
KDTREE_SPLIT_METHOD spConfigGetKDTreeSplitMethod(const SPConfig config, SP_CONFIG_MSG* msg)
{
	if (NULL == config)
	{
		spLoggerPrintError(INVALID_ARGUMENT_ERROR_MSG, __FILE__, __func__, __LINE__);

		*msg = SP_CONFIG_INVALID_ARGUMENT;
		return SPLIT_METHOD_RANDOM;
	}

	*msg = SP_CONFIG_SUCCESS;
	return config->spKDTreeSplitMethod;
}
Beispiel #14
0
int* spFindImages(SPPoint* queryFeatures, const int querySize,
		const SPKDTreeNode root, const SPConfig config, SP_CONFIG_MSG *msg){
    int i, knn, numOfSimilarImg, numOfImages;
    int *imageCounter, *res;
    SPListElement element;
    knn = spConfigGetKNN(config, msg);

    SPBPQueue q = spBPQueueCreate(knn);
    if(!q){
        spLoggerPrintError(ALLOC_FAIL, __FILE__, __FUNCTION__, __LINE__);
        return NULL;
    }
    numOfImages = spConfigGetNumOfImages(config, msg);
    numOfSimilarImg = spConfigGetNumOfSimilarImages(config, msg);
    imageCounter = (int*)calloc(numOfImages, sizeof(int));
    if(!imageCounter){
        spLoggerPrintError(ALLOC_FAIL, __FILE__, __FUNCTION__, __LINE__);
        spBPQueueDestroy(q);
        return NULL;
    }
    /* count the num of neighbours of every
     * image for all features of the query */
    for(i=0; i<querySize; i++){
        spBPQueueClear(q);
        spKNNSearch(queryFeatures[i], root, q);
        while((element = spBPQueuePeek(q))!=NULL){
            imageCounter[spListElementGetIndex(element)]+=1;
            spListElementDestroy(element);
            spBPQueueDequeue(q);
        }
    }
    spBPQueueClear(q);
    spBPQueueDestroy(q);
    res = getTopImagesFromArray(imageCounter, numOfImages, numOfSimilarImg);
    free(imageCounter);
    return res;
}
Beispiel #15
0
/*
 * Internal help getter for the most wanted (similar) images.
 * @param: imageCounter: to bound the max value.
 * @param: numOfImages: the number of images to search from.
 * @param: numOfSimilarImg: according to configuration file - the number of wanted similar
 * images.
 * @return:
 * 	- NULL in case of an error
 * 	- int array that represent the top images
 */
int* getTopImagesFromArray(int* imageCounter, int numOfImages,
									const int numOfSimilarImg){
    int i, j, maxIndex, maxValue, *res;
    res = (int*)malloc(numOfSimilarImg*sizeof(int));
    if(!res){
        spLoggerPrintError(ALLOC_FAIL, __FILE__, __FUNCTION__, __LINE__);
        return NULL;
    }
    for(i=0; i<numOfSimilarImg; i++){
        maxValue = 0;
        maxIndex = i;
        for(j=0; j<numOfImages; j++){
            if(imageCounter[j]>maxValue){
                maxIndex = j;
                maxValue = imageCounter[j];
            }
        }
        res[i] = maxIndex;
        imageCounter[maxIndex] = NOT_PRESENT;
    }
    return res;
}
SP_CONFIG_MSG readImageFeaturesFromFile(SPPoint** imFeatures, int* numOfFeats,
		SPConfig config, int imageIndex) {
	FILE* featsFile;
	char warning[MAX_SIZE];
	SP_CONFIG_MSG msg = getFeatsFile(config, imageIndex, &featsFile, "r+");
	int i, j;
	if (msg != SP_CONFIG_SUCCESS) {
		sprintf(warning, "Feats file for image number %d doesn't exist\n", imageIndex);
		spLoggerPrintError(warning, __FILE__, __func__, __LINE__);
		return msg;
	}

	fscanf(featsFile, "%d", numOfFeats);

	*imFeatures = (SPPoint*) malloc(sizeof(SPPoint) * *numOfFeats);
	VERIFY_ALLOC(*imFeatures);

	for (i = 0; i < *numOfFeats; i++) {
		int index;
		int dimension;
		fscanf(featsFile, "%d,%d", &index, &dimension);

		double values[dimension];

		for (j = 0; j < dimension; j++) {
			fscanf(featsFile, "%lf", &(values[j]));
		}

		SPPoint point = spPointCreate(values, dimension, index);
		VERIFY_ALLOC(point);
		(*imFeatures)[i] = point;
	}

	fclose(featsFile);
	return SP_CONFIG_SUCCESS;
}
/**
 * A recursive function to construct the kd-tree
 */
KDTreeNode constructTree(KDArray mat, int size, int dim, int splitMethod,
		int lastLevelDim) {
	KDTreeNode newNode;
	KDArray left, right;
	SPPoint* p;
	int splitDim = -1;
	double medianVal;

	assert(size > 0);
	p = kdArrayGetPoints(mat);

	newNode = (KDTreeNode) malloc(sizeof(*newNode));
	if (newNode == NULL )
	{
		spLoggerPrintError(ALLOC_ERROR_MSG, __FILE__, __func__, __LINE__);
		return NULL ;
	}

	if (size == 1) { // creates a new leaf which represents a point
		newNode->dim = -1;
		newNode->val = -1;
		newNode->left = NULL;
		newNode->right = NULL;
		newNode->data = spPointCopy(p[0]);
		return newNode;
	}

	if (splitMethod == 0) { // RANDOM
		srand(time(NULL ));
		splitDim = rand() % dim;
	} else if (splitMethod == 1) { // MAX SPREAD
		double maxSpread;
		int i;

		maxSpread = 0;
		for (i = 0; i < dim; i++) {
			int minIndex, maxIndex;
			double spread;

			minIndex = kdArrayGet(mat, i, 0);
			maxIndex = kdArrayGet(mat, i, size - 1);

			spread = spPointGetAxisCoor(p[maxIndex], i)
					- spPointGetAxisCoor(p[minIndex], i);
			if (spread >= maxSpread) {
				maxSpread = spread;
				splitDim = i;
			}
		}
	} else if (splitMethod == 2) { // INCREMENTAL
		splitDim = (lastLevelDim + 1) % dim;
	}

	left = kdArrayInitEmpty();
	if (left == NULL )
		return NULL ;
	right = kdArrayInitEmpty();
	if (right == NULL )
	{
		kdArrayDestroy(left);
		return NULL ;
	}

	// compute the median to split according to it
	medianVal = spPointGetAxisCoor(p[kdArrayGet(mat, splitDim, (size - 1) / 2)],
			splitDim);

	kdArraySplit(mat, splitDim, left, right);

	newNode->dim = splitDim;
	newNode->val = medianVal;

	// recursively create the left sub-tree
	newNode->left = constructTree(left, kdArrayGetSize(left), dim, splitMethod,
			splitDim);

	// recursively create the right sub-tree
	newNode->right = constructTree(right, kdArrayGetSize(right), dim,
			splitMethod, splitDim);

	newNode->data = NULL; // not a leaf

	// free data not needed anymore
	kdArrayDestroy(left);
	kdArrayDestroy(right);

	return newNode;
}
Beispiel #18
0
int Split(SPKDArray kdArr, int coor, SPKDArray* left_array, SPKDArray* right_array){
	int n;                  		   // number of points in kdArr
	int d;                  	       // number of dimensions of each point in kdArr
	int num_of_left_points;            // number of points that will be in the left half
	int num_of_right_points;           // number of points that will be in the right half
	int* is_index_in_left;              // array of 0's and 1's. value is 1 if the point in this index is in left half
	int* map_indexes;                  // mapping from the indexes of the points in kdArr to the indexes in left or right half
	int helper_function_result;        // holds the result of a call to a helper function
	int index;
	int i, j;
	int L_cnt; //index counter for left_points
	int R_cnt; //index counter for right_points

	//check validation of arguments
	if (coor<0){
		spLoggerPrintError(INVALID_ARG_ERROR, __FILE__, __func__, __LINE__);
		spLoggerPrintDebug(PARAMETER_COOR_INVALID, __FILE__, __func__, __LINE__);
		return -1;
	}

	if (kdArr==NULL){
		spLoggerPrintError(INVALID_ARG_ERROR, __FILE__, __func__, __LINE__);
		spLoggerPrintDebug(PARAMETER_KDARR_INVALID, __FILE__, __func__, __LINE__);
		return -1;
	}

	//initialize n and d
	n = kdArr->n;
	d = kdArr->d;

	//initialize num_of_left_points and num_of_right_points
	if (n%2==0){
		num_of_left_points = n/2;
	}
	else{
		num_of_left_points = (n+1)/2;
	}
	num_of_right_points = n - num_of_left_points;

	//allocate memory for *left_array -> this is creating a new SPKDArray
	if ( (helper_function_result = mallocForNewKdArray(left_array, num_of_left_points, d)) == -1){
		//free memory of left_array is in mallocForNewKdArray
		return -1;
	}

	//allocate memory for *right_array -> this is creating a new SPKDArray
	if ( (helper_function_result = mallocForNewKdArray(right_array, num_of_right_points, d)) == -1){
		//free memory of right_array is in mallocForNewKdArray
		destroyKDArray(*left_array);
		return -1;
	}

	//initialize n and d for left_array and right_array
	(*left_array)->d = d;
	(*left_array)->n = num_of_left_points;
	(*right_array)->d = d;
	(*right_array)->n = num_of_right_points;

	//allocate memory for is_index_in_left
	if ( (is_index_in_left = (int*)malloc(n*sizeof(int))) == NULL){
		spLoggerPrintError(ALLOC_ERROR_MSG, __FILE__, __func__, __LINE__);
		destroyKDArray(*left_array);
		destroyKDArray(*right_array);
		return -1;
	}

	// fill is_index_in_left
	for (i=0; i<num_of_left_points; i++){
		is_index_in_left[kdArr->matrix_of_sorted_indexes[coor][i]] = 1;
	}
	for (i=num_of_left_points; i<n; i++){
		is_index_in_left[kdArr->matrix_of_sorted_indexes[coor][i]] = 0;
	}

	// fill left->array_of_points and right->array_of_points
	L_cnt=0; 		//index counter for left_points
	R_cnt=0; 		//index counter for right_points

	for (i=0; i<n; i++){ 	// i= index counter for is_index_in_left
		if (is_index_in_left[i]==1){
			if( ((*left_array)->array_of_points[L_cnt]= spPointCopy(kdArr->array_of_points[i])) == NULL){
				destroyKDArray(*left_array);
				destroyKDArray(*right_array);
				free(is_index_in_left);
				return -1;
			}
			L_cnt++;
		}
		else{ //is_index_in_left[i]==0
			if( ((*right_array)->array_of_points[R_cnt]= spPointCopy(kdArr->array_of_points[i])) ==NULL){
				destroyKDArray(*left_array);
				destroyKDArray(*right_array);
				free(is_index_in_left);
				return -1;
			}
			R_cnt++;
		}
	}

	//allocate memory for map_indexes
	if ( (map_indexes= (int*)malloc(n*sizeof(int)))==NULL ){
		spLoggerPrintError(ALLOC_ERROR_MSG, __FILE__, __func__, __LINE__);
		destroyKDArray(*left_array);
		destroyKDArray(*right_array);
		free(is_index_in_left);
		return -1;
	}

	//fill map_indexes
	L_cnt=0; //counter for left
	R_cnt=0; //counter for right
	for (i=0; i<n; i++){
		if (is_index_in_left[i]==1){ //i is an index that belongs to left
			map_indexes[i] = L_cnt;
			L_cnt++;
		}
		else{ //i is an index that belongs to right
			map_indexes[i] = R_cnt;
			R_cnt++;
		}
	}

	//fill left_array->matrix_of_sorted_indexes and right_array->matrix_of_sorted_indexes
	L_cnt=0; //counter for left
	R_cnt=0; //counter for right
	for (i=0; i<d; i++){  		//for number of dimensions
		for(j=0; j<n; j++){		//for number of points
			index = kdArr->matrix_of_sorted_indexes[i][j];
			if (is_index_in_left[index]==1){ //the index to map belongs to left
				(*left_array)->matrix_of_sorted_indexes[i][L_cnt] = map_indexes[index];
				L_cnt++;
			}
			else{ //the index to map belongs to right
				(*right_array)->matrix_of_sorted_indexes[i][R_cnt] = map_indexes[index];
				R_cnt++;
			}
		}
		//reset counters
		R_cnt=0;
		L_cnt=0;
	}

	//free memory and return
	free(map_indexes);
	free(is_index_in_left);
	return 1;
}
Beispiel #19
0
SPKDArray Init(SPPoint* arr, int size){
	SPKDArray KDArray;
	int d;                  // d = the dimension of the points (assuming dimension is the same for all points)
	double** index_val_arr; //double array containing n rows. each row contains the index and the value of a specific coordinate in the point of that index
	int i,j;
	int malloc_result;     // holds the result of the call to mallocForNewKdArray


	//check validation of the parameters
	if (size<1){
		spLoggerPrintError(INVALID_ARG_ERROR, __FILE__, __func__, __LINE__);
		spLoggerPrintDebug(PARAMETER_SIZE_INVALID, __FILE__, __func__, __LINE__);
		return NULL;
	}
	if (arr==NULL){
		spLoggerPrintError(INVALID_ARG_ERROR, __FILE__, __func__, __LINE__);
		spLoggerPrintDebug(PARAMETER_ARR_INVALID, __FILE__, __func__, __LINE__);
		return NULL;
	}

	//initialize d
	d = spPointGetDimension(arr[0]);

	// allocate memory for KDArray and its fields
	malloc_result = mallocForNewKdArray(&KDArray, size, d);
	if (malloc_result==-1){
		// the memory freeing would already be done inside mallocForInitKdArray
		return NULL;
	}

	//copy each point from arr to KDArray->array_of_points
	for (i=0; i<size; i++){
		KDArray->array_of_points[i] = spPointCopy(arr[i]); //spPointCopy returns NULL if an allocation error occurred
		if (KDArray->array_of_points[i] == NULL){
			spLoggerPrintError(GENERAL_ERROR_MSG, __FILE__, __func__, __LINE__);
			spLoggerPrintDebug(SPPOINTCOPY_RETURNED_NULL, __FILE__, __func__, __LINE__);
			destroyKDArray(KDArray);
			return NULL;
		}
	}

	//allocate memory for index_val_arr: n rows, 2 columns
	if ( (index_val_arr = (double**)malloc(size*sizeof(double*))) == NULL){
		spLoggerPrintError(ALLOC_ERROR_MSG, __FILE__, __func__, __LINE__);
		destroyKDArray(KDArray);
		return NULL;
	}

	for (i=0; i<size; i++){
		if( (index_val_arr[i]=(double*)malloc(2*sizeof(double))) == NULL){
			spLoggerPrintError(ALLOC_ERROR_MSG, __FILE__, __func__, __LINE__);
			for (j=0; j<i; j++){
				free(index_val_arr[j]);
			}
			free(index_val_arr);
			destroyKDArray(KDArray);
			return NULL;
		}
	}
	// for each coordinate
	for (i=0; i<d; i++){ // i=coordinate

		// fill index and value of coordinate to val_index_arr
		for (j=0; j<size; j++){ //j=index of point
			index_val_arr[j][0] = (double)j;
			index_val_arr[j][1] = spPointGetAxisCoor(arr[j],i);
		}

		/* sort the rows in index_val_arr by the value in the second column,
		 * meaning by the value of the coordinate of each point.
		 * the first column will be the indexes of the points sorted by the values of the coordinate
		 */
		qsort(index_val_arr, size, sizeof(index_val_arr[0]), copmareByValue);

		// fill the sorted indexes in to KDArray->Array
		for (j=0; j<size; j++){ //j=index of point
			KDArray->matrix_of_sorted_indexes[i][j] = (int)index_val_arr[j][0];
		}
	}

	// initialize n and d
	KDArray->n = size;
	KDArray->d = d;

	for (j=0; j<size; j++){
		free(index_val_arr[j]);
	}
	free(index_val_arr);

	return KDArray;
}
Beispiel #20
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;
}
SPPoint* spFeatureExtractFromFeatureFile(const char* filename, int numOfImages,int *numOfFeatures, int *numOfDim){
	FILE *featureFile = NULL;
	SPPoint* featureArray = NULL;
	int i,j, numOfImagesFile;
	char* str = NULL;
	char errorMsg[1025];

	spLoggerPrintInfo("Extracting features from file...");
	if(filename == NULL){
		spLoggerPrintError("filename is NULL", "main.cpp", "main", 184);//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
		return NULL; //ERROR
	}

	featureFile = fopen(filename,"r");
	if (featureFile == NULL){
		sprintf(errorMsg, "The features file %s couldn’t be open", filename);
		spLoggerPrintError(errorMsg, "SPFeaturesFiles.c", "spFeatureExtractFromFeatureFile", 48);
		return NULL; //ERROR
	}
	if(fscanf(featureFile,"%d;;%d;;%d\n",&numOfImagesFile,numOfFeatures,numOfDim) != 3){
		spLoggerPrintError("Wrong feature file format - couldn't read", "SPFeaturesFiles.c", "spFeatureExtractFromFeatureFile", 54);
		return NULL; //ERROR
	}
	if(numOfImages != numOfImagesFile){
		spLoggerPrintError("Number of images from features file isn't matching the given configuration", "SPFeaturesFiles.c", "spFeatureExtractFromFeatureFile", 54);
		return NULL; //ERROR
	}

	featureArray = (SPPoint*) malloc(*numOfFeatures * sizeof(SPPoint));
	if(featureArray == NULL){
		spLoggerPrintError("Memory Allocation Failure", "SPFeaturesFiles.c", "spFeatureExtractFromFeatureFile", 63);
		return NULL; //ERROR
	}

	for (i = 0; i < *numOfFeatures; ++i) {
		int imgIndex;
		double *coorArray;
		coorArray = (double*) malloc(*numOfDim * sizeof(double));
		if(coorArray == NULL){
			spLoggerPrintError("Memory Allocation Failure", "SPFeaturesFiles.c", "spFeatureExtractFromFeatureFile", 72);
			return NULL; //ERROR
		}
		if(fscanf(featureFile,"%d;;",&imgIndex) != 1){
			spLoggerPrintError("Wrong feature file format - couldn't read", "SPFeaturesFiles.c", "spFeatureExtractFromFeatureFile", 77);
			return NULL; //ERROR
		}

		for (j = 0; j < *numOfDim-1; ++j) {
			if(fscanf(featureFile,"%lf;;",&coorArray[j]) != 1){
				spLoggerPrintError("Wrong feature file format - couldn't read", "SPFeaturesFiles.c", "spFeatureExtractFromFeatureFile", 83);
				return NULL; //ERROR
			}
		}
		if(fscanf(featureFile,"%lf;;\n",&coorArray[*numOfDim - 1]) != 1){
			spLoggerPrintError("Wrong feature file format - couldn't read", "SPFeaturesFiles.c", "spFeatureExtractFromFeatureFile", 88);
			return NULL; //ERROR
		}

		featureArray[i] = spPointCreate(coorArray, *numOfDim, imgIndex);
		if(featureArray[i] == NULL){
			spLoggerPrintError("Memory Allocation Failure", "SPFeaturesFiles.c", "spFeatureExtractFromFeatureFile", 94);
			return NULL; //ERROR
		}
		free(coorArray);
	}
	if(fscanf(featureFile,"%s",str) == 1){
		spLoggerPrintError("Wrong feature file format - couldn't read", "SPFeaturesFiles.c", "spFeatureExtractFromFeatureFile", 100);
		return NULL; //ERROR
	}
	spLoggerPrintInfo("Done extracting features from file");
	fclose(featureFile);
	return featureArray;
}