Exemple #1
1
int main()
{
#ifdef SIFTGPU_DLL_RUNTIME
    #ifdef _WIN32
        #ifdef _DEBUG
            HMODULE  hsiftgpu = LoadLibrary("siftgpu_d.dll");
        #else
            HMODULE  hsiftgpu = LoadLibrary("siftgpu.dll");
        #endif
    #else
        void * hsiftgpu = dlopen("libsiftgpu.so", RTLD_LAZY);
    #endif

    if(hsiftgpu == NULL) return 0;

    #ifdef REMOTE_SIFTGPU
        ComboSiftGPU* (*pCreateRemoteSiftGPU) (int, char*) = NULL;
        pCreateRemoteSiftGPU = (ComboSiftGPU* (*) (int, char*)) GET_MYPROC(hsiftgpu, "CreateRemoteSiftGPU");
        ComboSiftGPU * combo = pCreateRemoteSiftGPU(REMOTE_SERVER_PORT, REMOTE_SERVER);
        SiftGPU* sift = combo;
        SiftMatchGPU* matcher = combo;
    #else
        SiftGPU* (*pCreateNewSiftGPU)(int) = NULL;
        SiftMatchGPU* (*pCreateNewSiftMatchGPU)(int) = NULL;
        pCreateNewSiftGPU = (SiftGPU* (*) (int)) GET_MYPROC(hsiftgpu, "CreateNewSiftGPU");
        pCreateNewSiftMatchGPU = (SiftMatchGPU* (*)(int)) GET_MYPROC(hsiftgpu, "CreateNewSiftMatchGPU");
        SiftGPU* sift = pCreateNewSiftGPU(1);
        SiftMatchGPU* matcher = pCreateNewSiftMatchGPU(4096);
    #endif

#elif defined(REMOTE_SIFTGPU)
    ComboSiftGPU * combo = CreateRemoteSiftGPU(REMOTE_SERVER_PORT, REMOTE_SERVER);
    SiftGPU* sift = combo;
    SiftMatchGPU* matcher = combo;
#else
    //this will use overloaded new operators
    SiftGPU  *sift = new SiftGPU;
    SiftMatchGPU *matcher = new SiftMatchGPU(4096);
#endif
    vector<float > descriptors1(1), descriptors2(1);
    vector<SiftGPU::SiftKeypoint> keys1(1), keys2(1);    
    int num1 = 0, num2 = 0;

    //process parameters
    //The following parameters are default in V340
    //-m,       up to 2 orientations for each feature (change to single orientation by using -m 1)
    //-s        enable subpixel subscale (disable by using -s 0)
    

    char * argv[] = {"-fo", "-1",  "-v", "1"};//
    //-fo -1    staring from -1 octave 
    //-v 1      only print out # feature and overall time
    //-loweo    add a (.5, .5) offset
    //-tc <num> set a soft limit to number of detected features
    
    //NEW:  parameters for  GPU-selection
    //1. CUDA.                   Use parameter "-cuda", "[device_id]"
    //2. OpenGL.				 Use "-Display", "display_name" to select monitor/GPU (XLIB/GLUT)
	//   		                 on windows the display name would be something like \\.\DISPLAY4

    //////////////////////////////////////////////////////////////////////////////////////
    //You use CUDA for nVidia graphic cards by specifying
    //-cuda   : cuda implementation (fastest for smaller images)
    //          CUDA-implementation allows you to create multiple instances for multiple threads
	//          Checkout src\TestWin\MultiThreadSIFT
    /////////////////////////////////////////////////////////////////////////////////////

    //////////////////////////////////////////////////////////////////////////////////////
    ////////////////////////Two Important Parameters///////////////////////////
    // First, texture reallocation happens when image size increases, and too many 
    // reallocation may lead to allocatoin failure.  You should be careful when using 
    // siftgpu on a set of images with VARYING imag sizes. It is recommended that you 
    // preset the allocation size to the largest width and largest height by using function
    // AllocationPyramid or prameter '-p' (e.g. "-p", "1024x768").

    // Second, there is a parameter you may not be aware of: the allowed maximum working
    // dimension. All the SIFT octaves that needs a larger texture size will be skipped.
    // The default prameter is 2560 for the unpacked implementation and 3200 for the packed.
    // Those two default parameter is tuned to for 768MB of graphic memory. You should adjust
    // it for your own GPU memory. You can also use this to keep/skip the small featuers.
    // To change this, call function SetMaxDimension or use parameter "-maxd".
	//
	// NEW: by default SiftGPU will try to fit the cap of GPU memory, and reduce the working 
	// dimension so as to not allocate too much. This feature can be disabled by -nomc
    //////////////////////////////////////////////////////////////////////////////////////


    int argc = sizeof(argv)/sizeof(char*);
    sift->ParseParam(argc, argv);
    
    ///////////////////////////////////////////////////////////////////////
    //Only the following parameters can be changed after initialization (by calling ParseParam). 
    //-dw, -ofix, -ofix-not, -fo, -unn, -maxd, -b
    //to change other parameters at runtime, you need to first unload the dynamically loaded libaray
    //reload the libarary, then create a new siftgpu instance


    //Create a context for computation, and SiftGPU will be initialized automatically 
    //The same context can be used by SiftMatchGPU
    if(sift->CreateContextGL() != SiftGPU::SIFTGPU_FULL_SUPPORTED) return 0;

    if(sift->RunSIFT("../data/800-1.jpg"))
    {
        //Call SaveSIFT to save result to file, the format is the same as Lowe's
        //sift->SaveSIFT("../data/800-1.sift"); //Note that saving ASCII format is slow

        //get feature count
        num1 = sift->GetFeatureNum();

        //allocate memory
        keys1.resize(num1);    descriptors1.resize(128*num1);

        //reading back feature vectors is faster than writing files
        //if you dont need keys or descriptors, just put NULLs here
        sift->GetFeatureVector(&keys1[0], &descriptors1[0]);
        //this can be used to write your own sift file.            
    }

    //You can have at most one OpenGL-based SiftGPU (per process).
    //Normally, you should just create one, and reuse on all images. 
    if(sift->RunSIFT("../data/640-1.jpg"))
    {
        num2 = sift->GetFeatureNum();
        keys2.resize(num2);    descriptors2.resize(128*num2);
        sift->GetFeatureVector(&keys2[0], &descriptors2[0]);
    }

    //Testing code to check how it works when image size varies
    //sift->RunSIFT("../data/256.jpg");sift->SaveSIFT("../data/256.sift.1");
    //sift->RunSIFT("../data/1024.jpg"); //this will result in pyramid reallocation
    //sift->RunSIFT("../data/256.jpg"); sift->SaveSIFT("../data/256.sift.2");
    //two sets of features for 256.jpg may have different order due to implementation
 
    //*************************************************************************
    /////compute descriptors for user-specified keypoints (with or without orientations)

    //Method1, set new keypoints for the image you've just processed with siftgpu
    //say vector<SiftGPU::SiftKeypoint> mykeys;
    //sift->RunSIFT(mykeys.size(), &mykeys[0]); 
    //sift->RunSIFT(num2, &keys2[0], 1);         sift->SaveSIFT("../data/640-1.sift.2");
    //sift->RunSIFT(num2, &keys2[0], 0);        sift->SaveSIFT("../data/640-1.sift.3");

    //Method2, set keypoints for the next coming image
    //The difference of with method 1 is that method 1 skips gaussian filtering
    //SiftGPU::SiftKeypoint mykeys[100];
    //for(int i = 0; i < 100; ++i){
    //    mykeys[i].s = 1.0f;mykeys[i].o = 0.0f;
    //    mykeys[i].x = (i%10)*10.0f+50.0f;
    //    mykeys[i].y = (i/10)*10.0f+50.0f;
    //}
    //sift->SetKeypointList(100, mykeys, 0);
    //sift->RunSIFT("../data/800-1.jpg");                    sift->SaveSIFT("../data/800-1.sift.2");
    //### for comparing with method1: 
    //sift->RunSIFT("../data/800-1.jpg"); 
    //sift->RunSIFT(100, mykeys, 0);                          sift->SaveSIFT("../data/800-1.sift.3");
    //*********************************************************************************


    //**********************GPU SIFT MATCHING*********************************
    //**************************select shader language*************************
    //SiftMatchGPU will use the same shader lanaguage as SiftGPU by default
    //Before initialization, you can choose between glsl, and CUDA(if compiled). 
    //matcher->SetLanguage(SiftMatchGPU::SIFTMATCH_CUDA); // +i for the (i+1)-th device

    //Verify current OpenGL Context and initialize the Matcher;
    //If you don't have an OpenGL Context, call matcher->CreateContextGL instead;
    matcher->VerifyContextGL(); //must call once

    //Set descriptors to match, the first argument must be either 0 or 1
    //if you want to use more than 4096 or less than 4096
    //call matcher->SetMaxSift() to change the limit before calling setdescriptor
    matcher->SetDescriptors(0, num1, &descriptors1[0]); //image 1
    matcher->SetDescriptors(1, num2, &descriptors2[0]); //image 2

    //match and get result.    
    int (*match_buf)[2] = new int[num1][2];
    //use the default thresholds. Check the declaration in SiftGPU.h
    int num_match = matcher->GetSiftMatch(num1, match_buf);
    std::cout << num_match << " sift matches were found;\n";
    
    //enumerate all the feature matches
    for(int i  = 0; i < num_match; ++i)
    {
        //How to get the feature matches: 
        //SiftGPU::SiftKeypoint & key1 = keys1[match_buf[i][0]];
        //SiftGPU::SiftKeypoint & key2 = keys2[match_buf[i][1]];
        //key1 in the first image matches with key2 in the second image
    }

    //*****************GPU Guided SIFT MATCHING***************
    //example: define a homography, and use default threshold 32 to search in a 64x64 window
    //float h[3][3] = {{0.8f, 0, 0}, {0, 0.8f, 0}, {0, 0, 1.0f}};
    //matcher->SetFeatureLocation(0, &keys1[0]); //SetFeatureLocaiton after SetDescriptors
    //matcher->SetFeatureLocation(1, &keys2[0]);
    //num_match = matcher->GetGuidedSiftMatch(num1, match_buf, h, NULL);
    //std::cout << num_match << " guided sift matches were found;\n";
    //if you can want to use a Fundamental matrix, check the function definition

    // clean up..
    delete[] match_buf;
#ifdef REMOTE_SIFTGPU
    delete combo;
#else
    delete sift;
    delete matcher;
#endif

#ifdef SIFTGPU_DLL_RUNTIME
    FREE_MYLIB(hsiftgpu);
#endif
    return 1;
}
inline void ServerSiftGPU::ServerLoop(int port, int argc, char** argv)
{
	SOCKET sockfd, newsockfd;	
	struct	sockaddr_in	serv_addr, cli_addr;
	socklen_t addr_len = sizeof(sockaddr_in);
	//////////////////////////////////////////////////
	memset((char*)&serv_addr, 0, sizeof(serv_addr));
	serv_addr.sin_family	= AF_INET;
	serv_addr.sin_port	= htons(port);
	serv_addr.sin_addr.s_addr = INADDR_ANY;
	/////////////////////////////////////////////

    if(ServerSiftGPU::InitSocket() == 0)
	{
		return;
	}
	//////////////////////////////////////////////////////////////
	sockfd=socket(AF_INET,SOCK_STREAM,0);
	if(sockfd==INVALID_SOCKET) 
	{
		std::cout << "server: can't open stream socket\n";
		return;
	}else if(bind(sockfd,(struct sockaddr*)&serv_addr, sizeof(serv_addr)))
    {
	    std::cout << "server: can't bind to port " <<  port <<"\n";
	    return;
    }else if(listen(sockfd, 1))
	{
		std::cout << "server: failed to listen\n";
		return;
	}else
	{
		std::cout << "server: listent to port "<< port << "\n";
	}
		
	newsockfd = accept(sockfd, (struct sockaddr*) &cli_addr, &addr_len);
	if(newsockfd == INVALID_SOCKET)
	{
		std::cout << "error: accept failed\n";
        closesocket(sockfd);
		return;
	}
	////////////////////////////////////////////////////////////////
	char buf[1024];
	int command, result;
	int sift_feature_count = 0;;
	vector<SiftGPU::SiftKeypoint> keys;
	vector<float> descriptors;
	vector<char> databuf;

	/////////////////////////////////////////////////////////////////
	SiftGPU siftgpu;
	SiftMatchGPU matcher;

	if(argc > 0) siftgpu.ParseParam(argc, argv);
    
	/////////////////////
	siftgpu.SetVerbose(0);
	/////////////////////////////////////////////////////////////////

    do
    {
	    while(SocketUtil::readint(newsockfd, &command) && command != COMMAND_DISCONNECT)
	    {
		    switch(command)
		    {
			case COMMAND_INITIALIZE:
				{
				    result = (siftgpu.CreateContextGL() == SiftGPU::SIFTGPU_FULL_SUPPORTED);
				    SocketUtil::writeint(newsockfd, result);
				    if(result)	break;
				}
            case COMMAND_EXIT:
                closesocket(newsockfd);
                closesocket(sockfd);
                return;
		    case COMMAND_ALLOCATE_PYRAMID:
			    {
				    int size[2];
				    SocketUtil::readint(newsockfd, size, 2);
				    if(size[0] > 0 && size[1] > 0) siftgpu.AllocatePyramid(size[0], size[1]);
				    break;
			    }
		    case COMMAND_GET_KEY_VECTOR:
			    {
				    int size = sift_feature_count * sizeof(SiftGPU::SiftKeypoint);
				    SocketUtil::writedata(newsockfd, &keys[0], size);
				    break;
			    }
		    case COMMAND_GET_DES_VECTOR:
			    {
				    int size = sift_feature_count * sizeof(float) * 128;
				    SocketUtil::writedata(newsockfd, &descriptors[0], size);
				    break;
			    }
		    case COMMAND_RUNSIFT:
			    {
				    result = siftgpu.RunSIFT();
				    if((sift_feature_count = siftgpu.GetFeatureNum()) > 0)
				    {
					    keys.resize(sift_feature_count);
					    descriptors.resize(sift_feature_count * 128);
					    siftgpu.GetFeatureVector(&keys[0], &descriptors[0]);
						std::cout << "RunSIFT: [-] [" << sift_feature_count << "]\n";
				    }
				    SocketUtil::writeint(newsockfd, result);
				    break;
			    }
		    case COMMAND_RUNSIFT_FILE:
			    {
				    SocketUtil::readline(newsockfd, buf, 1024);

				    result = siftgpu.RunSIFT(buf);
				    if((sift_feature_count = siftgpu.GetFeatureNum()) > 0)
				    {
					    keys.resize(sift_feature_count);
					    descriptors.resize(sift_feature_count * 128);
					    siftgpu.GetFeatureVector(&keys[0], &descriptors[0]);
				    }
					std::cout << "RunSIFT: "<< buf <<" " << sift_feature_count << "\n" ;
				    SocketUtil::writeint(newsockfd, result);
				    break;
			    }
		    case COMMAND_SET_KEYPOINT:
			    {
				    int keys_have_orientation;
				    SocketUtil::readint(newsockfd, &sift_feature_count);
				    SocketUtil::readint(newsockfd, &keys_have_orientation);
				    if(sift_feature_count > 0)
				    {
					    keys.resize(sift_feature_count);
					    descriptors.resize(sift_feature_count * 128);
						SocketUtil::readdata(newsockfd, &keys[0], int(keys.size() * sizeof(SiftGPU::SiftKeypoint)));
					    siftgpu.SetKeypointList(sift_feature_count, &keys[0], keys_have_orientation);
				    }
				    break;
			    }
		    case COMMAND_RUNSIFT_KEY:
			    {
				    int keys_have_orientation;
				    SocketUtil::readint(newsockfd, &sift_feature_count);
				    SocketUtil::readint(newsockfd, &keys_have_orientation);
				    if(sift_feature_count > 0)
				    {
						std::cout << "RunSIFT: "<< sift_feature_count << " KEYPOINTS\n" ;
					    int key_data_size = sift_feature_count * sizeof(SiftGPU::SiftKeypoint);
					    keys.resize(sift_feature_count);
					    descriptors.resize(sift_feature_count * 128);
					    SocketUtil::readdata(newsockfd, &keys[0], key_data_size);
					    result = siftgpu.RunSIFT(sift_feature_count, &keys[0], keys_have_orientation);
					    siftgpu.GetFeatureVector(NULL, &descriptors[0]);
				    }else
				    {
					    result = 0;
				    }
				    SocketUtil::writeint(newsockfd, result);
				    break;
			    }
		    case COMMAND_RUNSIFT_DATA:
			    {
				    int data_des[4], size = 0;	
				    SocketUtil::readint(newsockfd, data_des, 4);
					SocketUtil::readint(newsockfd, &size, 1);
					std::cout << "RunSIFT: [" << data_des[0] << "x" << data_des[1] << "]";

					databuf.resize(size);
					void* data_ptr = &databuf[0];
					SocketUtil::readdata(newsockfd, data_ptr, size);


				    result = siftgpu.RunSIFT(data_des[0], data_des[1], data_ptr, data_des[2], data_des[3]);
				    if((sift_feature_count = siftgpu.GetFeatureNum()) > 0)
				    {
					    keys.resize(sift_feature_count);
					    descriptors.resize(sift_feature_count * 128);
					    siftgpu.GetFeatureVector(&keys[0], &descriptors[0]);
				    }
					std::cout << "[" << sift_feature_count << "]\n";
				    SocketUtil::writeint(newsockfd, result);
				    break;
			    }
		    case COMMAND_SAVE_SIFT:
			    {
				    SocketUtil::readline(newsockfd, buf, 1024);
				    siftgpu.SaveSIFT(buf);
				    break;
			    }
		    case COMMAND_SET_MAX_DIMENSION:
			    {
				    int maxd;
				    if(SocketUtil::readint(newsockfd, &maxd) && maxd > 0) siftgpu.SetMaxDimension(maxd);
				    break;
			    }
		    case COMMAND_SET_TIGHTPYRAMID:
			    {
				    int tight;
				    if(SocketUtil::readint(newsockfd, &tight))  siftgpu.SetTightPyramid(tight);
				    break;
			    }
		    case COMMAND_GET_FEATURE_COUNT:
			    {
				    SocketUtil::writeint(newsockfd, sift_feature_count);
				    break;
			    }
			case COMMAND_PARSE_PARAM:
				{
				    SocketUtil::readline(newsockfd, buf, 1024);
					std::cout << "ParseParam [" << buf << "]\n";
					vector<char*> params;
					char* p = buf;
					while(*p)
					{
						while(*p == ' ' || *p == '\t')*p++ = 0;
						params.push_back(p);
						while(*p && *p != ' ' && *p != '\t') p++;
					}
					siftgpu.ParseParam(params.size(), &params[0]);
					break;
				}
			case COMMAND_MATCH_INITIALIZE:
				{
					result = matcher.CreateContextGL();
					SocketUtil::writeint(newsockfd, result);
					break;
				}
			case COMMAND_MATCH_SET_LANGUAGE:
				{
					int language;
					if(SocketUtil::readint(newsockfd, &language)) matcher.SetLanguage(language);
					break;
				}
			case COMMAND_MATCH_SET_DES_FLOAT:
				{
					int command[3] = {0, 0, 0};
					if(SocketUtil::readdata(newsockfd, command, sizeof(command)))
					{
						databuf.resize(sizeof(float) * 128 * command[1]);
						if(SocketUtil::readdata(newsockfd, &databuf[0], databuf.size()))
						{
							matcher.SetDescriptors(command[0], command[1], (float*) (&databuf[0]), command[2]);	
						}
					}
					break;
				}
			case COMMAND_MATCH_SET_DES_BYTE:
				{
					int command[3] = {0, 0, 0};
					if(SocketUtil::readdata(newsockfd, command, sizeof(command)))
					{
						databuf.resize(sizeof(unsigned char) * 128 * command[1]);
						if(SocketUtil::readdata(newsockfd, &databuf[0], databuf.size()))
						{
							matcher.SetDescriptors(command[0], command[1], (unsigned char*) (&databuf[0]), command[2]);	
						}
					}
					break;
				}
			case COMMAND_MATCH_GET_MATCH:
				{
					int command[2]; float fcommand[2];
					result = 0;
					if( SocketUtil::readdata(newsockfd, command, sizeof(command)) &&
						SocketUtil::readdata(newsockfd, fcommand, sizeof(fcommand)))
					{
						int max_match  = command[0], mbm = command[1];
						float distmax = fcommand[0], ratiomax = fcommand[1];
						databuf.resize(max_match * 2 * sizeof(int));
						result = matcher.GetSiftMatch(max_match, ( int(*)[2]) (&databuf[0]), distmax, ratiomax, mbm);

					}
					SocketUtil::writeint(newsockfd, result);
					if(result > 0) SocketUtil::writedata(newsockfd, &databuf[0], sizeof(int) * 2 * result);
					std::cout << "SiftMatch: " <<  result << "\n"; 
					break;
				}
			case COMMAND_MATCH_SET_MAXSIFT:
				{
					int max_sift;
					if(SocketUtil::readint(newsockfd, &max_sift)) matcher.SetMaxSift(max_sift);
					break;
				}
				break;
		    default:
			    std::cout << "unrecognized command: " << command << "\n";
				break;
		    }
	    }

        //client disconneted
        closesocket(newsockfd);
        //wait for the next client.
        std::cout << "wait for new client...";
	    newsockfd = accept(sockfd, (struct sockaddr*) &cli_addr, &addr_len);
	    if(newsockfd == INVALID_SOCKET)
	    {
		    std::cout << "error: accept failed";
            closesocket(sockfd);
		    return;
	    }else
        {
            std::cout << "connected\n\n";
        }
   }while(1);
}
Exemple #3
0
void GPUSiftDetector::operator ()(const Mat1b &img,
                                  const Mat &mask,
                                  std::vector<KeyPoint> &keypoints,
                                  std::vector<float> &descriptors) const
{
  SiftGPU* sift = getSiftGPUInstance();
  ntk_ensure(sift, "Cannot use SiftGPU");

  std::vector<SiftGPU::SiftKeypoint> gpu_keypoints;

  bool ok = sift->RunSIFT(img);

  int n_features = sift->GetFeatureNum();
  gpu_keypoints.resize(n_features);
  descriptors.resize(128*n_features);
  sift->GetFeatureVector(&gpu_keypoints[0], &descriptors[0]);

  keypoints.resize(n_features);
  for (int i = 0; i < n_features; ++i)
  {
    cv::KeyPoint& location = keypoints[i];
    location.pt = Point2f(gpu_keypoints[i].x, gpu_keypoints[i].y);
    location.angle = gpu_keypoints[i].o;
    location.octave = gpu_keypoints[i].s;
    location.size = gpu_keypoints[i].s * 16;
  }
}
/***Method 1, set new keypoints for the image you've just processed with siftgpu*/
void LoadMyKeyPoints1(SiftGPU& sift, vector<SiftGPU::SiftKeypoint>& keys2, int num2, vector<SiftGPU::SiftKeypoint>& mykeys)
{
	sift.RunSIFT(mykeys.size(),&mykeys[0]);
	sift.RunSIFT(num2,&keys2[0],1);		
        sift.SaveSIFT("../640-1.sift.2");
	sift.RunSIFT(num2,&keys2[0],0);		
        sift.SaveSIFT("../640-1.sift.3");
}
int main(void)
{
SiftGPU sift;
char *argv[]={"-fo","-l","-v","l"};
sift.ParseParam(4,argv);
int support = sift.CreateContextGL();
if(support!=SiftGPU::SIFTGPU_FULL_SUPPORTED) return 0;
return 0;
}
Exemple #6
0
int main(int argc, char * argv[])
{
#ifdef SIFTGPU_DLL_RUNTIME
    #ifdef _WIN32
        #ifdef _DEBUG
            HMODULE  hsiftgpu = LoadLibrary("siftgpu_d.dll");
        #else
            HMODULE  hsiftgpu = LoadLibrary("siftgpu.dll");
        #endif
    #else
        void * hsiftgpu = dlopen("../bin/libsiftgpu.so", RTLD_LAZY);
    #endif

    if(hsiftgpu == NULL) return 0;

    #ifdef REMOTE_SIFTGPU
        ComboSiftGPU* (*pCreateRemoteSiftGPU) (int, char*) = NULL;
        pCreateRemoteSiftGPU = (ComboSiftGPU* (*) (int, char*)) GET_MYPROC(hsiftgpu, "CreateRemoteSiftGPU");
        ComboSiftGPU * combo = pCreateRemoteSiftGPU(REMOTE_SERVER_PORT, REMOTE_SERVER);
        SiftGPU* sift = combo;
        SiftMatchGPU* matcher = combo;
    #else
        SiftGPU* (*pCreateNewSiftGPU)(int) = NULL;
        SiftMatchGPU* (*pCreateNewSiftMatchGPU)(int) = NULL;
        pCreateNewSiftGPU = (SiftGPU* (*) (int)) GET_MYPROC(hsiftgpu, "CreateNewSiftGPU");
        pCreateNewSiftMatchGPU = (SiftMatchGPU* (*)(int)) GET_MYPROC(hsiftgpu, "CreateNewSiftMatchGPU");
        SiftGPU* sift = pCreateNewSiftGPU(1);
        SiftMatchGPU* matcher = pCreateNewSiftMatchGPU(4096);
    #endif

#elif defined(REMOTE_SIFTGPU)
    ComboSiftGPU * combo = CreateRemoteSiftGPU(REMOTE_SERVER_PORT, REMOTE_SERVER);
    SiftGPU* sift = combo;
    SiftMatchGPU* matcher = combo;
#else
    //this will use overloaded new operators
    SiftGPU  *sift = new SiftGPU;
    SiftMatchGPU *matcher = new SiftMatchGPU(4096);
#endif
    vector<float > descriptors1(1), descriptors2(1);
    vector<SiftGPU::SiftKeypoint> keys1(1), keys2(1);
    int num1 = 0, num2 = 0;
    float start,all;
    char * argw[] = {"-fo", "-1",  "-v", "0","-t","0.03","-cuda","0","-maxd","3200"};

    string directory=argv[1]; //"../../../Rendimiento/Imagenes/Imagenes_2";
    vector<string> images;
    vector<string> detections;
    const string slash = "/";
    if(listFilesDirectory(images, directory))
    {
        cout << "ERROR:finish Main"<<"\n" <<endl;
        return -1;
    }
    for(unsigned int i=0; i < images.size(); i++)
    {
        int lastindex = images[i].find_last_of(".");
        string imagesPath = directory + slash + images[i];
        string outputPath = images[i].substr(images[i].rfind("/")+1,lastindex).append(".sift");
        string detectsPath = directory + slash + outputPath;
        detections.push_back(detectsPath);
        images[i] = imagesPath;
    }
    int argd = sizeof(argw)/sizeof(char*);
    sift->ParseParam(argd, argw);
    if(sift->CreateContextGL() != SiftGPU::SIFTGPU_FULL_SUPPORTED) return 0;
    //start=(float)getMilliSecond();
    for(unsigned int i=0; i < images.size(); i++)
    {
        const char * imgPath = images[i].c_str();
        sift->RunSIFT(imgPath);
        sift->RunSIFT(num2, &keys2[0], 0);
        string siftStr = detections[i];
        const char * siftPath =siftStr.c_str();
        sift->SaveSIFT(siftPath);
    }
    //getHumanReadableTime(start);
}
int main(int argc, char * argv[])
{
#ifndef TEST_MULTI_PROCESS_SIFTGPU
	SiftGPU sift;
#else
	ComboSiftGPU* combo = CreateRemoteSiftGPU();
	SiftGPU& sift = (*combo);
#endif
	int num;
	float timing[10], time_all =0, time_start;

	//Parse parameters
	sift.ParseParam(argc - 1, argv + 1);
	sift.SetVerbose(0); 

	std::cout<<"Initialize and warm up...\n";
	//create an OpenGL context for computation
	if(sift.CreateContextGL() ==0) return 0;
	
	if(sift.RunSIFT()==0)	return 0;

	//image is loaded for only once for this experiment
#ifndef TEST_MULTI_PROCESS_SIFTGPU
	std::cout<<"Loading image: " << sift._timing[0]*1000 << "ms, "
	         <<"Tex initialization: "<<sift._timing[1]*1000 << "ms\n\n"
	         <<"Start 2x"<<SIFTGPU_REPEAT<<" repetitions...\n";
#ifdef INCLUDE_DISK_READING_TIME
    char imagepath[MAX_PATH];
    strcpy(imagepath, sift.GetCurrentImagePath()); 
#endif
#endif

	//run one more time to get all texture allocated

	sift.RunSIFT();
	num = sift.GetFeatureNum();


	//use no message output mode to get maximum speed.
	time_start = (float) GetMilliSecond();
	for(int i = 0; i < SIFTGPU_REPEAT; i++)
	{
#ifdef INCLUDE_DISK_READING_TIME
        sift.RunSIFT(imagepath);
#else
		sift.RunSIFT();
#endif
		if(sift.GetFeatureNum()==num) std::cout <<"+";
		else std::cout << "e";
	}
	time_all = ((float)GetMilliSecond() - time_start)/1000/SIFTGPU_REPEAT;
	std::cout<<"\n"; 

	//change the timing setting, so that we can get more accurate timing for each steps
	//in this mode, the overal speed will be decreased.
	sift.SetVerbose(-2); //little trick to disable all output but keep the timing
	std::fill(timing, timing + 10, 0.0f);
	for(int k = 0; k < SIFTGPU_REPEAT; k++)
	{
#ifdef INCLUDE_DISK_READING_TIME
        sift.RunSIFT(imagepath);
#else
		sift.RunSIFT();
#endif
		for(int j = 0; j < 10; j++)		timing[j] += sift._timing[j];
		if(sift.GetFeatureNum()==num) std::cout <<"#";
		else std::cout << "e";
	}
	for(int j = 0; j < 10; j++) 	timing[j] /= SIFTGPU_REPEAT;

	std::cout
		<<"\n\n****************************************\n"
		<<"[Feature Count]:\t" << num << "\n"
		<<"[Average Time]:\t\t" << time_all * 1000.0f << "ms\n"
		<<"[Average Speed]:\t" << 1.0 / time_all << "hz\n"
#ifndef TEST_MULTI_PROCESS_SIFTGPU
#ifdef INCLUDE_DISK_READING_TIME
		<<"[Load Image File]:\t" << timing[0] * 1000.0f << "ms\n"
#endif
		<<"[Build Pyramid]:\t" << timing[2] * 1000.0f << "ms\n"
		<<"[Detection]:\t\t" << timing[3] * 1000.0f << "ms\n"
		<<"[Feature List]:\t\t" << timing[4] * 1000.0f << "ms\n"
		<<"[Orientation]:\t\t" << timing[5] * 1000.0f << "ms\n"
		<<"[MO Feature List]:\t" << timing[6] * 1000.0f << "ms\n"
		<<"[Download Keys]:\t" << timing[7] * 1000.0f << "ms\n"
		<<"[Descriptor]:\t\t" << timing[8] * 1000.0f << "ms\n"
#endif
		<<"****************************************\n";

#ifdef TEST_MULTI_PROCESS_SIFTGPU
	delete combo;
#endif

	return 0;
}