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

📄 siftgpu.cpp

📁 SiftGPU is an implementation of SIFT [1] for GPU. SiftGPU processes pixels parallely to build Gaussi
💻 CPP
📖 第 1 页 / 共 3 页
字号:
		//Loop between verbose level 0, 1, 2
		if(GlobalUtil::_verbose)
		{
			GlobalUtil::_verbose  = GlobalUtil::_timingS;
			GlobalUtil::_timingS = 0;
			if(GlobalUtil::_verbose ==0 && GlobalUtil::_UseSiftGPUEX)
				std::cout << "Console ouput disabled, press Q/V to enable\n\n";
		}else
		{
			GlobalUtil::_verbose = 1;
			GlobalUtil::_timingS = 1;
		}
	}else if(verbose == -2)
	{
		//trick for disabling all output (still keeps the timing level)
		GlobalUtil::_verbose = 0;
		GlobalUtil::_timingS = 1;
	}else 
	{
		GlobalUtil::_verbose = verbose>0;
		GlobalUtil::_timingS = verbose>1;
	}

}


SiftParam::SiftParam()
{

	_level_min = -1;
	_dog_level_num  = 3;
	_level_max = 0;
	_sigma0 = 0;
	_sigman = 0;
	_edge_threshold = 0;
	_dog_threshold =  0;


}

float SiftParam::GetInitialSmoothSigma(int octave_min)
{
	float	sa = _sigma0 * powf(2.0f, float(_level_min)/float(_dog_level_num)) ; 
	float   sb = _sigman / powf(2.0f,  float(octave_min)) ;//
	float sigma_skip0 = sa>sb+ 0.001?sqrt(sa*sa - sb*sb): 0.0f;
	return sigma_skip0; 
}

void SiftParam::ParseSiftParam()
{ 

	if(_dog_level_num ==0) _dog_level_num = 3;
	if(_level_max ==0) _level_max = _dog_level_num + 1;
	if(_sigma0 ==0.0f) _sigma0 = 1.6f * powf(2.0f, 1.0f / _dog_level_num) ;
	if(_sigman == 0.0f) _sigman = 0.5f;


	_level_num = _level_max -_level_min + 1;

	_level_ds  = _level_min + _dog_level_num;
	if(_level_ds > _level_max ) _level_ds = _level_max ;


	///
	float _sigmak = powf(2.0f, 1.0f / _dog_level_num) ;
	float dsigma0 = _sigma0 * sqrt (1.0f - 1.0f / (_sigmak*_sigmak) ) ;
	float sa, sb;

 
	sa = _sigma0 * powf(_sigmak, (float)_level_min) ; 
	sb = _sigman / powf(2.0f,   (float)GlobalUtil::_octave_min_default) ;//

	_sigma_skip0 = sa>sb+ 0.001?sqrt(sa*sa - sb*sb): 0.0f;

    sa = _sigma0 * powf(_sigmak, float(_level_min )) ;
    sb = _sigma0 * powf(_sigmak, float(_level_ds - _dog_level_num)) ;

	_sigma_skip1 = sa>sb + 0.001? sqrt(sa*sa - sb*sb): 0.0f;

	_sigma_num = _level_max - _level_min;
	_sigma = new float[_sigma_num];

	for(int i = _level_min + 1; i <= _level_max; i++)
	{
		_sigma[i-_level_min -1] =  dsigma0 * powf(_sigmak, float(i)) ;
	}

	if(_dog_threshold ==0)	_dog_threshold      = 0.02f / _dog_level_num ;
	if(_edge_threshold==0) _edge_threshold		= 10.0f;
}


