LFSegContour.cpp 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265
  1. /**
  2. * @file LFSegContour.cpp
  3. * @brief Local Features are connected components of a arbitrary segmentation
  4. * @author Erik Rodner
  5. * @date 01/21/2008
  6. */
  7. #include <vislearning/nice.h>
  8. #ifdef NICE_USELIB_ICE
  9. #include <image_nonvis.h>
  10. #include <iostream>
  11. #include <core/image/RectangleT.h>
  12. #include "vislearning/features/localfeatures/LFSegContour.h"
  13. #include "vislearning/segmentation/SegLocal.h"
  14. #include <core/iceconversion/image_convertice.h>
  15. #include <core/iceconversion/convertice.h>
  16. using namespace OBJREC;
  17. using namespace std;
  18. using namespace NICE;
  19. LFSegContour::LFSegContour( const Config *conf, FeatureFactory *_fc )
  20. {
  21. segmentation = new SegLocal ( conf );
  22. fourier_coefficients = conf->gI ( "LFSegContour", "fourier_coefficients", 50 );
  23. display_segmentation = conf->gB ( "LFSegContour", "display_segmentation", false);
  24. xsize = (size_t)conf->gI("FCGreyValues", "xsize", 11 );
  25. ysize = (size_t)conf->gI("FCGreyValues", "ysize", 11 );
  26. minArea = (size_t)conf->gI("LFSegContour", "min_area", 25 );
  27. std::string descriptor_method_s = conf->gS ("LFSegContour", "descriptor_method" );
  28. fc = _fc;
  29. if ( descriptor_method_s == "fourier" )
  30. descriptor_method = DESCRIPTOR_METHOD_FOURIER;
  31. else if ( descriptor_method_s == "hu" )
  32. descriptor_method = DESCRIPTOR_METHOD_HU;
  33. else if ( descriptor_method_s == "patch" ) {
  34. descriptor_method = DESCRIPTOR_METHOD_PATCH;
  35. if ( fc == NULL )
  36. {
  37. fprintf (stderr, "LFSegContour: please specify a patch feature factory !\n");
  38. exit(-1);
  39. }
  40. } else {
  41. fprintf (stderr, "LFSegContour: descriptor method not yet implemented !\n");
  42. exit(-1);
  43. }
  44. }
  45. LFSegContour::~LFSegContour()
  46. {
  47. delete segmentation;
  48. }
  49. int LFSegContour::getDescSize () const
  50. {
  51. if ( descriptor_method == DESCRIPTOR_METHOD_FOURIER )
  52. return 2*fourier_coefficients - 2;
  53. else if ( descriptor_method == DESCRIPTOR_METHOD_HU )
  54. return 7;
  55. else {
  56. return xsize*ysize;
  57. }
  58. }
  59. int LFSegContour::calcContourDescriptorFourier ( const ice::Contur & c,
  60. NICE::Vector & f ) const
  61. {
  62. if ( (size_t)c.Number() < fourier_coefficients/2 )
  63. return -1;
  64. ice::PointList pl1, pl2;
  65. double *r_feature = new double[fourier_coefficients];
  66. double *i_feature = new double[fourier_coefficients];
  67. double phi_1 = 0;
  68. pl1 = ice::ConturPointList (c, 1);
  69. pl2 = ice::NewPointList (pl1->lng);
  70. ice::FourierD (pl1->xptr, pl1->yptr, pl1->lng, NORMAL, pl2->xptr, pl2->yptr);
  71. if (fabs (pl2->xptr[1]) < 1.0e-12) {
  72. if (pl2->yptr[1] > 0)
  73. phi_1 = PI / 2.0;
  74. if (pl2->yptr[1] < 0)
  75. phi_1 = -PI / 2.0;
  76. if (fabs (pl2->yptr[1]) < 1.0e-12)
  77. {
  78. fprintf (stderr, "LFSegContour: numerical problems !!\n");
  79. exit(-1);
  80. }
  81. } else {
  82. phi_1 = atan (pl2->yptr[1] / pl2->xptr[1]);
  83. }
  84. if (pl2->xptr[1] < 0 && pl2->yptr[1] < 0)
  85. phi_1 += M_PI;
  86. if (pl2->xptr[1] < 0 && pl2->yptr[1] > 0)
  87. phi_1 += M_PI;
  88. // die ersten 2*fd-2 Merkmale berechnen
  89. for (size_t i = 0; i < fourier_coefficients / 2; ++i) {
  90. double sinphi = sin (double (i + 1) * phi_1);
  91. double cosphi = cos (double (i + 1) * phi_1);
  92. r_feature[i] =
  93. pl2->xptr[i + 1] * cosphi + pl2->yptr[i + 1] * sinphi;
  94. i_feature[i] =
  95. pl2->yptr[i + 1] * cosphi - pl2->xptr[i + 1] * sinphi;
  96. }
  97. for (size_t i = fourier_coefficients / 2; i < fourier_coefficients; ++i)
  98. {
  99. double cosphi = cos (double (-i - 1 + fourier_coefficients / 2) * phi_1);
  100. double sinphi = sin (double (-i - 1 + fourier_coefficients / 2) * phi_1);
  101. r_feature[i] =
  102. pl2->xptr[pl2->lng - i - 1 + fourier_coefficients / 2] * cosphi +
  103. pl2->yptr[pl2->lng - i - 1 + fourier_coefficients / 2] * sinphi;
  104. i_feature[i] =
  105. pl2->yptr[pl2->lng - i - 1 + fourier_coefficients / 2] * cosphi -
  106. pl2->xptr[pl2->lng - i - 1 + fourier_coefficients / 2] * sinphi;
  107. }
  108. f.resize( 2*fourier_coefficients - 2 );
  109. for (size_t i = 0; i < fourier_coefficients - 1; ++i)
  110. {
  111. f[i] = r_feature[i + 1] / sqrt (r_feature[0] * r_feature[0] +
  112. i_feature[0] * i_feature[0]);
  113. }
  114. for (size_t i = fourier_coefficients - 1; i < 2 * fourier_coefficients - 2; ++i)
  115. {
  116. f[i] = i_feature[i - fourier_coefficients + 2]
  117. / sqrt (r_feature[0] * r_feature[0] + i_feature[0] * i_feature[0]);
  118. }
  119. // aufräumen
  120. ice::FreePointList (pl1);
  121. ice::FreePointList (pl2);
  122. delete [] r_feature;
  123. delete [] i_feature;
  124. return 0;
  125. }
  126. int LFSegContour::calcContourDescriptorHU ( const ice::Contur & c,
  127. // refactor-nice.pl: check this substitution
  128. // old: Vector & f ) const
  129. NICE::Vector & f ) const
  130. {
  131. ice::Moments m ( c );
  132. f = NICE::makeEVector ( m.AffineHuInvariants() );
  133. return 0;
  134. }
  135. int LFSegContour::calcContourDescriptorPatch ( const NICE::Image & img,
  136. const ice::Contur & c,
  137. NICE::Vector & f ) const
  138. {
  139. int xi, yi, xa, ya;
  140. c.GetRect( xi, yi, xa, ya );
  141. Rect r ( xi, yi, xa-xi+1, ya-yi+1 );
  142. const NICE::Image *img_w = img.createSubImage ( r );
  143. fc->convert ( *img_w, f );
  144. delete img_w;
  145. return 0;
  146. }
  147. // refactor-nice.pl: check this substitution
  148. // old: int LFSegContour::extractFeatures ( const Image & img, VVector & features,
  149. int LFSegContour::extractFeatures ( const NICE::Image & img, VVector & features,
  150. VVector & positions ) const
  151. {
  152. std::vector<ice::Contur> contours;
  153. segmentation->getContours ( img, contours );
  154. NICE::Vector x;
  155. int r;
  156. ice::Image mark;
  157. if ( display_segmentation )
  158. {
  159. mark = ice::NewImg ( img.width(), img.height(), 30 );
  160. ice::ClearImg(mark);
  161. }
  162. for ( vector<ice::Contur>::const_iterator i = contours.begin();
  163. i != contours.end();
  164. i++ )
  165. {
  166. if ( display_segmentation )
  167. ice::MarkContur ( *i, 1, mark );
  168. int xi, yi, xa, ya;
  169. i->GetRect(xi, yi, xa, ya);
  170. if ( (xa-xi)*(ya-yi) < minArea ) continue;
  171. if ( descriptor_method == DESCRIPTOR_METHOD_FOURIER )
  172. r = calcContourDescriptorFourier ( *i, x );
  173. else if ( descriptor_method == DESCRIPTOR_METHOD_HU )
  174. r = calcContourDescriptorHU ( *i, x );
  175. else
  176. r = calcContourDescriptorPatch ( img, *i, x );
  177. if ( r >= 0 ) {
  178. features.push_back ( x );
  179. NICE::Vector p ( 4 );
  180. p[0] = xi; p[1] = yi;
  181. p[2] = xa-xi; p[3] = ya-yi;
  182. positions.push_back ( p );
  183. }
  184. }
  185. if ( display_segmentation )
  186. {
  187. #ifndef NOVISUAL
  188. NICE::Image *mark_nice = NICE::createGrayImage ( mark );
  189. showImageOverlay(img, *mark_nice);
  190. delete mark_nice;
  191. #else
  192. fprintf (stderr, "LFSegContour::extractFeatures: visualization disabled !\n");
  193. #endif
  194. }
  195. return positions.size();
  196. }
  197. void LFSegContour::visualizeFeatures ( NICE::Image & mark,
  198. const VVector & positions,
  199. size_t color ) const
  200. {
  201. for ( size_t i = 0 ; i < positions.size() ; i++ )
  202. {
  203. const NICE::Vector & pos = positions[i];
  204. int x = (int)pos[0];
  205. int y = (int)pos[1];
  206. int w = (int)pos[2];
  207. int h = (int)pos[3];
  208. RectangleT<Ipp8u> r ( Coord(x,y), Coord(x+w, y+w));
  209. mark.draw ( r, color );
  210. }
  211. }
  212. #endif