⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 simplesift.cpp

📁 SiftGPU is an implementation of SIFT [1] for GPU. SiftGPU processes pixels parallely to build Gaussi
💻 CPP
字号:
////////////////////////////////////////////////////////////////////////////
//	File:		SimpleSIFT.cpp
//	Author:		Changchang Wu
//	Description : A simple example shows how to use SiftGPU and SiftMatchGPU
//
//
//
//	Copyright (c) 2007 University of North Carolina at Chapel Hill
//	All Rights Reserved
//
//	Permission to use, copy, modify and distribute this software and its
//	documentation for educational, research and non-profit purposes, without
//	fee, and without a written agreement is hereby granted, provided that the
//	above copyright notice and the following paragraph appear in all copies.
//	
//	The University of North Carolina at Chapel Hill make no representations
//	about the suitability of this software for any purpose. It is provided
//	'as is' without express or implied warranty. 
//
//	Please send BUG REPORTS to ccwu@cs.unc.edu
//
////////////////////////////////////////////////////////////////////////////


#include <stdlib.h>
#include <vector>
#include <iostream>
using std::vector;
using std::iostream;

//Load at runtime if defined
#define SIFTGPU_DLL_RUNTIME

#ifdef _WIN32
	#ifdef SIFTGPU_DLL_RUNTIME
		#define WIN32_LEAN_AND_MEAN
		#include <windows.h>
	#else
		//dll import definition for win32
		#define SIFTGPU_DLL
		#ifdef _DEBUG
			#pragma comment(lib, "../lib/siftgpu_d.lib")
		#else
			#pragma comment(lib, "../lib/siftgpu.lib")
		#endif
	#endif
#else
	#ifdef SIFTGPU_DLL_RUNTIME
		#include <dlfcn.h>
	#endif
#endif

#include "../../SiftGPU/src/SiftGPU.h"


int main()
{
#ifdef SIFTGPU_DLL_RUNTIME

	SiftGPU* (*pCreateNewSiftGPU)(int) = NULL;
	SiftMatchGPU* (*pCreateNewSiftMatchGPU)(int) = NULL;

	#ifdef _WIN32
		#ifdef _DEBUG
			HMODULE  hsiftgpu = LoadLibrary("siftgpu_d.dll");
		#else
			HMODULE  hsiftgpu = LoadLibrary("siftgpu.dll");
		#endif
		if(hsiftgpu == NULL) return 0;
		pCreateNewSiftGPU = (SiftGPU* (*) (int)) GetProcAddress(hsiftgpu, "CreateNewSiftGPU");
		pCreateNewSiftMatchGPU = (SiftMatchGPU* (*)(int)) GetProcAddress(hsiftgpu, "CreateNewSiftMatchGPU");
	#else
		void * hsiftgpu = dlopen("libsiftgpu.so", RTLD_LAZY);
		if(hsiftgpu == NULL) return 0;
		pCreateNewSiftGPU =  (SiftGPU* (*) (int)) dlsym(hsiftgpu, "CreateNewSiftGPU");
		pCreateNewSiftMatchGPU = (SiftMatchGPU* (*)(int)) dlsym(hsiftgpu, "CreateNewSiftMatchGPU");
	#endif
	SiftGPU* sift = pCreateNewSiftGPU(1);
	SiftMatchGPU* matcher = pCreateNewSiftMatchGPU(4096); 
#else
	//this will use overloaded new operators
	SiftGPU  *sift = new SiftGPU;
	SiftMatchGPU *matcher = new SiftMatchGPU(4096);
#endif
	vector<float > descriptors1, descriptors2;
	vector<SiftGPU::SiftKeypoint> keys1, keys2;	
	int num1, num2;

	//process parameters
	//The following parameters are now 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)
	//-pack		use packed implementation (use the old unpacked version by using -unpack)
	//-glsl     use GLSL instead of CG
	

	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

	//***If GLSL has problems or works slow, you can switch back to CG using "-cg" ***/
	
	//////////////////////////////////////////////////////////////////////////////////////

	//You can select a different shader for nVidia graphic cards by using
	//-cg     :	Use CG insted of GLSL
	//-cuda   : cuda implementation (fastest for smaller images)
	/////////////////////////////////////////////////////////////////////////////////////

	//////////////////////////////////////////////////////////////////////////////////////
	////////////////////////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".
	//////////////////////////////////////////////////////////////////////////////////////


	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 an OpenGL context for computation, and SiftGPU will be initialized automatically 
	if(sift->CreateContextGL() != SiftGPU::SIFTGPU_FULL_SUPPORTED) return 0;


	////******************----Manage openGL contex yourself----***************************
	//if you prefer to create openGL contexts yourself or you are mixing siftgpu with other 
	//openGL code, you'll need to call sift->VerifyContextGL() instead. You have to make sure 
	//that you activate the OpenGL context (WglMakeCurrent in win32), and have GL_FILL polygon mode
	//before calling the siftgpu functions. Check GLTestWnd::glCreateRC for win32 example

	///////////////////////////////////////////////////////////////////////////////////////////////
	//1. Note that GL_TEXTURE_RECTANGLE_ARB is always enabled in SiftGPU. When you have problem 
	//displaying textures, you can try first glDisable(GL_TEXTURE_RECTANGLE_ARB) before painting, 
	//but don't forget to call glEnable(GL_TEXTURE_RECTANGLE_ARB) after. (Thanks to Pilet)
	///////////////////////////////////////////////////////////////////////////////////////////////
	//2. Besides, SiftGPU also changes several other OpenGL states, including texture binding to
	//GL_TEXTURE_RECTANGLE_ARB and current ViewPort. You might need to restore the viewport yourself.
	//To avoid this, you can create a seperate OpenGL context for SiftGPU, and use another context
	//for displaying. 


	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"); //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 should create only one SiftGPU instance and reuse it on all the 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");
	//*********************************************************************************


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

	//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)
	{
		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***************
	//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";

	// clean up..not necessary here..
	delete[] match_buf;
	delete sift;
	delete matcher;
#ifdef SIFTGPU_DLL_RUNTIME
	#ifdef _WIN32
		FreeLibrary(hsiftgpu);
	#else
		dlclose(hsiftgpu);
	#endif
#endif
	return 1;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -