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

📄 pyramidgl.cpp

📁 SiftGPU is an implementation of SIFT [1] for GPU. SiftGPU processes pixels parallely to build Gaussi
💻 CPP
📖 第 1 页 / 共 5 页
字号:
	GLTexImage::DetachFBO(1);
	GLTexImage::DetachFBO(2);
	UnloadProgram();
	GLTexImage::UnbindMultiTex(3);
	fbo.UnattachTex(GL_COLOR_ATTACHMENT1_EXT);
}

void PyramidPacked::DetectKeypointsEX()
{

	//first pass, compute dog, gradient, orientation
	GLenum buffers[4] = { 
		GL_COLOR_ATTACHMENT0_EXT,		GL_COLOR_ATTACHMENT1_EXT ,
		GL_COLOR_ATTACHMENT2_EXT,		GL_COLOR_ATTACHMENT3_EXT
	};

	int i, j;
	double t0, t, ts, t1, t2;
	FrameBufferObject fbo;

	if(GlobalUtil::_timingS && GlobalUtil::_verbose)ts = CLOCK();

	for(i = _octave_min; i < _octave_min + _octave_num; i++)
	{
		GLTexImage * gus = GetBaseLevel(i) + 1;
		GLTexImage * dog = GetBaseLevel(i, DATA_DOG) + 1;
		GLTexImage * grd = GetBaseLevel(i, DATA_GRAD) + 1;
		GLTexImage * rot = GetBaseLevel(i, DATA_ROT) + 1;
		glDrawBuffers(3, buffers);
		gus->FitTexViewPort();
		//compute the gradient
		for(j = param._level_min +1; j <=  param._level_max ; j++, gus++, dog++, grd++, rot++)
		{
			//gradient, dog, orientation
			glActiveTexture(GL_TEXTURE0);
			gus->BindTex();
			glActiveTexture(GL_TEXTURE1);
			(gus-1)->BindTex();
			//output
			dog->AttachToFBO(0);
			grd->AttachToFBO(1);
			rot->AttachToFBO(2);
			ShaderMan::UseShaderGradientPass((gus-1)->GetTexID());
			//compuate
			dog->DrawQuadMT4();
		}
	}
	if(GlobalUtil::_timingS && GlobalUtil::_verbose)
	{
		glFinish();
		t1 = CLOCK();
	}
	GLTexImage::DetachFBO(1);
	GLTexImage::DetachFBO(2);
	//glDrawBuffers(1, buffers);
	glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT);
	

	GlobalUtil::CheckErrorsGL();

	for ( i = _octave_min; i < _octave_min + _octave_num; i++)
	{
		if(GlobalUtil::_timingO)
		{
			t0 = CLOCK();
			std::cout<<"#"<<(i + _down_sample_factor)<<"\t";
		}
		GLTexImage * dog = GetBaseLevel(i, DATA_DOG) + 2;
		GLTexImage * key = GetBaseLevel(i, DATA_KEYPOINT) +2;
		key->FitTexViewPort();

		for( j = param._level_min +2; j <  param._level_max ; j++, dog++, key++)
		{
			if(GlobalUtil::_timingL)t = CLOCK();		
			key->AttachToFBO(0);
			glActiveTexture(GL_TEXTURE0);
			dog->BindTex();
			glActiveTexture(GL_TEXTURE1);
			(dog+1)->BindTex();
			glActiveTexture(GL_TEXTURE2);
			(dog-1)->BindTex();
			ShaderMan::UseShaderKeypoint((dog+1)->GetTexID(), (dog-1)->GetTexID());
			key->DrawQuadMT8();
			if(GlobalUtil::_timingL)
			{
				glFinish();
				std::cout<<(CLOCK()-t)<<"\t";
			}
		}
		if(GlobalUtil::_timingO)
		{
			glFinish();
			std::cout<<"|\t"<<(CLOCK()-t0)<<"\n";
		}
	}

	if(GlobalUtil::_timingS)
	{
		glFinish();
		if(GlobalUtil::_verbose) 
		{	
			t2 = CLOCK();
			std::cout	<<"<Gradient, DOG  >\t"<<(t1-ts)<<"\n"
						<<"<Get Keypoints  >\t"<<(t2-t1)<<"\n";
		}
						
	}
	UnloadProgram();
	GLTexImage::UnbindMultiTex(3);
	fbo.UnattachTex(GL_COLOR_ATTACHMENT1_EXT);
}

void PyramidPacked::GenerateFeatureList()
{
	//generate the histogram pyramid
	FrameBufferObject fbo;
	glReadBuffer(GL_COLOR_ATTACHMENT0_EXT);
	glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT);
	GLTexImage * htex, * ftex, * tex;
	double t1, t2, t3, ot1, ot2, ts1 = 0, ts2 = 0; 
	int ocount= 0, idx = 0;
	int hist_level_num = _hpLevelNum - _pyramid_octave_first; 
	int hist_skip_gpu = GlobalUtil::_ListGenSkipGPU; 
	_featureNum = 0;

	FitHistogramPyramid();
