📄 pyramidgl.cpp
字号:
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 + -