23 #if defined(SIFTGPU_CUDA_ENABLED)
37 #include "CuTexImage.h"
40 #include "ProgramCU.h"
49 #define USE_TIMING() double t, t0, tt;
50 #define OCTAVE_START() if(GlobalUtil::_timingO){ t = t0 = CLOCK(); cout<<"#"<<i+_down_sample_factor<<"\t"; }
51 #define LEVEL_FINISH() if(GlobalUtil::_timingL){ ProgramCU::FinishCUDA(); tt = CLOCK();cout<<(tt-t)<<"\t"; t = CLOCK();}
52 #define OCTAVE_FINISH() if(GlobalUtil::_timingO)cout<<"|\t"<<(CLOCK()-t0)<<endl;
58 _histoPyramidTex =
NULL;
60 _descriptorTex =
NULL;
61 _orientationTex =
NULL;
70 PyramidCU::~PyramidCU()
72 DestroyPerLevelData();
75 if(_inputTex)
delete _inputTex;
76 if(_bufferPBO) glDeleteBuffers(1, &_bufferPBO);
77 if(_bufferTEX)
delete _bufferTEX;
80 void PyramidCU::InitializeContext()
86 void PyramidCU::InitPyramid(
int w,
int h,
int ds)
88 int wp, hp, toobig = 0;
94 _down_sample_factor = 0;
97 wp = w >> _octave_min_default;
98 hp = h >> _octave_min_default;
102 _octave_min_default =
max(-3, _octave_min_default);
104 wp = w << (-_octave_min_default);
105 hp = h << (-_octave_min_default);
107 _octave_min = _octave_min_default;
112 _down_sample_factor = ds;
144 std::cout<<(toobig == 2 ?
"[**SKIP OCTAVES**]:\tExceeding Memory Cap (-nomc)\n" :
145 "[**SKIP OCTAVES**]:\tReaching the dimension limit(-maxd)!\n");
148 if( wp == _pyramid_width && hp == _pyramid_height && _allocated )
153 ResizePyramid(wp, hp);
155 else if( wp > _pyramid_width || hp > _pyramid_height )
157 ResizePyramid(
max(wp, _pyramid_width),
max(hp, _pyramid_height));
158 if(wp < _pyramid_width || hp < _pyramid_height) FitPyramid(wp, hp);
167 void PyramidCU::ResizePyramid(
int w,
int h)
170 unsigned int totalkb = 0;
171 int _octave_num_new, input_sz, i, j;
174 if(_pyramid_width == w && _pyramid_height == h && _allocated)
return;
180 _pyramid_octave_first = 0;
185 input_sz =
min(w,h) ;
195 if(_octave_num_new < 1)
197 _octave_num_new = (int)
floor (log (
double(input_sz))/log(2.0)) -3 ;
198 if(_octave_num_new<1 ) _octave_num_new = 1;
201 if(_pyramid_octave_num != _octave_num_new)
206 DestroyPerLevelData();
207 DestroyPyramidData();
209 _pyramid_octave_num = _octave_num_new;
212 _octave_num = _pyramid_octave_num;
214 int noct = _octave_num;
215 int nlev = param._level_num;
218 if(_allPyramid==
NULL) _allPyramid =
new CuTexImage[ noct* nlev * DATA_NUM];
220 CuTexImage * gus = GetBaseLevel(_octave_min, DATA_GAUSSIAN);
221 CuTexImage * dog = GetBaseLevel(_octave_min, DATA_DOG);
222 CuTexImage * got = GetBaseLevel(_octave_min, DATA_GRAD);
223 CuTexImage * key = GetBaseLevel(_octave_min, DATA_KEYPOINT);
227 for(i = 0; i< noct; i++)
229 int wa = ((w + 3) / 4) * 4;
231 totalkb += ((nlev *8 -19)* (wa * h) * 4 / 1024);
232 for( j = 0; j< nlev; j++, gus++, dog++, got++, key++)
234 gus->InitTexture(wa, h);
236 dog->InitTexture(wa, h);
237 if( j >= 1 && j < 1 + param._dog_level_num)
239 got->InitTexture(wa, h, 2);
240 got->InitTexture2D();
242 if(j > 1 && j < nlev -1) key->
InitTexture(wa, h, 4);
248 totalkb += ResizeFeatureStorage();
258 void PyramidCU::FitPyramid(
int w,
int h)
260 _pyramid_octave_first = 0;
264 int _octave_num_max =
max(1, (
int)
floor (log (
double(
min(w, h)))/log(2.0)) -3 );
266 if(_octave_num < 1 || _octave_num > _octave_num_max)
268 _octave_num = _octave_num_max;
272 int pw = _pyramid_width>>1, ph = _pyramid_height>>1;
273 while(_pyramid_octave_first + _octave_num < _pyramid_octave_num &&
276 _pyramid_octave_first++;
282 int nlev = param._level_num;
283 CuTexImage * gus = GetBaseLevel(_octave_min, DATA_GAUSSIAN);
284 CuTexImage * dog = GetBaseLevel(_octave_min, DATA_DOG);
285 CuTexImage * got = GetBaseLevel(_octave_min, DATA_GRAD);
286 CuTexImage * key = GetBaseLevel(_octave_min, DATA_KEYPOINT);
287 for(
int i = 0; i< _octave_num; i++)
289 int wa = ((w + 3) / 4) * 4;
291 for(
int j = 0; j< nlev; j++, gus++, dog++, got++, key++)
293 gus->InitTexture(wa, h);
295 dog->InitTexture(wa, h);
296 if( j >= 1 && j < 1 + param._dog_level_num)
298 got->InitTexture(wa, h, 2);
299 got->InitTexture2D();
301 if(j > 1 && j < nlev -1) key->
InitTexture(wa, h, 4);
308 int PyramidCU::CheckCudaDevice(
int device)
310 return ProgramCU::CheckCudaDevice(device);
313 void PyramidCU::SetLevelFeatureNum(
int idx,
int fcount)
315 _featureTex[idx].InitTexture(fcount, 1, 4);
316 _levelFeatureNum[idx] = fcount;
319 int PyramidCU::ResizeFeatureStorage()
322 if(_levelFeatureNum==
NULL) _levelFeatureNum =
new int[_octave_num * param._dog_level_num];
323 std::fill(_levelFeatureNum, _levelFeatureNum+_octave_num * param._dog_level_num, 0);
325 int wmax = GetBaseLevel(_octave_min)->GetImgWidth();
326 int hmax = GetBaseLevel(_octave_min)->GetImgHeight();
327 int whmax =
max(wmax, hmax);
331 int num = (int)
ceil(log(
double(whmax))/log(4.0));
333 if( _hpLevelNum != num)
336 if(_histoPyramidTex )
delete [] _histoPyramidTex;
337 _histoPyramidTex =
new CuTexImage[_hpLevelNum];
340 for(i = 0, w = 1; i < _hpLevelNum; i++)
347 totalkb += (((1 << (2 * _hpLevelNum)) -1) / 3 * 16 / 1024);
350 int idx = 0, n = _octave_num * param._dog_level_num;
356 for(i = 0; i < _octave_num; i++)
358 CuTexImage * tex = GetBaseLevel(i+_octave_min);
362 else if(fmax < 32) fmax = 32;
364 for(
int j = 0; j < param._dog_level_num; j++, idx++)
366 _featureTex[idx].InitTexture(fmax, 1, 4);
367 totalkb += fmax * 16 /1024;
371 _orientationTex[idx].InitTexture(fmax, 1, 4);
372 totalkb += fmax * 16 /1024;
379 if(_descriptorTex==
NULL)
382 int fmax = _featureTex->GetImgWidth();
384 totalkb += ( fmax /2);
388 totalkb += _descriptorTex->GetDataSize()/1024;
393 void PyramidCU::GetFeatureDescriptors()
396 float* pd = &_descriptor_buffer[0];
397 vector<float> descriptor_buffer2;
400 if(_keypoint_index.size() > 0)
402 descriptor_buffer2.resize(_descriptor_buffer.size());
403 pd = &descriptor_buffer2[0];
407 for(
int i = 0, idx = 0; i < _octave_num; i++)
409 got = GetBaseLevel(i + _octave_min, DATA_GRAD) + 1;
410 for(
int j = 0; j < param._dog_level_num; j++, ftex++, idx++, got++)
412 if(_levelFeatureNum[idx]==0)
continue;
413 ProgramCU::ComputeDescriptor(ftex, got, _descriptorTex, IsUsingRectDescription());
414 _descriptorTex->CopyToHost(pd);
415 pd += 128*_levelFeatureNum[idx];
421 if(_keypoint_index.size() > 0)
424 for(
int i = 0; i < _featureNum; ++i)
426 int index = _keypoint_index[i];
427 memcpy(&_descriptor_buffer[index*128], &descriptor_buffer2[i*128], 128 *
sizeof(
float));
434 void PyramidCU::GenerateFeatureListTex()
439 const double twopi = 2.0*3.14159265358979323846;
440 float sigma_half_step = powf(2.0f, 0.5f / param._dog_level_num);
441 float octave_sigma = _octave_min>=0? float(1<<_octave_min): 1.0f/(1<<(-_octave_min));
443 if(_down_sample_factor>0) octave_sigma *= float(1<<_down_sample_factor);
445 _keypoint_index.resize(0);
446 for(
int i = 0; i < _octave_num; i++, octave_sigma*= 2.0f)
448 for(
int j = 0; j < param._dog_level_num; j++, idx++)
451 float level_sigma = param.GetLevelSigma(j + param._level_min + 1) * octave_sigma;
452 float sigma_min = level_sigma / sigma_half_step;
453 float sigma_max = level_sigma * sigma_half_step;
455 for(
int k = 0; k < _featureNum; k++)
457 float * key = &_keypoint_buffer[k*4];
458 float sigmak = key[2];
460 if(IsUsingRectDescription()) sigmak =
min(key[2], key[3]) / 12.0f;
462 if( (sigmak >= sigma_min && sigmak < sigma_max)
463 ||(sigmak < sigma_min && i ==0 && j == 0)
464 ||(sigmak > sigma_max && i == _octave_num -1 && j == param._dog_level_num - 1))
467 list.push_back((key[0] -
offset) / octave_sigma + 0.5f);
468 list.push_back((key[1] -
offset) / octave_sigma + 0.5f);
469 if(IsUsingRectDescription())
471 list.push_back(key[2] / octave_sigma);
472 list.push_back(key[3] / octave_sigma);
475 list.push_back(key[2] / octave_sigma);
476 list.push_back((
float)fmod(twopi-key[3], twopi));
480 _keypoint_index.push_back(k);
485 _levelFeatureNum[idx] = fcount;
486 if(fcount==0)
continue;
489 SetLevelFeatureNum(idx, fcount);
496 std::cout<<
"#Features:\t"<<_featureNum<<
"\n";
501 void PyramidCU::ReshapeFeatureListCPU()
504 int n = param._dog_level_num*_octave_num;
505 for( i = 0; i < n; i++)
507 sz = _levelFeatureNum[i];
508 if(sz > szmax ) szmax = sz;
510 float * buffer =
new float[szmax*16];
511 float * buffer1 = buffer;
512 float * buffer2 = buffer + szmax*4;
518 #ifdef NO_DUPLICATE_DOWNLOAD
519 const double twopi = 2.0*3.14159265358979323846;
520 _keypoint_buffer.resize(0);
521 float os = _octave_min>=0? float(1<<_octave_min): 1.0f/(1<<(-_octave_min));
522 if(_down_sample_factor>0) os *= float(1<<_down_sample_factor);
527 for(i = 0; i < n; i++)
529 if(_levelFeatureNum[i]==0)
continue;
531 _featureTex[i].CopyToHost(buffer1);
534 float * src = buffer1;
535 float * des = buffer2;
536 const static double factor = 2.0*3.14159265358979323846/65535.0;
537 for(
int j = 0; j < _levelFeatureNum[i]; j++, src+=4)
539 unsigned short * orientations = (
unsigned short*) (&src[3]);
540 if(orientations[0] != 65535)
545 des[3] = float( factor* orientations[0]);
548 if(orientations[1] != 65535 && orientations[1] != orientations[0])
553 des[3] = float(factor* orientations[1]);
560 SetLevelFeatureNum(i, fcount);
561 _featureTex[i].CopyFromHost(buffer2);
563 if(fcount == 0)
continue;
565 #ifdef NO_DUPLICATE_DOWNLOAD
566 float oss = os * (1 << (i / param._dog_level_num));
567 _keypoint_buffer.resize((_featureNum + fcount) * 4);
568 float* ds = &_keypoint_buffer[_featureNum * 4];
570 for(
int k = 0; k < fcount; k++, ds+=4, fs+=4)
572 ds[0] = oss*(fs[0]-0.5f) +
offset;
573 ds[1] = oss*(fs[1]-0.5f) +
offset;
575 ds[3] = (float)fmod(twopi-fs[3], twopi);
578 _featureNum += fcount;
583 std::cout<<
"#Features MO:\t"<<_featureNum<<
endl;
587 void PyramidCU::GenerateFeatureDisplayVBO()
591 int nvbo = _octave_num * param._dog_level_num;
592 if(_featureDisplayVBO==
NULL)
595 _featureDisplayVBO =
new GLuint[nvbo];
596 _featurePointVBO =
new GLuint[nvbo];
597 glGenBuffers(nvbo, _featureDisplayVBO);
598 glGenBuffers(nvbo, _featurePointVBO);
600 for(
int i = 0; i < nvbo; i++)
602 if(_levelFeatureNum[i]<=0)
continue;
604 CuTexImage texPBO1( _levelFeatureNum[i]* 10, 1, 4, _featureDisplayVBO[i]);
605 CuTexImage texPBO2(_levelFeatureNum[i], 1, 4, _featurePointVBO[i]);
606 ProgramCU::DisplayKeyBox(ftex, &texPBO1);
607 ProgramCU::DisplayKeyPoint(ftex, &texPBO2);
611 void PyramidCU::DestroySharedData()
616 delete[] _histoPyramidTex;
618 _histoPyramidTex =
NULL;
623 delete _descriptorTex;
624 _descriptorTex =
NULL;
629 delete[] _histo_buffer;
634 void PyramidCU::DestroyPerLevelData()
639 delete [] _levelFeatureNum;
640 _levelFeatureNum =
NULL;
645 delete [] _featureTex;
651 delete [] _orientationTex;
652 _orientationTex =
NULL;
654 int no = _octave_num* param._dog_level_num;
657 if(_featureDisplayVBO)
659 glDeleteBuffers(no, _featureDisplayVBO);
660 delete [] _featureDisplayVBO;
661 _featureDisplayVBO =
NULL;
663 if( _featurePointVBO)
665 glDeleteBuffers(no, _featurePointVBO);
666 delete [] _featurePointVBO;
667 _featurePointVBO =
NULL;
671 void PyramidCU::DestroyPyramidData()
675 delete [] _allPyramid;
680 void PyramidCU::DownloadKeypoints()
682 const double twopi = 2.0*3.14159265358979323846;
684 float * buffer = &_keypoint_buffer[0];
685 vector<float> keypoint_buffer2;
688 if(_keypoint_index.size() > 0)
690 keypoint_buffer2.resize(_keypoint_buffer.size());
691 buffer = &keypoint_buffer2[0];
693 float * p = buffer, *ps;
696 float os = _octave_min>=0? float(1<<_octave_min): 1.0f/(1<<(-_octave_min));
697 if(_down_sample_factor>0) os *= float(1<<_down_sample_factor);
700 for(
int i = 0; i < _octave_num; i++, os *= 2.0f)
703 for(
int j = 0; j < param._dog_level_num; j++, idx++, ftex++)
706 if(_levelFeatureNum[idx]>0)
709 for(
int k = 0; k < _levelFeatureNum[idx]; k++, ps+=4)
711 ps[0] = os*(ps[0]-0.5f) +
offset;
712 ps[1] = os*(ps[1]-0.5f) +
offset;
714 ps[3] = (float)fmod(twopi-ps[3], twopi);
716 p+= 4* _levelFeatureNum[idx];
722 if(_keypoint_index.size() > 0)
724 for(
int i = 0; i < _featureNum; ++i)
726 int index = _keypoint_index[i];
727 memcpy(&_keypoint_buffer[index*4], &keypoint_buffer2[i*4], 4 *
sizeof(
float));
732 void PyramidCU::GenerateFeatureListCPU()
735 GenerateFeatureList();
738 void PyramidCU::GenerateFeatureList(
int i,
int j,
int reduction_count, vector<int>& hbuffer)
740 int fcount = 0, idx = i * param._dog_level_num + j;
741 int hist_level_num = _hpLevelNum - _pyramid_octave_first /2;
745 ftex = _featureTex + idx;
746 htex = _histoPyramidTex + hist_level_num -1;
747 tex = GetBaseLevel(_octave_min + i, DATA_KEYPOINT) + 2 + j;
748 got = GetBaseLevel(_octave_min + i, DATA_GRAD) + 2 + j;
750 ProgramCU::InitHistogram(tex, htex);
752 for(k = 0; k < reduction_count - 1; k++, htex--)
754 ProgramCU::ReduceHistogram(htex, htex -1);
760 ProgramCU::FinishCUDA();
764 for(ii = 0; ii < len; ++ii) {
if(!(hbuffer[ii]>= 0)) hbuffer[ii] = 0; }
767 for(ii = 0; ii < len; ++ii) fcount += hbuffer[ii];
768 SetLevelFeatureNum(idx, fcount);
773 _featureNum += fcount;
774 _keypoint_buffer.resize(fcount * 4);
776 int* ibuf = (
int*) (&_keypoint_buffer[0]);
778 for(ii = 0; ii < len; ++ii)
780 int x = ii%4, y = ii / 4;
781 for(
int jj = 0 ; jj < hbuffer[ii]; ++jj, ibuf+=4)
783 ibuf[0] = x; ibuf[1] = y; ibuf[2] = jj; ibuf[3] = 0;
786 _featureTex[idx].CopyFromHost(&_keypoint_buffer[0]);
789 ProgramCU::GenerateList(_featureTex + idx, ++htex);
790 for(k = 2; k < reduction_count; k++)
792 ProgramCU::GenerateList(_featureTex + idx, ++htex);
797 void PyramidCU::GenerateFeatureList()
800 int ocount = 0, reduction_count;
809 CuTexImage* tex = GetBaseLevel(_octave_min + i, DATA_KEYPOINT) + 2;
810 reduction_count = FitHistogramPyramid(tex);
816 std::cout<<
"#"<<i+_octave_min + _down_sample_factor<<
":\t";
825 int idx = i * param._dog_level_num + j;
826 _levelFeatureNum[idx] = 0;
830 GenerateFeatureList(i, j, reduction_count, hbuffer);
835 int idx = i * param._dog_level_num + j;
836 ocount += _levelFeatureNum[idx];
837 std::cout<< _levelFeatureNum[idx] <<
"\t";
843 std::cout <<
"| \t" << int(ocount) <<
" :\t(" << (t2 - t1) <<
")\n";
853 std::cout<<
"#Features:\t"<<_featureNum<<
"\n";
859 GLTexImage* PyramidCU::GetLevelTexture(
int octave,
int level)
861 return GetLevelTexture(octave, level, DATA_GAUSSIAN);
867 GLenum
format = GL_LUMINANCE;
868 int convert_done = 1;
869 if(_bufferPBO == 0) glGenBuffers(1, &_bufferPBO);
875 convert_done = tex->
CopyToPBO(_bufferPBO);
881 if(texPBO._cuData == 0 || tex->
_cuData ==
NULL) convert_done = 0;
882 else ProgramCU::DisplayConvertDOG(tex, &texPBO);
888 if(texPBO._cuData == 0 || tex->
_cuData ==
NULL) convert_done = 0;
889 else ProgramCU::DisplayConvertGRD(tex, &texPBO);
894 CuTexImage * dog = tex - param._level_num * _pyramid_octave_num;
897 if(texPBO._cuData == 0 || tex->
_cuData ==
NULL) convert_done = 0;
898 else ProgramCU::DisplayConvertKEY(tex, dog, &texPBO);
912 _bufferTEX->SetImageSize(0, 0);
918 GLTexImage* PyramidCU::GetLevelTexture(
int octave,
int level,
int dataName)
920 CuTexImage* tex = GetBaseLevel(octave, dataName) + (level - param._level_min);
922 return ConvertTexCU2GL(tex, dataName);
925 void PyramidCU::ConvertInputToCU(
GLTexInput* input)
932 _inputTex->InitTexture(ws, hs, 1);
936 if(_bufferPBO == 0) glGenBuffers(1, &_bufferPBO);
939 _inputTex->InitTexture(ws, hs, 1);
940 _inputTex->CopyFromPBO(ws, hs, _bufferPBO);
941 }
else if(input->
CopyToPBO(_bufferPBO, ws, hs))
944 _inputTex->InitTexture(ws, hs, 1);
945 ProgramCU::ReduceToSingleChannel(_inputTex, &texPBO, !input->
_rgb_converted);
948 std::cerr<<
"Unable To Convert Intput\n";
953 void PyramidCU::BuildPyramid(
GLTexInput * input)
960 for ( i = _octave_min; i < _octave_min + _octave_num; i++)
963 float* filter_sigma = param._sigma;
965 CuTexImage *buf = GetBaseLevel(i, DATA_KEYPOINT) +2;
966 j = param._level_min + 1;
970 if( i == _octave_min )
972 ConvertInputToCU(input);
976 ProgramCU::FilterImage(tex, _inputTex, buf,
977 param.GetInitialSmoothSigma(_octave_min + _down_sample_factor));
980 if(i < 0) ProgramCU::SampleImageU(tex, _inputTex, -i);
981 else ProgramCU::SampleImageD(tex, _inputTex, i);
982 ProgramCU::FilterImage(tex, tex, buf,
983 param.GetInitialSmoothSigma(_octave_min + _down_sample_factor));
987 ProgramCU::SampleImageD(tex, GetBaseLevel(i - 1) + param._level_ds - param._level_min);
988 if(param._sigma_skip1 > 0)
990 ProgramCU::FilterImage(tex, tex, buf, param._sigma_skip1);
994 for( ; j <= param._level_max ; j++, tex++, filter_sigma++)
997 ProgramCU::FilterImage(tex + 1, tex, buf, *filter_sigma);
1007 void PyramidCU::DetectKeypointsEX()
1012 double t0, t, ts, t1, t2;
1016 for(i = _octave_min; i < _octave_min + _octave_num; i++)
1019 CuTexImage * dog = GetBaseLevel(i, DATA_DOG) + 1;
1020 CuTexImage * got = GetBaseLevel(i, DATA_GRAD) + 1;
1022 for(j = param._level_min +1; j <= param._level_max ; j++, gus++, dog++, got++)
1026 ProgramCU::ComputeDOG(gus, dog, got);
1031 ProgramCU::FinishCUDA();
1035 for ( i = _octave_min; i < _octave_min + _octave_num; i++)
1040 std::cout<<
"#"<<(i + _down_sample_factor)<<
"\t";
1042 CuTexImage * dog = GetBaseLevel(i, DATA_DOG) + 2;
1043 CuTexImage * key = GetBaseLevel(i, DATA_KEYPOINT) +2;
1046 for( j = param._level_min +2; j < param._level_max ; j++, dog++, key++)
1051 ProgramCU::ComputeKEY(dog, key, param._dog_threshold, param._edge_threshold);
1054 std::cout<<(CLOCK()-t)<<
"\t";
1059 std::cout<<
"|\t"<<(CLOCK()-t0)<<
"\n";
1065 ProgramCU::FinishCUDA();
1069 std::cout <<
"<Gradient, DOG >\t"<<(t1-ts)<<
"\n"
1070 <<
"<Get Keypoints >\t"<<(t2-t1)<<
"\n";
1075 void PyramidCU::CopyGradientTex()
1081 for(
int i = 0, idx = 0; i < _octave_num; i++)
1083 CuTexImage * got = GetBaseLevel(i + _octave_min, DATA_GRAD) + 1;
1085 for(
int j = 0; j < param._dog_level_num ; j++, got++, idx++)
1092 ProgramCU::FinishCUDA();
1096 std::cout <<
"<Copy Grad/Orientation>\t"<<(t1-ts)<<
"\n";
1101 void PyramidCU::ComputeGradient()
1109 for(i = _octave_min; i < _octave_min + _octave_num; i++)
1112 CuTexImage * dog = GetBaseLevel(i, DATA_DOG) + 1;
1113 CuTexImage * got = GetBaseLevel(i, DATA_GRAD) + 1;
1116 for(j = 0; j < param._dog_level_num ; j++, gus++, dog++, got++)
1118 ProgramCU::ComputeDOG(gus, dog, got);
1123 ProgramCU::FinishCUDA();
1127 std::cout <<
"<Gradient, DOG >\t"<<(t1-ts)<<
"\n";
1132 int PyramidCU::FitHistogramPyramid(
CuTexImage* tex)
1135 int hist_level_num = _hpLevelNum - _pyramid_octave_first / 2;
1136 htex = _histoPyramidTex + hist_level_num - 1;
1140 for(
int k = 0; k < hist_level_num; k++, htex--)
1152 void PyramidCU::GetFeatureOrientations()
1156 int *
count = _levelFeatureNum;
1157 float sigma, sigma_step = powf(2.0f, 1.0f/param._dog_level_num);
1159 for(
int i = 0; i < _octave_num; i++)
1161 CuTexImage* got = GetBaseLevel(i + _octave_min, DATA_GRAD) + 1;
1162 CuTexImage* key = GetBaseLevel(i + _octave_min, DATA_KEYPOINT) + 2;
1164 for(
int j = 0; j < param._dog_level_num; j++, ftex++,
count++, got++, key++)
1166 if(*
count<=0)
continue;
1170 sigma = param.GetLevelSigma(j+param._level_min+1);
1172 ProgramCU::ComputeOrientation(ftex, got, key, sigma, sigma_step, _existing_keypoints);
1181 void PyramidCU::GetSimplifiedOrientation()
1184 GetFeatureOrientations();
1187 CuTexImage* PyramidCU::GetBaseLevel(
int octave,
int dataName)
1189 if(octave <_octave_min || octave > _octave_min + _octave_num)
return NULL;
1190 int offset = (_pyramid_octave_first + octave - _octave_min) * param._level_num;
1191 int num = param._level_num * _pyramid_octave_num;
1192 if (dataName == DATA_ROT) dataName = DATA_GRAD;
1193 return _allPyramid + num * dataName +
offset;
filament::Texture::InternalFormat format
#define FOR_EACH_OCTAVE(i, R)
#define FOR_EACH_LEVEL(j, R)
void CopyFromHost(const void *buf)
void CopyToHost(void *buf)
virtual bool InitTexture(int width, int height, int nchannel=1)
int CopyToPBO(GLuint pbo)
int CopyToPBO(GLuint pbo, int width, int height, GLenum format=GL_RGBA)
static int _TruncateMethod
static int _octave_num_default
static int _octave_min_default
static int _OrientationPack2
static int _FeatureCountThreshold
static int _ForceTightPyramid
static float _MaxFeaturePercent
static int _MaxLevelFeatureNum
static int _MaxOrientation
static void InitGLParam(int NotTargetGL=0)
QTextStream & endl(QTextStream &stream)
MiniVec< float, N > floor(const MiniVec< float, N > &a)
MiniVec< float, N > ceil(const MiniVec< float, N > &a)
int CheckErrorCUDA(const char *location)