#ifdef _REVERSE_ORDER
	idx = _octave_num * param._dog_level_num - 1;
	for(int i = _octave_num - 1; i >=0; i--)
	{
		tex = GetBaseLevel(_octave_min + i, DATA_KEYPOINT) + 2 + param._dog_level_num - 1;
		//output

		if(GlobalUtil::_timingO)
		{
			ot1 = ot2 = 0; 
			ocount = 0;
			std::cout<<"#"<<i+_octave_min + _down_sample_factor<<":\t";
		}
		for(int j = param._dog_level_num - 1; j >=0; j--, tex--, idx--)
		{
#else
	for(int i = 0; i < _octave_num; i++)
	{
		tex = GetBaseLevel(_octave_min + i, DATA_KEYPOINT) + 2;
		//output

		if(GlobalUtil::_timingO)
		{
			ot1 = ot2 = 0; 
			ocount = 0;
			std::cout<<"#"<<i+_octave_min + _down_sample_factor<<":\t";
		}
		for(int j = 0; j < param._dog_level_num; j++, tex++, idx++)
		{
#endif
			float fcount = 0.0f; 
			htex = _histoPyramidTex + hist_level_num - 1 - i;
			ftex = _featureTex + idx;
			if(GlobalUtil::_timingL) t1= CLOCK();
			//fill zero to an extra row/col if the height/width is odd
			glActiveTexture(GL_TEXTURE0);
			tex->BindTex();
			htex->AttachToFBO(0);
			int tight = (htex->GetImgWidth() * 4 == tex->GetImgWidth() -1 && htex->GetImgHeight() *4 == tex->GetImgHeight()-1 );
			ShaderMan::UseShaderGenListInit(tex->GetImgWidth(), tex->GetImgHeight(), tight);
			htex->FitTexViewPort();
			//this uses the fact that no feature is on the edge.
			htex->DrawQuadReduction();
			//reduction..
			htex--;
	
			//this part might have problems on several GPUS
			//because the output of one pass is the input of the next pass
			//need to call glFinish to make it right
			//but too much glFinish makes it slow
			for(int k = 0; k <hist_level_num - i-1 - hist_skip_gpu; k++, htex--)
			{
				htex->AttachToFBO(0);
				htex->FitTexViewPort();
				(htex+1)->BindTex();
				ShaderMan::UseShaderGenListHisto();
				htex->DrawQuadReduction();		
			}
			//
			if(GlobalUtil::_timingL)	t2= CLOCK();

			if(hist_skip_gpu == 0)
			{		
				//read back one pixel
				float fn[4];
				glReadPixels(0, 0, 1, 1, GL_RGBA , GL_FLOAT, fn);
				fcount = (fn[0] + fn[1] + fn[2] + fn[3]);
				if(fcount < 1) fcount = 0;

				_levelFeatureNum[ idx] = (int)(fcount);
				SetLevelFeatureNum(idx, (int)fcount);

				//save  number of features
				ocount+=int(fcount);
				_featureNum += int(fcount);

				//
				if(fcount < 1.0) 
				{
					ot1 += (t2 - t1); 
					if(GlobalUtil::_timingL) std::cout<<"0\t";
					continue;
				}
			

				///generate the feature texture

				htex=  _histoPyramidTex;

				htex->BindTex();

				//first pass
				ftex->AttachToFBO(0);
				if(GlobalUtil::_MaxOrientation>1)
				{
					//this is very important...
					ftex->FitRealTexViewPort();
					glClear(GL_COLOR_BUFFER_BIT);
					glFinish();
				}else
				{	
					ftex->FitTexViewPort();
				}


				ShaderMan::UseShaderGenListStart((float)ftex->GetImgWidth(), htex->GetTexID());

				ftex->DrawQuad();
				//make sure it finishes before the next step
				ftex->DetachFBO(0);
				//pass on each pyramid level
				htex++;
			}else
			{

				int tw = htex[1].GetDrawWidth(), th = htex[1].GetDrawHeight();
				int fc = 0;
				glReadPixels(0, 0, tw, th, GL_RGBA , GL_FLOAT, _histo_buffer);	
				_keypoint_buffer.resize(0);
				for(int y = 0, pos = 0; y < th; y++)
				{
					for(int x= 0; x < tw; x++)
					{
						for(int c = 0; c < 4; c++, pos++)
						{
							int ss =  (int) _histo_buffer[pos]; 
							if(ss == 0) continue;
							float ft[4] = {2 * x + (c%2? 1.5f:  0.5f), 2 * y + (c>=2? 1.5f: 0.5f), 0, 1 };
							for(int t = 0; t < ss; t++)
							{
								ft[2] = (float) t; 
								_keypoint_buffer.insert(_keypoint_buffer.end(), ft, ft+4);
							}
							fc += (int)ss; 
						}
					}
				}
				_levelFeatureNum[ idx] = fc;
				SetLevelFeatureNum(idx, fc);
				if(fc == 0) 
				{
					ot1 += (t2 - t1); 
					if(GlobalUtil::_timingL) std::cout<<"0\t";
					continue;
				}
				fcount = (float) fc; 	
				ocount += fc;	
				_featureNum += fc;
				/////////////////////
				ftex->AttachToFBO(0);
				if(GlobalUtil::_MaxOrientation>1)
				{
					ftex->FitRealTexViewPort();
					glClear(GL_COLOR_BUFFER_BIT);
				}else
				{					
					ftex->FitTexViewPort();
				}
				_keypoint_buffer.resize(ftex->GetDrawWidth() * ftex->GetDrawHeight()*4, 0);
				///////////
				glActiveTexture(GL_TEXTURE0);
				ftex->BindTex();
				glTexSubImage2D(GlobalUtil::_texTarget, 0, 0, 0, ftex->GetDrawWidth(),
					ftex->GetDrawHeight(), GL_RGBA, GL_FLOAT, &_keypoint_buffer[0]);
				htex += 2; 
			}

			for(int lev = 1 + hist_skip_gpu; lev < hist_level_num  - i; lev++, htex++)
			{
				glActiveTexture(GL_TEXTURE0);
				ftex->BindTex();
				ftex->AttachToFBO(0);
				glActiveTexture(GL_TEXTURE1);
				htex->BindTex();
				ShaderMan::UseShaderGenListStep(ftex->GetTexID(), htex->GetTexID());
				ftex->DrawQuad();
				ftex->DetachFBO(0);	
			}

			ftex->AttachToFBO(0);
			glActiveTexture(GL_TEXTURE1);
			tex->BindTex();
			ShaderMan::UseShaderGenListEnd(tex->GetTexID());
			ftex->DrawQuad();

			if(GlobalUtil::_timingL)
			{
				glFinish();
				t3 = CLOCK();
				ot1 += (t2 - t1); ot2 += ( t3 - t2);
				std::cout<<int(fcount)<<"\t";
			}
			GLTexImage::UnbindMultiTex(2);
		}
		if(GlobalUtil::_timingO)
		{	
			ts1 += ot1; ts2 += ot2; 
			std::cout << "| \t" << int(ocount) << " :\t(" << ot1 <<",\t" << ot2 << ")\n";
		}
	}
	if(GlobalUtil::_timingS)glFinish();
	if(GlobalUtil::_verbose)
	{
		std::cout<<"#Features:\t"<<_featureNum<<"\n";
	}

}


void PyramidPacked::GenerateFeatureListV2()
{
}


void PyramidPacked::GenerateFeatureListCPU()
{
	FrameBufferObject fbo;
	_featureNum = 0;
	GLTexImage * tex = GetBaseLevel(_octave_min);
	float * mem = new float [tex->GetTexWidth()*tex->GetTexHeight()*4];
	vector<float> list;
	int idx = 0;
	for(int i = 0; i < _octave_num; i++)
	{
		for(int j = 0; j < param._dog_level_num; j++, idx++)
		{
			tex = GetBaseLevel(_octave_min + i, DATA_KEYPOINT) + j + 2;
			tex->BindTex();
			glGetTexImage(GlobalUtil::_texTarget, 0, GL_RGBA, GL_FLOAT, mem);
			//tex->AttachToFBO(0);
			//tex->FitTexViewPort();
			//glReadPixels(0, 0, tex->GetTexWidth(), tex->GetTexHeight(), GL_RED, GL_FLOAT, mem);
			//
			//make a list of 
			list.resize(0);
			float *pl = mem;
			int fcount = 0 ;
			for(int k = 0; k < tex->GetDrawHeight(); k++)
			{
				float * p = pl; 
				pl += tex->GetTexWidth() * 4;
				for( int m = 0; m < tex->GetDrawWidth(); m ++, p+=4)
				{
				//	if(m ==0 || k ==0 || k == tex->GetDrawHeight() -1 || m == tex->GetDrawWidth() -1) continue;
				//	if(*p == 0) continue;
					int t = ((int) fabs(p[0])) - 1;
					if(t < 0) continue;
					int xx = m + m + ( (t %2)? 1 : 0);
					int yy = k + k + ( (t <2)? 0 : 1);
					if(xx ==0 || yy == 0) continue;
					if(xx >= tex->GetImgWidth() - 1 || yy >= tex->GetImgHeight() - 1)continue;
					list.push_back(xx + 0.5f + p[1]);
					list.push_back(yy + 0.5f + p[2]);
					list.push_back(GlobalUtil::_KeepExtremumSign && p[0] < 0 ? -1.0f : 1.0f);
					list.push_back(p[3]);
					fcount ++;
				}
			}
			if(fcount==0)continue;

			if(GlobalUtil::_timingL) std::cout<<fcount<<".";
			
			GLTexImage * ftex = _featureTex+idx;
			_levelFeatureNum[idx] = (fcount);
			SetLevelFeatureNum(idx, fcount);

			_featureNum += (fcount);


			int fw = ftex->GetImgWidth();
			int fh = ftex->GetImgHeight();

			list.resize(4*fh*fw);

			ftex->BindTex();
			ftex->AttachToFBO(0);
	//		glTexImage2D(GlobalUtil::_texTarget, 0, GlobalUtil::_iTexFormat, fw, fh, 0, GL_BGRA, GL_FLOAT, &list[0]);
			glTexSubImage2D(GlobalUtil::_texTarget, 0, 0, 0, fw, fh, GL_RGBA, GL_FLOAT, &list[0]);
			//
		}
	}
	GLTexImage::UnbindTex();
	delete mem;
	if(GlobalUtil::_verbose)
	{
		std::cout<<"#Features:\t"<<_featureNum<<"\n";
	}
}



void PyramidPacked::GetFeatureOrientations()
{
	GLTexImage * gtex, * otex;
	GLTexImage * ftex = _featureTex;
	GLTexImage * fotex = _orientationTex; 
	int * count	 = _levelFeatureNum;
	float sigma, sigma_step = powf(2.0f, 1.0f/param._dog_level_num);


	FrameBufferObject fbo;
	if(_orientationTex)
	{
		GLenum buffers[] = { GL_COLOR_ATTACHMENT0_EXT, GL_COLOR_ATTACHMENT1_EXT };
		glDrawBuffers(2, buffers);
	}else
	{
		glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT);
	}

	for(int i = 0; i < _octave_num; i++)
	{
		gtex = GetBaseLevel(i+_octave_min, DATA_GRAD) + GlobalUtil::_GradientLevelOffset;
		otex = GetBaseLevel(i+_octave_min, DATA_ROT) + GlobalUtil::_GradientLevelOffset;


		for(int j = 0; j < param._dog_level_num; j++, ftex++, otex++, count++, gtex++, fotex++)
		{
			if(*count<=0)continue;

			sigma = param.GetLevelSigma(j+param._level_min+1);


			ftex->FitTexViewPort();

			glActiveTexture(GL_TEXTURE0);
			ftex->BindTex();
			glActiveTexture(GL_TEXTURE1);
			gtex->BindTex();
			glActiveTexture(GL_TEXTURE2);
			otex->BindTex();
			//
			ftex->AttachToFBO(0);
			if(_orientationTex)		fotex->AttachToFBO(1);

			ShaderMan::UseShaderOrientation(gtex->GetTexID(),
				gtex->GetImgWidth(), gtex->GetImgHeight(),
				sigma, otex->GetTexID(), sigma_step, _existing_keypoints);
			ftex->DrawQuad();
		}
	}

	GLTexImage::UnbindMultiTex(3);
	if(GlobalUtil::_timingS)glFinish();
	if(_orientationTex)	fbo.UnattachTex(GL_COLOR_ATTACHMENT1_EXT);

}


void PyramidPacked::GetSimplifiedOrientation()
{
	//
	int idx = 0;
//	int n = _octave_num  * param._dog_level_num;
	float sigma, sigma_step = powf(2.0f, 1.0f/param._dog_level_num); 
	GLTexImage * ftex = _featureTex;

	FrameBufferObject fbo;
	glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT);
	for(int i = 0; i < _octave_num; i++)
	{
		GLTexImage *otex = GetBaseLevel(i + _octave_min, DATA_ROT) + 2;
		for(int j = 0; j < param._dog_level_num; j++, ftex++,  otex++, idx ++)
		{
			if(_levelFeatureNum[idx]<=0)continue;
			sigma = param.GetLevelSigma(j+param._level_min+1);
			//
			ftex->AttachToFBO(0);
			ftex->FitTexViewPort();

			glActiveTexture(GL_TEXTURE0);
			ftex->BindTex();
			glActiveTexture(GL_TEXTURE1);
			otex->BindTex();

			ShaderMan::UseShaderSimpleOrientation(otex->GetTexID(), sigma, sigma_step);
			ftex->DrawQuad();
		}
	}
	GLTexImage::UnbindMultiTex(2);
}

void PyramidPacked::InitPy

⌨️ 快捷键说明

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