23 #if defined(CL_SIFTGPU_ENABLED)
27 #include <CL/OpenCL.h>
44 #define USE_TIMING() double t, t0, tt;
45 #define OCTAVE_START() if(GlobalUtil::_timingO){ t = t0 = CLOCK(); cout<<"#"<<i+_down_sample_factor<<"\t"; }
46 #define LEVEL_FINISH() if(GlobalUtil::_timingL){ _OpenCL->FinishCL(); tt = CLOCK();cout<<(tt-t)<<"\t"; t = CLOCK();}
47 #define OCTAVE_FINISH() if(GlobalUtil::_timingO)cout<<"|\t"<<(CLOCK()-t0)<<endl;
53 _histoPyramidTex =
NULL;
55 _descriptorTex =
NULL;
56 _orientationTex =
NULL;
59 else _OpenCL =
new ProgramBagCLN();
60 _OpenCL->InitProgramBag(sp);
61 _inputTex =
new CLTexImage( _OpenCL->GetContextCL(),
62 _OpenCL->GetCommandQueue());
67 PyramidCL::~PyramidCL()
69 DestroyPerLevelData();
72 if(_OpenCL)
delete _OpenCL;
73 if(_inputTex)
delete _inputTex;
74 if(_bufferTEX)
delete _bufferTEX;
77 void PyramidCL::InitializeContext()
82 void PyramidCL::InitPyramid(
int w,
int h,
int ds)
84 int wp, hp, toobig = 0;
87 _down_sample_factor = 0;
90 wp = w >> _octave_min_default;
91 hp = h >> _octave_min_default;
95 _octave_min_default =
max(-3, _octave_min_default);
97 wp = w << (-_octave_min_default);
98 hp = h << (-_octave_min_default);
100 _octave_min = _octave_min_default;
105 _down_sample_factor = ds;
121 std::cout<<
"**************************************************************\n"
122 "Image larger than allowed dimension, data will be downsampled!\n"
123 "use -maxd to change the settings\n"
124 "***************************************************************\n";
127 if( wp == _pyramid_width && hp == _pyramid_height && _allocated )
132 ResizePyramid(wp, hp);
134 else if( wp > _pyramid_width || hp > _pyramid_height )
136 ResizePyramid(
max(wp, _pyramid_width),
max(hp, _pyramid_height));
137 if(wp < _pyramid_width || hp < _pyramid_height) FitPyramid(wp, hp);
145 _OpenCL->SelectInitialSmoothingFilter(_octave_min + _down_sample_factor, param);
148 void PyramidCL::ResizePyramid(
int w,
int h)
151 unsigned int totalkb = 0;
152 int _octave_num_new, input_sz, i, j;
155 if(_pyramid_width == w && _pyramid_height == h && _allocated)
return;
161 _pyramid_octave_first = 0;
165 input_sz =
min(w,h) ;
172 if(_octave_num_new < 1) _octave_num_new = GetRequiredOctaveNum(input_sz) ;
174 if(_pyramid_octave_num != _octave_num_new)
179 DestroyPerLevelData();
180 DestroyPyramidData();
182 _pyramid_octave_num = _octave_num_new;
185 _octave_num = _pyramid_octave_num;
187 int noct = _octave_num;
188 int nlev = param._level_num;
189 int texNum = noct* nlev * DATA_NUM;
192 if(_allPyramid==
NULL)
194 _allPyramid =
new CLTexImage[ texNum];
195 cl_context
context = _OpenCL->GetContextCL();
196 cl_command_queue queue = _OpenCL->GetCommandQueue();
197 for(i = 0; i < texNum; ++i) _allPyramid[i].SetContext(
context, queue);
202 CLTexImage * gus = GetBaseLevel(_octave_min, DATA_GAUSSIAN);
203 CLTexImage * dog = GetBaseLevel(_octave_min, DATA_DOG);
204 CLTexImage * grd = GetBaseLevel(_octave_min, DATA_GRAD);
205 CLTexImage * rot = GetBaseLevel(_octave_min, DATA_ROT);
206 CLTexImage * key = GetBaseLevel(_octave_min, DATA_KEYPOINT);
212 for(i = 0; i< noct; i++)
214 for( j = 0; j< nlev; j++, gus++, dog++, grd++, rot++, key++)
219 if(j < 1 + param._dog_level_num)
227 int tsz = (gus -1)->GetTexPixelCount() * 16;
228 totalkb += ((nlev *5 -6)* tsz / 1024);
234 totalkb += ResizeFeatureStorage();
242 void PyramidCL::FitPyramid(
int w,
int h)
244 _pyramid_octave_first = 0;
248 int _octave_num_max = GetRequiredOctaveNum(
min(w, h));
250 if(_octave_num < 1 || _octave_num > _octave_num_max)
252 _octave_num = _octave_num_max;
256 int pw = _pyramid_width>>1, ph = _pyramid_height>>1;
257 while(_pyramid_octave_first + _octave_num < _pyramid_octave_num &&
260 _pyramid_octave_first++;
266 for(
int i = 0; i < _octave_num; i++)
268 CLTexImage * tex = GetBaseLevel(i + _octave_min);
269 CLTexImage * dog = GetBaseLevel(i + _octave_min, DATA_DOG);
270 CLTexImage * grd = GetBaseLevel(i + _octave_min, DATA_GRAD);
271 CLTexImage * rot = GetBaseLevel(i + _octave_min, DATA_ROT);
272 CLTexImage * key = GetBaseLevel(i + _octave_min, DATA_KEYPOINT);
273 for(
int j = param._level_min; j <= param._level_max; j++, tex++, dog++, grd++, rot++, key++)
276 if(j == param._level_min)
continue;
278 if(j < param._level_max - 1)
291 void PyramidCL::SetLevelFeatureNum(
int idx,
int fcount)
293 _featureTex[idx].InitBufferTex(fcount, 1, 4);
294 _levelFeatureNum[idx] = fcount;
297 int PyramidCL::ResizeFeatureStorage()
300 if(_levelFeatureNum==
NULL) _levelFeatureNum =
new int[_octave_num * param._dog_level_num];
301 std::fill(_levelFeatureNum, _levelFeatureNum+_octave_num * param._dog_level_num, 0);
303 cl_context
context = _OpenCL->GetContextCL();
304 cl_command_queue queue = _OpenCL->GetCommandQueue();
305 int wmax = GetBaseLevel(_octave_min)->GetImgWidth() * 2;
306 int hmax = GetBaseLevel(_octave_min)->GetImgHeight() * 2;
307 int whmax =
max(wmax, hmax);
311 int num = (int)
ceil(log(
double(whmax))/log(4.0));
313 if( _hpLevelNum != num)
316 if(_histoPyramidTex )
delete [] _histoPyramidTex;
317 _histoPyramidTex =
new CLTexImage[_hpLevelNum];
318 for(i = 0; i < _hpLevelNum; ++i) _histoPyramidTex[i].SetContext(
context, queue);
321 for(i = 0, w = 1; i < _hpLevelNum; i++)
323 _histoPyramidTex[i].InitBufferTex(w, whmax, 4);
328 totalkb += (((1 << (2 * _hpLevelNum)) -1) / 3 * 16 / 1024);
331 int idx = 0, n = _octave_num * param._dog_level_num;
332 if(_featureTex==
NULL)
334 _featureTex =
new CLTexImage[n];
335 for(i = 0; i <n; ++i) _featureTex[i].SetContext(
context, queue);
339 _orientationTex =
new CLTexImage[n];
340 for(i = 0; i < n; ++i) _orientationTex[i].SetContext(
context, queue);
344 for(i = 0; i < _octave_num; i++)
346 CLTexImage * tex = GetBaseLevel(i+_octave_min);
350 else if(fmax < 32) fmax = 32;
352 for(
int j = 0; j < param._dog_level_num; j++, idx++)
354 _featureTex[idx].InitBufferTex(fmax, 1, 4);
355 totalkb += fmax * 16 /1024;
359 _orientationTex[idx].InitBufferTex(fmax, 1, 4);
360 totalkb += fmax * 16 /1024;
366 if(_descriptorTex==
NULL)
369 int fmax = _featureTex->GetImgWidth();
370 _descriptorTex =
new CLTexImage(
context, queue);
371 totalkb += ( fmax /2);
372 _descriptorTex->InitBufferTex(fmax *128, 1, 1);
375 totalkb += _descriptorTex->GetDataSize()/1024;
380 void PyramidCL::GetFeatureDescriptors()
419 void PyramidCL::GenerateFeatureListTex()
424 const double twopi = 2.0*3.14159265358979323846;
425 float sigma_half_step = powf(2.0f, 0.5f / param._dog_level_num);
426 float octave_sigma = _octave_min>=0? float(1<<_octave_min): 1.0f/(1<<(-_octave_min));
428 if(_down_sample_factor>0) octave_sigma *= float(1<<_down_sample_factor);
430 _keypoint_index.resize(0);
431 for(
int i = 0; i < _octave_num; i++, octave_sigma*= 2.0f)
433 for(
int j = 0; j < param._dog_level_num; j++, idx++)
436 float level_sigma = param.GetLevelSigma(j + param._level_min + 1) * octave_sigma;
437 float sigma_min = level_sigma / sigma_half_step;
438 float sigma_max = level_sigma * sigma_half_step;
440 for(
int k = 0; k < _featureNum; k++)
442 float * key = &_keypoint_buffer[k*4];
443 if( (key[2] >= sigma_min && key[2] < sigma_max)
444 ||(key[2] < sigma_min && i ==0 && j == 0)
445 ||(key[2] > sigma_max && i == _octave_num -1 && j == param._dog_level_num - 1))
448 list.push_back((key[0] -
offset) / octave_sigma + 0.5f);
449 list.push_back((key[1] -
offset) / octave_sigma + 0.5f);
450 list.push_back(key[2] / octave_sigma);
451 list.push_back((
float)fmod(twopi-key[3], twopi));
454 _keypoint_index.push_back(k);
459 _levelFeatureNum[idx] = fcount;
460 if(fcount==0)
continue;
461 CLTexImage * ftex = _featureTex+idx;
463 SetLevelFeatureNum(idx, fcount);
464 ftex->CopyFromHost(&list[0]);
470 std::cout<<
"#Features:\t"<<_featureNum<<
"\n";
475 void PyramidCL::ReshapeFeatureListCPU()
478 int n = param._dog_level_num*_octave_num;
479 for( i = 0; i < n; i++)
481 sz = _levelFeatureNum[i];
482 if(sz > szmax ) szmax = sz;
484 float * buffer =
new float[szmax*16];
485 float * buffer1 = buffer;
486 float * buffer2 = buffer + szmax*4;
492 #ifdef NO_DUPLICATE_DOWNLOAD
493 const double twopi = 2.0*3.14159265358979323846;
494 _keypoint_buffer.resize(0);
495 float os = _octave_min>=0? float(1<<_octave_min): 1.0f/(1<<(-_octave_min));
496 if(_down_sample_factor>0) os *= float(1<<_down_sample_factor);
501 for(i = 0; i < n; i++)
503 if(_levelFeatureNum[i]==0)
continue;
505 _featureTex[i].CopyToHost(buffer1);
508 float * src = buffer1;
509 float * des = buffer2;
510 const static double factor = 2.0*3.14159265358979323846/65535.0;
511 for(
int j = 0; j < _levelFeatureNum[i]; j++, src+=4)
513 unsigned short * orientations = (
unsigned short*) (&src[3]);
514 if(orientations[0] != 65535)
519 des[3] = float( factor* orientations[0]);
522 if(orientations[1] != 65535 && orientations[1] != orientations[0])
527 des[3] = float(factor* orientations[1]);
534 SetLevelFeatureNum(i, fcount);
535 _featureTex[i].CopyFromHost(buffer2);
537 if(fcount == 0)
continue;
539 #ifdef NO_DUPLICATE_DOWNLOAD
540 float oss = os * (1 << (i / param._dog_level_num));
541 _keypoint_buffer.resize((_featureNum + fcount) * 4);
542 float* ds = &_keypoint_buffer[_featureNum * 4];
544 for(
int k = 0; k < fcount; k++, ds+=4, fs+=4)
546 ds[0] = oss*(fs[0]-0.5f) +
offset;
547 ds[1] = oss*(fs[1]-0.5f) +
offset;
549 ds[3] = (float)fmod(twopi-fs[3], twopi);
552 _featureNum += fcount;
557 std::cout<<
"#Features MO:\t"<<_featureNum<<
endl;
561 void PyramidCL::GenerateFeatureDisplayVBO()
585 void PyramidCL::DestroySharedData()
590 delete[] _histoPyramidTex;
592 _histoPyramidTex =
NULL;
597 delete _descriptorTex;
598 _descriptorTex =
NULL;
603 delete[] _histo_buffer;
608 void PyramidCL::DestroyPerLevelData()
613 delete [] _levelFeatureNum;
614 _levelFeatureNum =
NULL;
619 delete [] _featureTex;
625 delete [] _orientationTex;
626 _orientationTex =
NULL;
628 int no = _octave_num* param._dog_level_num;
631 if(_featureDisplayVBO)
633 glDeleteBuffers(no, _featureDisplayVBO);
634 delete [] _featureDisplayVBO;
635 _featureDisplayVBO =
NULL;
637 if( _featurePointVBO)
639 glDeleteBuffers(no, _featurePointVBO);
640 delete [] _featurePointVBO;
641 _featurePointVBO =
NULL;
645 void PyramidCL::DestroyPyramidData()
649 delete [] _allPyramid;
654 void PyramidCL::DownloadKeypoints()
656 const double twopi = 2.0*3.14159265358979323846;
658 float * buffer = &_keypoint_buffer[0];
659 vector<float> keypoint_buffer2;
662 if(_keypoint_index.size() > 0)
664 keypoint_buffer2.resize(_keypoint_buffer.size());
665 buffer = &keypoint_buffer2[0];
667 float * p = buffer, *ps;
668 CLTexImage * ftex = _featureTex;
670 float os = _octave_min>=0? float(1<<_octave_min): 1.0f/(1<<(-_octave_min));
671 if(_down_sample_factor>0) os *= float(1<<_down_sample_factor);
674 for(
int i = 0; i < _octave_num; i++, os *= 2.0f)
677 for(
int j = 0; j < param._dog_level_num; j++, idx++, ftex++)
680 if(_levelFeatureNum[idx]>0)
682 ftex->CopyToHost(ps = p);
683 for(
int k = 0; k < _levelFeatureNum[idx]; k++, ps+=4)
685 ps[0] = os*(ps[0]-0.5f) +
offset;
686 ps[1] = os*(ps[1]-0.5f) +
offset;
688 ps[3] = (float)fmod(twopi-ps[3], twopi);
690 p+= 4* _levelFeatureNum[idx];
696 if(_keypoint_index.size() > 0)
698 for(
int i = 0; i < _featureNum; ++i)
700 int index = _keypoint_index[i];
701 memcpy(&_keypoint_buffer[index*4], &keypoint_buffer2[i*4], 4 *
sizeof(
float));
706 void PyramidCL::GenerateFeatureListCPU()
709 GenerateFeatureList();
712 void PyramidCL::GenerateFeatureList(
int i,
int j,
int reduction_count, vector<int>& hbuffer)
767 void PyramidCL::GenerateFeatureList()
820 GLTexImage* PyramidCL::GetLevelTexture(
int octave,
int level)
822 return GetLevelTexture(octave, level, DATA_GAUSSIAN);
825 GLTexImage* PyramidCL::ConvertTexCL2GL(CLTexImage* tex,
int dataName)
832 int width = tex->GetImgWidth() * ratio;
833 int height = tex->GetImgHeight() * ratio;
834 int tw =
max(
width, _bufferTEX->GetTexWidth());
835 int th =
max(
height, _bufferTEX->GetTexHeight());
836 _bufferTEX->InitTexture(tw, th, 1, GL_RGBA);
840 CLTexImage texCL(_OpenCL->GetContextCL(), _OpenCL->GetCommandQueue());
841 texCL.InitTextureGL(*_bufferTEX,
width,
height, 4);
845 case DATA_GAUSSIAN: _OpenCL->UnpackImage(tex, &texCL);
break;
846 case DATA_DOG:_OpenCL->UnpackImageDOG(tex, &texCL);
break;
847 case DATA_GRAD:_OpenCL->UnpackImageGRD(tex, &texCL);
break;
848 case DATA_KEYPOINT:_OpenCL->UnpackImageKEY(tex,
849 tex - param._level_num * _pyramid_octave_num, &texCL);
break;
858 GLTexImage* PyramidCL::GetLevelTexture(
int octave,
int level,
int dataName)
860 CLTexImage* tex = GetBaseLevel(octave, dataName) + (level - param._level_min);
861 return ConvertTexCL2GL(tex, dataName);
864 void PyramidCL::ConvertInputToCL(
GLTexInput* input, CLTexImage* output)
870 output->InitTexture(ws, hs, 1);
883 std::cerr<<
"Unable To Convert Intput\n";
887 void PyramidCL::BuildPyramid(
GLTexInput * input)
894 for ( i = _octave_min; i < _octave_min + _octave_num; i++)
897 CLTexImage *tex = GetBaseLevel(i);
898 CLTexImage *buf = GetBaseLevel(i, DATA_DOG) +2;
899 FilterCL ** filter = _OpenCL->f_gaussian_step;
900 j = param._level_min + 1;
904 if( i == _octave_min )
908 ConvertInputToCL(input, _inputTex);
909 if(i < 0) _OpenCL->SampleImageU(tex, _inputTex, -i- 1);
910 else _OpenCL->SampleImageD(tex, _inputTex, i + 1);
913 if(i == 0) ConvertInputToCL(input, tex);
916 ConvertInputToCL(input, _inputTex);
917 if(i < 0) _OpenCL->SampleImageU(tex, _inputTex, -i);
918 else _OpenCL->SampleImageD(tex, _inputTex, i);
921 _OpenCL->FilterInitialImage(tex, buf);
924 _OpenCL->SampleImageD(tex, GetBaseLevel(i - 1) + param._level_ds - param._level_min);
925 _OpenCL->FilterSampledImage(tex, buf);
928 for( ; j <= param._level_max ; j++, tex++, filter++)
931 _OpenCL->FilterImage(*filter, tex + 1, tex, buf);
939 void PyramidCL::DetectKeypointsEX()
942 double t0, t, ts, t1, t2;
946 for(i = _octave_min; i < _octave_min + _octave_num; i++)
948 CLTexImage * gus = GetBaseLevel(i) + 1;
949 CLTexImage * dog = GetBaseLevel(i, DATA_DOG) + 1;
950 CLTexImage * grd = GetBaseLevel(i, DATA_GRAD) + 1;
951 CLTexImage * rot = GetBaseLevel(i, DATA_ROT) + 1;
953 for(j = param._level_min +1; j <= param._level_max ; j++, gus++, dog++, grd++, rot++)
957 _OpenCL->ComputeDOG(gus, gus - 1, dog, grd, rot);
969 for ( i = _octave_min; i < _octave_min + _octave_num; i++)
974 std::cout<<
"#"<<(i + _down_sample_factor)<<
"\t";
976 CLTexImage * dog = GetBaseLevel(i, DATA_DOG) + 2;
977 CLTexImage * key = GetBaseLevel(i, DATA_KEYPOINT) +2;
980 for( j = param._level_min +2; j < param._level_max ; j++, dog++, key++)
985 _OpenCL->ComputeKEY(dog, key, param._dog_threshold, param._edge_threshold);
988 std::cout<<(CLOCK()-t)<<
"\t";
993 std::cout<<
"|\t"<<(CLOCK()-t0)<<
"\n";
1003 std::cout <<
"<Gradient, DOG >\t"<<(t1-ts)<<
"\n"
1004 <<
"<Get Keypoints >\t"<<(t2-t1)<<
"\n";
1009 void PyramidCL::CopyGradientTex()
1035 void PyramidCL::ComputeGradient()
1066 int PyramidCL::FitHistogramPyramid(CLTexImage* tex)
1069 int hist_level_num = _hpLevelNum - _pyramid_octave_first / 2;
1070 htex = _histoPyramidTex + hist_level_num - 1;
1071 int w = (tex->GetImgWidth() + 2) >> 2;
1072 int h = tex->GetImgHeight();
1074 for(
int k = 0; k < hist_level_num; k++, htex--)
1077 htex->InitTexture(w, h, 4);
1086 void PyramidCL::GetFeatureOrientations()
1117 void PyramidCL::GetSimplifiedOrientation()
1120 GetFeatureOrientations();
1123 CLTexImage* PyramidCL::GetBaseLevel(
int octave,
int dataName)
1125 if(octave <_octave_min || octave > _octave_min + _octave_num)
return NULL;
1126 int offset = (_pyramid_octave_first + octave - _octave_min) * param._level_num;
1127 int num = param._level_num * _pyramid_octave_num;
1128 return _allPyramid + num * dataName +
offset;
static int _octave_num_default
static int _octave_min_default
static int _OrientationPack2
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 > ceil(const MiniVec< float, N > &a)