123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265 |
- /**
- * @file LFSegContour.cpp
- * @brief Local Features are connected components of a arbitrary segmentation
- * @author Erik Rodner
- * @date 01/21/2008
- */
- #include <vislearning/nice.h>
- #ifdef NICE_USELIB_ICE
- #include <image_nonvis.h>
- #include <iostream>
- #include <core/image/RectangleT.h>
- #include "vislearning/features/localfeatures/LFSegContour.h"
- #include "vislearning/segmentation/SegLocal.h"
- #include <core/iceconversion/image_convertice.h>
- #include <core/iceconversion/convertice.h>
- using namespace OBJREC;
- using namespace std;
- using namespace NICE;
- LFSegContour::LFSegContour( const Config *conf, FeatureFactory *_fc )
- {
- segmentation = new SegLocal ( conf );
- fourier_coefficients = conf->gI ( "LFSegContour", "fourier_coefficients", 50 );
- display_segmentation = conf->gB ( "LFSegContour", "display_segmentation", false);
- xsize = (size_t)conf->gI("FCGreyValues", "xsize", 11 );
- ysize = (size_t)conf->gI("FCGreyValues", "ysize", 11 );
- minArea = (size_t)conf->gI("LFSegContour", "min_area", 25 );
-
- std::string descriptor_method_s = conf->gS ("LFSegContour", "descriptor_method" );
- fc = _fc;
- if ( descriptor_method_s == "fourier" )
- descriptor_method = DESCRIPTOR_METHOD_FOURIER;
- else if ( descriptor_method_s == "hu" )
- descriptor_method = DESCRIPTOR_METHOD_HU;
- else if ( descriptor_method_s == "patch" ) {
- descriptor_method = DESCRIPTOR_METHOD_PATCH;
- if ( fc == NULL )
- {
- fprintf (stderr, "LFSegContour: please specify a patch feature factory !\n");
- exit(-1);
- }
- } else {
- fprintf (stderr, "LFSegContour: descriptor method not yet implemented !\n");
- exit(-1);
- }
- }
- LFSegContour::~LFSegContour()
- {
- delete segmentation;
- }
- int LFSegContour::getDescSize () const
- {
- if ( descriptor_method == DESCRIPTOR_METHOD_FOURIER )
- return 2*fourier_coefficients - 2;
- else if ( descriptor_method == DESCRIPTOR_METHOD_HU )
- return 7;
- else {
- return xsize*ysize;
- }
- }
- int LFSegContour::calcContourDescriptorFourier ( const ice::Contur & c,
- NICE::Vector & f ) const
- {
- if ( (size_t)c.Number() < fourier_coefficients/2 )
- return -1;
- ice::PointList pl1, pl2;
- double *r_feature = new double[fourier_coefficients];
- double *i_feature = new double[fourier_coefficients];
- double phi_1 = 0;
- pl1 = ice::ConturPointList (c, 1);
- pl2 = ice::NewPointList (pl1->lng);
- ice::FourierD (pl1->xptr, pl1->yptr, pl1->lng, NORMAL, pl2->xptr, pl2->yptr);
- if (fabs (pl2->xptr[1]) < 1.0e-12) {
- if (pl2->yptr[1] > 0)
- phi_1 = PI / 2.0;
- if (pl2->yptr[1] < 0)
- phi_1 = -PI / 2.0;
- if (fabs (pl2->yptr[1]) < 1.0e-12)
- {
- fprintf (stderr, "LFSegContour: numerical problems !!\n");
- exit(-1);
- }
- } else {
- phi_1 = atan (pl2->yptr[1] / pl2->xptr[1]);
- }
- if (pl2->xptr[1] < 0 && pl2->yptr[1] < 0)
- phi_1 += M_PI;
- if (pl2->xptr[1] < 0 && pl2->yptr[1] > 0)
- phi_1 += M_PI;
- // die ersten 2*fd-2 Merkmale berechnen
- for (size_t i = 0; i < fourier_coefficients / 2; ++i) {
- double sinphi = sin (double (i + 1) * phi_1);
- double cosphi = cos (double (i + 1) * phi_1);
- r_feature[i] =
- pl2->xptr[i + 1] * cosphi + pl2->yptr[i + 1] * sinphi;
- i_feature[i] =
- pl2->yptr[i + 1] * cosphi - pl2->xptr[i + 1] * sinphi;
- }
- for (size_t i = fourier_coefficients / 2; i < fourier_coefficients; ++i)
- {
- double cosphi = cos (double (-i - 1 + fourier_coefficients / 2) * phi_1);
- double sinphi = sin (double (-i - 1 + fourier_coefficients / 2) * phi_1);
- r_feature[i] =
- pl2->xptr[pl2->lng - i - 1 + fourier_coefficients / 2] * cosphi +
- pl2->yptr[pl2->lng - i - 1 + fourier_coefficients / 2] * sinphi;
- i_feature[i] =
- pl2->yptr[pl2->lng - i - 1 + fourier_coefficients / 2] * cosphi -
- pl2->xptr[pl2->lng - i - 1 + fourier_coefficients / 2] * sinphi;
- }
- f.resize( 2*fourier_coefficients - 2 );
- for (size_t i = 0; i < fourier_coefficients - 1; ++i)
- {
- f[i] = r_feature[i + 1] / sqrt (r_feature[0] * r_feature[0] +
- i_feature[0] * i_feature[0]);
- }
- for (size_t i = fourier_coefficients - 1; i < 2 * fourier_coefficients - 2; ++i)
- {
- f[i] = i_feature[i - fourier_coefficients + 2]
- / sqrt (r_feature[0] * r_feature[0] + i_feature[0] * i_feature[0]);
- }
- // aufräumen
- ice::FreePointList (pl1);
- ice::FreePointList (pl2);
- delete [] r_feature;
- delete [] i_feature;
- return 0;
- }
- int LFSegContour::calcContourDescriptorHU ( const ice::Contur & c,
- // refactor-nice.pl: check this substitution
- // old: Vector & f ) const
- NICE::Vector & f ) const
- {
- ice::Moments m ( c );
- f = NICE::makeEVector ( m.AffineHuInvariants() );
- return 0;
- }
- int LFSegContour::calcContourDescriptorPatch ( const NICE::Image & img,
- const ice::Contur & c,
- NICE::Vector & f ) const
- {
- int xi, yi, xa, ya;
- c.GetRect( xi, yi, xa, ya );
- Rect r ( xi, yi, xa-xi+1, ya-yi+1 );
- const NICE::Image *img_w = img.createSubImage ( r );
- fc->convert ( *img_w, f );
- delete img_w;
- return 0;
- }
- // refactor-nice.pl: check this substitution
- // old: int LFSegContour::extractFeatures ( const Image & img, VVector & features,
- int LFSegContour::extractFeatures ( const NICE::Image & img, VVector & features,
- VVector & positions ) const
- {
- std::vector<ice::Contur> contours;
- segmentation->getContours ( img, contours );
- NICE::Vector x;
- int r;
- ice::Image mark;
- if ( display_segmentation )
- {
- mark = ice::NewImg ( img.width(), img.height(), 30 );
- ice::ClearImg(mark);
- }
- for ( vector<ice::Contur>::const_iterator i = contours.begin();
- i != contours.end();
- i++ )
- {
- if ( display_segmentation )
- ice::MarkContur ( *i, 1, mark );
- int xi, yi, xa, ya;
- i->GetRect(xi, yi, xa, ya);
-
- if ( (xa-xi)*(ya-yi) < minArea ) continue;
- if ( descriptor_method == DESCRIPTOR_METHOD_FOURIER )
- r = calcContourDescriptorFourier ( *i, x );
- else if ( descriptor_method == DESCRIPTOR_METHOD_HU )
- r = calcContourDescriptorHU ( *i, x );
- else
- r = calcContourDescriptorPatch ( img, *i, x );
- if ( r >= 0 ) {
- features.push_back ( x );
- NICE::Vector p ( 4 );
- p[0] = xi; p[1] = yi;
- p[2] = xa-xi; p[3] = ya-yi;
- positions.push_back ( p );
- }
- }
- if ( display_segmentation )
- {
- #ifndef NOVISUAL
- NICE::Image *mark_nice = NICE::createGrayImage ( mark );
- showImageOverlay(img, *mark_nice);
- delete mark_nice;
- #else
- fprintf (stderr, "LFSegContour::extractFeatures: visualization disabled !\n");
- #endif
- }
- return positions.size();
- }
- void LFSegContour::visualizeFeatures ( NICE::Image & mark,
- const VVector & positions,
- size_t color ) const
- {
- for ( size_t i = 0 ; i < positions.size() ; i++ )
- {
- const NICE::Vector & pos = positions[i];
- int x = (int)pos[0];
- int y = (int)pos[1];
- int w = (int)pos[2];
- int h = (int)pos[3];
- RectangleT<Ipp8u> r ( Coord(x,y), Coord(x+w, y+w));
- mark.draw ( r, color );
- }
- }
- #endif
|