GaussPyramid.cpp 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284
  1. #include "core/image/GaussPyramid.h"
  2. #include <iostream>
  3. #include <vector>
  4. namespace NICE {
  5. GaussPyramid::GaussPyramid(const Image& src, uint levelin, float rate)
  6. {
  7. this->rate=rate;
  8. gaussimage.resize(levelin+1);
  9. convertBitDepth(src, &gaussimage[0]);
  10. uint level=0;
  11. uint x=(uint)src.width();
  12. uint y=(uint)src.height();
  13. while (level<levelin && x/rate>=2 && y/rate>=2) {
  14. x=uint(x/rate);
  15. y=uint(y/rate);
  16. level++;
  17. }
  18. buildGaussPyramid(level,rate);
  19. }
  20. GaussPyramid::GaussPyramid(const FloatImage& src, uint levelin, float rate)
  21. {
  22. this->rate=rate;
  23. gaussimage.resize(levelin+1);
  24. gaussimage[0]=src;
  25. uint level=0;
  26. uint x=(uint)src.width();
  27. uint y=(uint)src.height();
  28. while (level<levelin && x/rate>=2 && y/rate>=2) {
  29. x=uint(x/rate);
  30. y=uint(y/rate);
  31. level++;
  32. }
  33. buildGaussPyramid(level,rate);
  34. }
  35. GaussPyramid::GaussPyramid(const Image& src, uint sizeMinX, uint sizeMinY, float rate)
  36. {
  37. this->rate=rate;
  38. uint x=(uint)src.width();
  39. uint y=(uint)src.height();
  40. uint level=0;
  41. while (x/rate>=sizeMinX && y/rate>=sizeMinY) {
  42. x=uint(x/rate);
  43. y=uint(y/rate);
  44. level++;
  45. }
  46. gaussimage.resize(level+1);
  47. convertBitDepth(src, &gaussimage[0]);
  48. buildGaussPyramid(level,rate);
  49. }
  50. GaussPyramid::GaussPyramid(const FloatImage& src, uint sizeMinX, uint sizeMinY, float rate)
  51. {
  52. this->rate=rate;
  53. uint x=(uint)src.width();
  54. uint y=(uint)src.height();
  55. uint level=0;
  56. while (x/rate>=sizeMinX && y/rate>=sizeMinY) {
  57. x=uint(x/rate);
  58. y=uint(y/rate);
  59. level++;
  60. }
  61. gaussimage.resize(level+1);
  62. gaussimage[0]=src;
  63. buildGaussPyramid(level,rate);
  64. }
  65. void GaussPyramid::buildGaussPyramid(uint levelin, float rate)
  66. {
  67. laplaceimage.resize(levelin+1);
  68. #ifdef NICE_USELIB_IPP
  69. int maskSize;
  70. Ipp32f *pKernel=NULL;
  71. Ipp32f Kernel5x5[]={1.0, 4.0, 6.0, 4.0, 1.0,
  72. 4.0, 16.0, 24.0, 16.0, 4.0,
  73. 6.0, 24.0, 36.0, 24.0, 6.0,
  74. 4.0, 16.0, 24.0, 16.0, 4.0,
  75. 1.0, 4.0, 6.0, 4.0, 1.0};
  76. Ipp32f Kernel7x7[]={0.000900, 0.0031500, 0.006660, 0.008580, 0.006660, 0.0031500, 0.000900,
  77. 0.003150, 0.0110250, 0.023310, 0.030030, 0.023310, 0.0110250, 0.003150,
  78. 0.006660, 0.0233100, 0.049284, 0.063492, 0.049284, 0.0233100, 0.006660,
  79. 0.008580, 0.0300300, 0.063492, 0.081796, 0.063492, 0.0300300, 0.008580,
  80. 0.006660, 0.0233100, 0.049284, 0.063492, 0.049284, 0.0233100, 0.006660,
  81. 0.003150, 0.0110250, 0.023310, 0.030030, 0.023310, 0.0110250, 0.003150,
  82. 0.000900, 0.0031500, 0.006660, 0.008580, 0.006660, 0.0031500, 0.000900};
  83. if(isEqual(rate, 1.5f, 1E-6f)) {
  84. maskSize=7;
  85. pKernel=Kernel7x7;
  86. } else {
  87. maskSize=5;
  88. pKernel=Kernel5x5;
  89. }
  90. IppiSize ippiSize = {gaussimage[0].width(), gaussimage[0].height()};
  91. IppStatus ret = ippiPyramidInitAlloc(
  92. &gPyramid,
  93. levelin,
  94. ippiSize,
  95. rate);
  96. if(ret!=ippStsNoErr)
  97. fthrow(ImageException, ippGetStatusString(ret));
  98. ret = ippiPyramidInitAlloc(
  99. &lPyramid,
  100. levelin,
  101. ippiSize,
  102. rate);
  103. if(ret!=ippStsNoErr)
  104. fthrow(ImageException, ippGetStatusString(ret));
  105. IppiPyramidDownState_32f_C1R **gState =(IppiPyramidDownState_32f_C1R**) &(gPyramid->pState);
  106. IppiPyramidUpState_32f_C1R **lState =(IppiPyramidUpState_32f_C1R**) &(lPyramid->pState);
  107. Ipp32f **gImage = (Ipp32f**)(gPyramid->pImage);
  108. Ipp32f **lImage = (Ipp32f**)(lPyramid->pImage);
  109. IppiSize *pRoi = gPyramid->pRoi;
  110. int *gStep = gPyramid->pStep;
  111. int *lStep = lPyramid->pStep;
  112. int level = gPyramid->level;
  113. Ipp32f *ptr;
  114. int step;
  115. ret = ippiPyramidLayerDownInitAlloc_32f_C1R(
  116. gState,
  117. ippiSize,
  118. rate,
  119. pKernel,
  120. maskSize,
  121. IPPI_INTER_LINEAR);
  122. if(ret!=ippStsNoErr)
  123. fthrow(ImageException, ippGetStatusString(ret));
  124. ret = ippiPyramidLayerUpInitAlloc_32f_C1R (
  125. lState,
  126. ippiSize,
  127. rate,
  128. pKernel,
  129. maskSize,
  130. IPPI_INTER_LINEAR);
  131. if(ret!=ippStsNoErr)
  132. fthrow(ImageException, ippGetStatusString(ret));
  133. gImage[0] = gaussimage[0].getPixelPointer();
  134. gStep[0] = gaussimage[0].getStepsize();
  135. for (int i=1; i<=level; i++)
  136. {
  137. gaussimage[i] = FloatImage(pRoi[i].width,pRoi[i].height);
  138. gImage[i] = gaussimage[i].getPixelPointer();
  139. gStep[i] = gaussimage[i].getStepsize();
  140. ret = ippiPyramidLayerDown_32f_C1R(
  141. gImage[i-1],
  142. gStep[i-1],
  143. pRoi[i-1],
  144. gImage[i],
  145. gStep[i],
  146. pRoi[i],
  147. *gState);
  148. if(ret!=ippStsNoErr)
  149. fthrow(ImageException, ippGetStatusString(ret));
  150. }
  151. ptr = ippiMalloc_32f_C1(ippiSize.width,ippiSize.height,&step);
  152. for (int i=level-1; i>=0; i--)
  153. {
  154. laplaceimage[i] = FloatImage(pRoi[i].width,pRoi[i].height);
  155. lImage[i] = laplaceimage[i].getPixelPointer();
  156. lStep[i] = laplaceimage[i].getStepsize();
  157. ret = ippiPyramidLayerUp_32f_C1R(
  158. gImage[i+1],
  159. gStep[i+1],
  160. pRoi[i+1],
  161. ptr,
  162. step,
  163. pRoi[i],
  164. *lState);
  165. if(ret!=ippStsNoErr)
  166. fthrow(ImageException, ippGetStatusString(ret));
  167. ret = ippiSub_32f_C1R(
  168. gImage[i],
  169. gStep[i],
  170. ptr,
  171. step,
  172. lImage[i],
  173. lStep[i],
  174. pRoi[i]);
  175. if(ret!=ippStsNoErr)
  176. fthrow(ImageException, ippGetStatusString(ret));
  177. }
  178. ippiFree(ptr);
  179. ippiPyramidLayerDownFree_32f_C1R(*gState);
  180. ippiPyramidLayerUpFree_32f_C1R (*lState);
  181. #endif
  182. }
  183. GaussPyramid::~GaussPyramid()
  184. {
  185. #ifdef NICE_USELIB_IPP
  186. IppStatus ret = ippiPyramidFree(gPyramid);
  187. if(ret!=ippStsNoErr)
  188. fthrow(ImageException, ippGetStatusString(ret));
  189. ret = ippiPyramidFree(lPyramid);
  190. if(ret!=ippStsNoErr)
  191. fthrow(ImageException, ippGetStatusString(ret));
  192. #endif
  193. }
  194. const FloatImage &GaussPyramid::getGauss(uint nr) const
  195. {
  196. if(nr>gaussimage.size())
  197. fthrow(ImageException,"Invalid Gauss image! Largest Gauss image is nr==level!");
  198. return gaussimage[nr];
  199. }
  200. Image GaussPyramid::getGaussGray(uint nr) const
  201. {
  202. FloatImage out(
  203. (Ipp32f*)gPyramid->pImage[nr],
  204. gPyramid->pRoi[nr].width,
  205. gPyramid->pRoi[nr].height,
  206. gPyramid->pStep[nr],
  207. GrayColorImageCommonImplementation::shallowCopy);
  208. Image grayOut;
  209. convertBitDepth(out, &grayOut);
  210. return grayOut;
  211. }
  212. const FloatImage &GaussPyramid::getLaplace(uint nr) const
  213. {
  214. if(nr<1)
  215. fthrow(ImageException,"Invalid Laplace image! Smallest Laplace image is nr==1!");
  216. if(nr>laplaceimage.size())
  217. fthrow(ImageException,"Invalid Laplace image! Largest Laplace image is nr==level!");
  218. return laplaceimage[nr];
  219. }
  220. Coord GaussPyramid::CoordOrig(int level, const Coord &coord)
  221. {
  222. Coord result;
  223. float fac=1;
  224. for(int i=0;i<level;i++)
  225. fac*=level;
  226. result.x=int(coord.x*fac+0.5);
  227. result.y=int(coord.y*fac+0.5);
  228. return result;
  229. }
  230. Coord GaussPyramid::CoordLevel(int level, const Coord &coord)
  231. {
  232. Coord result;
  233. float fac=1;
  234. for(int i=0;i<level;i++)
  235. fac*=level;
  236. result.x=int(coord.x/fac+0.5);
  237. result.y=int(coord.y/fac+0.5);
  238. return result;
  239. }
  240. Coord GaussPyramid::CoordUp(int level, const Coord &coord)
  241. {
  242. UNUSED_PARAMETER(level);
  243. Coord result;
  244. result.x=int(coord.x*rate+0.5);
  245. result.y=int(coord.y*rate+0.5);
  246. return result;
  247. }
  248. Coord GaussPyramid::CoordDown(int level, const Coord &coord)
  249. {
  250. UNUSED_PARAMETER(level);
  251. Coord result;
  252. result.x=int(coord.x/rate+0.5);
  253. result.y=int(coord.y/rate+0.5);
  254. return result;
  255. }
  256. }//namespace NICE