void SiftGPUEX::DisplayOctave(void (*UseDisplayShader)(), int i)
{
	if(_pyramid == NULL)return;
	const int grid_sz = (int)ceil(_level_num/2.0);
	double scale = 1.0/grid_sz ;
	int gx=0, gy=0, dx, dy;

	if(_pyramid->_octave_min >0) scale *= (1<<_pyramid->_octave_min);
	else if(_pyramid->_octave_min < 0) scale /= (1<<(-_pyramid->_octave_min));


	i = i% _pyramid->_octave_num;  //
	if(i<0 ) i+= _pyramid->_octave_num;

	scale *= ( 1<<(i));




	UseDisplayShader();

	glPushMatrix();
	glScaled(scale, scale, scale);
	for(int level = _level_min; level<= _level_max; level++)
	{
		GLTexImage * tex = _pyramid->GetLevelTexture(i+_pyramid->_octave_min, level);

		dx = tex->GetImgWidth();
		dy = tex->GetImgHeight();

		glPushMatrix();

		glTranslated(dx*gx, dy*gy, 0);

		tex->BindTex();

		tex->DrawImage();
		tex->UnbindTex();

		glPopMatrix();

		gx++;
		if(gx>=grid_sz) 
		{
			gx =0;
			gy++;
		}

	}

	glPopMatrix();
	ShaderMan::UnloadProgram();
}

void SiftGPUEX::DisplayPyramid( void (*UseDisplayShader)(), int dataName, int nskip1, int nskip2)
{

	if(_pyramid == NULL)return;
	int grid_sz = (_level_num -nskip1 - nskip2);
	if(grid_sz > 4) grid_sz = (int)ceil(grid_sz*0.5);
	double scale = 1.0/grid_sz;
	int stepx = 0, stepy = 0, dx, dy=0, nstep;

	if(_pyramid->_octave_min >0) scale *= (1<<_pyramid->_octave_min);
	else if(_pyramid->_octave_min < 0) scale /= (1<<(-_pyramid->_octave_min));


	glPushMatrix();
	glScaled(scale, scale, scale);

	for(int i = _pyramid->_octave_min; i < _pyramid->_octave_min+_pyramid->_octave_num; i++)
	{
	
		nstep = i==_pyramid->_octave_min? grid_sz: _level_num;
		dx = 0;
		UseDisplayShader();
		for(int j = _level_min + nskip1; j <= _level_max-nskip2; j++)
		{
			GLTexImage * tex = _pyramid->GetLevelTexture(i, j, dataName);
			if(tex->GetImgWidth() == 0 || tex->GetImgHeight() == 0) continue;
			stepx = tex->GetImgWidth();
			stepy = tex->GetImgHeight();	
			////
			if(j == _level_min + nskip1 + nstep)
			{
				dy += stepy;
				dx = 0;
			}

			glPushMatrix();
			glTranslated(dx, dy, 0);
			tex->BindTex();
			tex->DrawImage();
			tex->UnbindTex();
			glPopMatrix();

			dx += stepx;

		}

		ShaderMan::UnloadProgram();

		dy+= stepy;
	}

	glPopMatrix();
}


void SiftGPUEX::DisplayLevel(void (*UseDisplayShader)(), int i)
{
	if(_pyramid == NULL)return;

	i = i%(_level_num * _pyramid->_octave_num);
	if (i<0 ) i+= (_level_num * _pyramid->_octave_num);
	int octave = _pyramid->_octave_min + i/_level_num;
	int level  = _level_min + i%_level_num;
	double scale = 1.0;

	if(octave >0) scale *= (1<<octave);
	else if(octave < 0) scale /= (1<<(-octave));

	GLTexImage * tex = _pyramid->GetLevelTexture(octave, level);

	UseDisplayShader();

	glPushMatrix();
	glScaled(scale, scale, scale);
	tex->BindTex();
	tex->DrawImage();
	tex->UnbindTex();
	glPopMatrix();
	ShaderMan::UnloadProgram();
}

void SiftGPUEX::DisplaySIFT()
{
	if(_pyramid == NULL) return;
	if(_view_debug)
	{
		DisplayDebug();
		return;
	}
	switch(_view)
	{
	case 0:
		DisplayInput();
		DisplayFeatureBox(_sub_view);
		break;
	case 1:
		DisplayPyramid(ShaderMan::UseShaderDisplayGaussian, SiftPyramid::DATA_GAUSSIAN);
		break;
	case 2:
		DisplayOctave(ShaderMan::UseShaderDisplayGaussian, _sub_view);	
		break;
	case 3:
		DisplayLevel(ShaderMan::UseShaderDisplayGaussian, _sub_view);
		break;
	case 4:
		DisplayPyramid(ShaderMan::UseShaderDisplayDOG, SiftPyramid::DATA_DOG, 1);
		break;
	case 5:
		DisplayPyramid(ShaderMan::UseShaderDisplayGrad, SiftPyramid::DATA_GRAD, 1);
		break;
	case 6:
		DisplayPyramid(ShaderMan::UseShaderDisplayDOG, SiftPyramid::DATA_DOG,2, 1);
		DisplayPyramid(ShaderMan::UseShaderDisplayKeypoints, SiftPyramid::DATA_KEYPOINT, 2,1);
	}
}


