LFPatches.cpp 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298
  1. /**
  2. * @file LFPatches.cpp
  3. * @brief simple patch based approach
  4. * @author Erik Rodner
  5. * @date 02/06/2008
  6. */
  7. #include <core/image/RectangleT.h>
  8. #include <core/image/ImageTools.h>
  9. #include <iostream>
  10. #include <sstream>
  11. #include "vislearning/features/localfeatures/LFPatches.h"
  12. #include "vislearning/features/localfeatures/IDRandomSampling.h"
  13. #include "vislearning/features/localfeatures/IDKLTSampling.h"
  14. #include "vislearning/features/localfeatures/IDSIFTSampling.h"
  15. #include "vislearning/image/ImagePyramid.h"
  16. using namespace OBJREC;
  17. using namespace std;
  18. using namespace NICE;
  19. LFPatches::LFPatches(const Config *conf, int _numPatches) :
  20. numPatches(_numPatches)
  21. {
  22. xsize = conf->gI("Patches", "xsize", 11);
  23. ysize = conf->gI("Patches", "ysize", 11);
  24. maxLevels = conf->gI("Patches", "levels", 10);
  25. scaleSpacing = conf->gD("Patches", "scale_spacing", sqrt(sqrt(2.0f)));
  26. detectormode = conf->gI("Patches", "detector", 0);
  27. std::string normalization_s = conf->gS("Patches", "normalization", "n01");
  28. if (detectormode == 0)
  29. {
  30. std::auto_ptr<InterestDetector> id_new(new IDRandomSampling(conf,
  31. numPatches));
  32. id = id_new;
  33. }
  34. else if (detectormode == 1)
  35. {
  36. std::auto_ptr<InterestDetector> id_new(new IDKLTSampling(conf,
  37. numPatches));
  38. id = id_new;
  39. }
  40. else if (detectormode == 2)
  41. {
  42. std::auto_ptr<InterestDetector> id_new(new IDSIFTSampling(conf));
  43. id = id_new;
  44. }
  45. else
  46. {
  47. std::auto_ptr<InterestDetector> id_new(new IDRandomSampling(conf,
  48. numPatches));
  49. id = id_new;
  50. }
  51. if (normalization_s == "n01")
  52. normalization = NORMALIZE_N01;
  53. else if (normalization_s == "stddev")
  54. normalization = NORMALIZE_STDDEV;
  55. else if (normalization_s == "mean")
  56. normalization = NORMALIZE_MEAN;
  57. else if (normalization_s == "none")
  58. normalization = NORMALIZE_NONE;
  59. else
  60. {
  61. fprintf(stderr, "LFPatches::LFPatches: unknown normalization method\n");
  62. exit(-1);
  63. }
  64. srand(time(NULL));
  65. }
  66. LFPatches::~LFPatches()
  67. {
  68. }
  69. int LFPatches::getDescSize() const
  70. {
  71. return xsize * ysize;
  72. }
  73. int LFPatches::extractFeatures(const NICE::Image & img, VVector & features,
  74. VVector & positions) const
  75. {
  76. ImagePyramid imp(img, maxLevels, scaleSpacing, xsize, ysize);
  77. //imp.show();
  78. VVector positions_tmp;
  79. if(positions.size()<=0)
  80. {
  81. id->getRandomInterests(imp, positions_tmp,numPatches);
  82. }
  83. else
  84. {
  85. positions_tmp=positions;
  86. }
  87. correctPositions(imp, positions_tmp, positions);
  88. calcDescriptors(imp, positions, features);
  89. return features.size();
  90. }
  91. void LFPatches::correctPositions(const ImagePyramid & imp, VVector & positions,
  92. VVector & positions_corrected) const
  93. {
  94. positions_corrected.clear();
  95. int numlevels = imp.getNumLevels();
  96. for (size_t i = 0; i < positions.size(); i++)
  97. {
  98. const NICE::Vector & position = positions[i];
  99. if ((size_t) position[2] < numlevels)
  100. {
  101. const NICE::Image & img = imp.getLevel((size_t) position[2]);
  102. double xl, yl;
  103. imp.getLevelCoordinates(position[0], position[1],
  104. (size_t) position[2], xl, yl);
  105. int x = (int) xl;
  106. int y = (int) yl;
  107. x -= xsize / 2;
  108. y -= ysize / 2;
  109. if ((x >= 0) && (y >= 0) && (x <= img.width() - xsize) && (y
  110. <= img.height() - ysize))
  111. {
  112. NICE::Vector position_new(3);
  113. imp.getOriginalCoordinates(x, y,
  114. (size_t) position[2], position_new[0], position_new[1]);
  115. position_new[2] = position[2];
  116. positions_corrected.push_back(position_new);
  117. }
  118. }
  119. }
  120. }
  121. void LFPatches::calcDescriptors(const ImagePyramid & imp, VVector & positions,
  122. VVector & features) const
  123. {
  124. NICE::Vector desc(getDescSize());
  125. for (VVector::iterator i = positions.begin(); i != positions.end();)
  126. {
  127. bool deletePosition = false;
  128. if (calcDescriptor(imp, *i, desc) < 0)
  129. {
  130. deletePosition = true;
  131. }
  132. else
  133. {
  134. features.push_back(desc);
  135. }
  136. if (deletePosition)
  137. {
  138. i = positions.erase(i);
  139. }
  140. else
  141. {
  142. i++;
  143. }
  144. }
  145. }
  146. int LFPatches::calcDescriptor(const ImagePyramid & imp,
  147. const NICE::Vector & position, NICE::Vector & desc) const
  148. {
  149. const NICE::Image & img = imp.getLevel((size_t) position[2]);
  150. double xl, yl;
  151. imp.getLevelCoordinates(position[0], position[1], (uint) position[2], xl,
  152. yl);
  153. int x = (int) xl;
  154. int y = (int) yl;
  155. if ((x < 0) || (y < 0) || (x > img.width() - xsize) || (y > img.height()
  156. - ysize))
  157. {
  158. return -1;
  159. }
  160. double mean = 0.0;
  161. double stddev = 0.0;
  162. if (normalization != NORMALIZE_NONE)
  163. {
  164. // compute mean
  165. for (int yi = y; yi < y + ysize; yi++)
  166. for (int xi = x; xi < x + xsize; xi++)
  167. mean += img.getPixel(xi, yi);
  168. mean /= (xsize * ysize);
  169. if (normalization != NORMALIZE_MEAN)
  170. {
  171. // compute stddev
  172. stddev = 0.0;
  173. for (int yi = y; yi < y + ysize; yi++)
  174. for (int xi = x; xi < x + xsize; xi++)
  175. {
  176. double d = img.getPixel(xi, yi) - mean;
  177. stddev += d * d;
  178. }
  179. if (stddev < 10e-5)
  180. return -1;
  181. stddev /= xsize * ysize;
  182. stddev = sqrt(stddev);
  183. }
  184. }
  185. if (normalization == NORMALIZE_STDDEV)
  186. {
  187. // normalize pixel values
  188. int k = 0;
  189. for (int yi = y; yi < y + ysize; yi++)
  190. for (int xi = x; xi < x + xsize; xi++, k++)
  191. desc[k] = (img.getPixel(xi, yi) - mean) / stddev + mean;
  192. }
  193. else if (normalization == NORMALIZE_N01)
  194. {
  195. // normalize pixel values
  196. int k = 0;
  197. for (int yi = y; yi < y + ysize; yi++)
  198. for (int xi = x; xi < x + xsize; xi++, k++)
  199. desc[k] = (img.getPixel(xi, yi) - mean) / stddev;
  200. }
  201. else if (normalization == NORMALIZE_MEAN)
  202. {
  203. // normalize pixel values
  204. int k = 0;
  205. for (int yi = y; yi < y + ysize; yi++)
  206. for (int xi = x; xi < x + xsize; xi++, k++)
  207. desc[k] = (img.getPixel(xi, yi) - mean);
  208. }
  209. else
  210. {
  211. int k = 0;
  212. for (int yi = y; yi < y + ysize; yi++)
  213. for (int xi = x; xi < x + xsize; xi++, k++)
  214. desc[k] = img.getPixel(xi, yi);
  215. }
  216. return 0;
  217. }
  218. void LFPatches::visualizeFeatures(NICE::Image & mark,
  219. const VVector & positions, size_t color) const
  220. {
  221. for (size_t i = 0; i < positions.size(); i++)
  222. {
  223. const NICE::Vector & pos = positions[i];
  224. double s = pow(scaleSpacing, pos[2]);
  225. int x = (int) (pos[0]);
  226. int y = (int) (pos[1]);
  227. int w = (int) (s * xsize);
  228. int h = (int) (s * ysize);
  229. RectangleT<Ipp8u> rect(Coord(x, y), Coord(x + w, y + w));
  230. mark.draw(rect, (unsigned char) color);
  231. }
  232. }
  233. void LFPatches::visualize(NICE::Image & img, const NICE::Vector & feature) const
  234. {
  235. if (feature.size() != (size_t) xsize * ysize)
  236. {
  237. fprintf(stderr, "LFPatches::visualize implementation failure\n");
  238. exit(-1);
  239. }
  240. img.resize(xsize, ysize);
  241. double max = -numeric_limits<double>::max();
  242. double min = numeric_limits<double>::max();
  243. int k = 0;
  244. for (k = 0; k < xsize * ysize; k++)
  245. {
  246. if (feature[k] > max)
  247. max = feature[k];
  248. if (feature[k] < min)
  249. min = feature[k];
  250. }
  251. k = 0;
  252. for (int y = 0; y < ysize; y++)
  253. for (int x = 0; x < xsize; x++, k++)
  254. {
  255. double val = ((feature[k] - min) * 255 / (max - min));
  256. img.setPixel(x, y, (int) val);
  257. }
  258. }