LFPatches.cpp 6.8 KB

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