void SiftGPUEX::SetView(int view, int sub_view, char *title)
{
	const char* view_titles[] =
	{
		"Original Image",
		"Gaussian Pyramid",
		"Octave Images",
		"Level Image",
		"Difference of Gaussian",
		"Gradient",
		"Keypoints"
	};
	const int view_num = 7;
	_view = view % view_num;
	if(_view <0) _view +=view_num;
	_sub_view = sub_view;

	if(_view_debug)
		strcpy(title, "Debug...");
	else
		strcpy(title, view_titles[_view]);

}


void SiftGPU::PrintUsage()
{
	std::cout
	<<"SiftGPU Usage:\n"
	<<"-h -help       : Help\n"
	<<"-i <strings>   : Filename(s) of the input image(s)\n"
	<<"-il <string>   : Filename of an image list file\n"
	<<"-o <string>    : Where to save SIFT features\n"
	<<"-f <float>     : Filter width factor; Width will be 2*factor+1 (default : 4.0)\n"
	<<"-w  <float>    : Orientation sample window factor (default: 2.0)\n"
	<<"-dw <float>  * : Descriptor grid size factor (default : 3.0)\n"
	<<"-fo <int>    * : First octave to detect DOG keypoints(default : 0)\n"
	<<"-no <int>      : Maximum number of Octaves (default : no limit)\n"
	<<"-d <int>       : Number of DOG levels in an octave (default : 3)\n"
	<<"-t <float>     : DOG threshold (default : 0.02/3)\n"
	<<"-e <float>     : Edge Threshold (default : 10.0)\n"
	<<"-m  <int=2>    : Multi Feature Orientations (default : 1)\n"
	<<"-m2p           : 2 Orientations packed as one float\n"
	<<"-s  <int=1>    : Sub-Pixel, Sub-Scale Localization, Multi-Refinement(num)\n"
	<<"-lcpu -lc <int>: CPU/GPU mixed Feature List Generation (defaut : 6)\n"
	<<"                 Use GPU first, and use CPU when reduction size <= pow(2,num)\n"
	<<"                 When <num> is missing or equals -1, no GPU will be used\n"
	<<"-noprep        : Upload raw data to GPU (default: RGB->LUM and down-sample on CPU)\n"
	<<"-sd            : Skip descriptor computation if specified\n"
	<<"-unn    *      : Write unnormalized descriptor if specified\n"
	<<"-b      *      : Write binary sift file if specified\n"
	<<"-fs <int>      : Block Size for freature storage <default : 4>\n"
	<<"-glsl          : Use GLSL SIFTGPU instead of CG (default : CG)\n"
	<<"-tight         : Automatically resize pyramid to fit new images tightly\n"
	<<"-p  WxH        : Inititialize the pyramids to contain image of WxH (eg -p 1024x768)\n"
	<<"-lm  <int>     : Maximum feature count for a level (for pre-allocation)\n"
	<<"-lmp <float>   : Maximum percent of pixels as features (for pre-allocaton)\n"
	<<"-v <int>       : Level of timing details. Same as calling Setverbose() function\n"
	<<"-loweo         : (0,0) at center of top-left pixel (defaut: corner)\n"
	<<"-maxd <int> *  : Max working dimension (default : 2560 (unpacked) / 3200 (packed))\n"
	<<"-exit          : Exit program after processing the input image\n"
	<<"-unpack        : Use the old unpacked implementation\n"
	<<"-di            : Use dynamic array indexing if available (defualt : no)\n"
	<<"                 It could make computation faster on cards like GTX 280\n"
	<<"-fastmath      : specify -fastmath to cg compiler (Not much difference.)\n"
	<<"-ofix     *    : use 0 as feature orientations.\n"
	<<"-ofix-not *	  : disable -ofix.\n"
	<<"------parameters marked with * can be changed after initialization---------\n"
	<<"\n";
}
void SiftGPU::ParseParam(int argc, char **argv)
{
	char* arg, *param;
	char* opt;
	int  HelpPrinted = 0, setMaxD = 0;
	int  i = 0;
	for( i = 0; i< argc; i++)
	{
		arg = argv[i];
		if(arg[0]!='-')continue;
		opt = arg+1;
		param = argv[i+1];
		if(_stricmp(opt, "h")==0 || _stricmp(opt,"help")==0)
		{
			HelpPrinted = 1;
			PrintUsage();
		}else if(_stricmp(opt, "glsl")==0)
		{
			GlobalUtil::_UseGLSL = 1;
		}else if(_stricmp(opt, "cg")==0)
		{
#if !defined(SIFTGPU_NO_CG)
			GlobalUtil::_UseGLSL = 0;
#endif
		}else if(_stricmp(opt, "cuda")==0)
		{
			GlobalUtil::_UseCUDA = 1;
			GlobalUtil::_usePackedTex = 0;
		}else if(_stricmp(opt, "pack")==0)
		{
			GlobalUtil::_usePackedTex = 1;
		}else if(_stricmp(opt, "unpack")==0)
		{
			GlobalUtil::_usePackedTex = 0;
		}else if(_stricmp(opt, "lcpu")==0||_stricmp(opt, "lc")==0)
		{
			int gskip = -1;
			if(i+1 <argc)	sscanf(param, "%d", &gskip);
			if(gskip >= 0)
			{
				GlobalUtil::_ListGenSkipGPU = gskip;
			}else
			{
				GlobalUtil::_ListGenGPU = 0;
			}
		}else if(_stricmp(opt, "prep")==0)
		{
			GlobalUtil::_PreProcessOnCPU = 1;
		}else if(_stricmp(opt, "noprep")==0)
		{
			GlobalUtil::_PreProcessOnCPU = 0;
		}else  if(_stricmp(opt, "fbo1")==0)
		{
			FrameBufferObject::UseSingleFBO =1;

		}else  if(_stricmp(opt, "fbos")==0)
		{
			FrameBufferObject::UseSingleFBO = 0;
		}
		else if(_stricmp(opt, "sd")==0)
		{
			GlobalUtil::_DescriptorPPT =0;
		}else if(_stricmp(opt, "unn")==0)
		{
			GlobalUtil::_NormalizedSIFT =0;
		}else if(_stricmp(opt, "b")==0)
		{
			GlobalUtil::_BinarySIFT = 1;
		}else if(_stricmp(opt, "tight")==0)
		{
			GlobalUtil::_ForceTightPyramid = 1;
		}else if(_stricmp(opt, "exit")==0)
		{
			GlobalUtil::_ExitAfterSIFT = 1;
		}else if(_stricmp(opt, "di")==0)
		{
			GlobalUtil::_UseDynamicIndexing = 1;
		}else if(_stricmp(opt, "sign")==0)
		{
			GlobalUtil::_KeepExtremumSign = 1;
		}else if(_stricmp(opt, "ov292")==0)
		{
			//for compatibility with old version//
			GlobalUtil::_GradientLevelOffset = 2; 
			GlobalUtil::_OrientationGaussianFactor = 4.5;
			GlobalUtil::_OrientationWindowFactor = 1.0;

		}else if(_stricmp(opt, "m")==0 || _stricmp(opt, "mo")==0)
		{
			int mo = 2; //default multi-orientation
			if(i+1 <argc)	sscanf(param, "%d", &mo);
			//at least two orientation
			GlobalUtil::_MaxOrientation = min(max(1, mo), 4);
		}else if(_stricmp(opt, "m2p") == 0)
		{
			GlobalUtil::_MaxOrientation = 2;
			GlobalUtil::_OrientationPack2 = 1;
		}else if(_stricmp(opt, "s") ==0)
		{
			int sp = 1; //default refinement
			if(i+1 <argc)	sscanf(param, "%d", &sp);
			//at least two orientation

⌨️ 快捷键说明

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