27 #include <fvclassifiers/surf.h> 30 #include <utils/time/clock.h> 31 #include <utils/time/tracker.h> 37 #include <surf/surflib.h> 42 #include <core/exception.h> 43 #include <core/exceptions/software.h> 44 #include <fvutils/color/colorspaces.h> 45 #include <fvutils/color/conversions.h> 46 #include <fvutils/readers/png.h> 47 #include <utils/system/console_colors.h> 49 #include <utils/logging/liblogger.h> 83 void saveIpoints(std::string sFileName,
const std::vector< surf::Ipoint >& ipts,
bool bVerbose,
bool bLaplacian,
int VLength)
85 std::cout<<
"Attempting to save interest points" << std::endl;
87 std::ofstream ipfile(sFileName.c_str());
89 std::cerr <<
"ERROR in loadIpoints(): " 90 <<
"Couldn't open file '" << sFileName.c_str() <<
"'!" << std::endl;
95 unsigned count = ipts.size();
99 ipfile << VLength + 1 << std::endl << count << std::endl;
101 ipfile << VLength << std::endl << count << std::endl;
112 for (
unsigned n=0; n<ipts.size(); n++){
114 sc = 2.5 * ipts[n].scale; sc*=sc;
122 ipfile <<
" " << ipts[n].laplace;
125 for (
int i = 0; i < VLength; i++) {
126 ipfile <<
" " << ipts[n].ivec[i];
133 std::cout << count <<
" interest points found" << std::endl;
142 void loadIpoints( std::string sFileName, std::vector< surf::Ipoint >& ipts,
bool bVerbose,
int& __vlen )
144 std::ifstream ipfile(sFileName.c_str());
147 std::cerr <<
"ERROR in loadIpoints(): " 148 <<
"Couldn't open file '" << sFileName.c_str() <<
"'!" << std::endl;
155 ipfile >> __vlen >> count;
164 for (
unsigned n=0; n<count; n++){
167 ipfile >> x >> y >> a >> b >> c;
169 float det = sqrt((a-c)*(a-c) + 4.0*b*b);
170 float e1 = 0.5*(a+c + det);
171 float e2 = 0.5*(a+c - det);
172 float l1 = (1.0/sqrt(e1));
173 float l2 = (1.0/sqrt(e2));
174 float sc = sqrt( l1*l2 );
178 ipts[n].scale = sc/2.5;
179 ipfile >> ipts[n].laplace;
182 ipts[n].ivec =
new double[ __vlen];
184 for(
int j = 0 ; j < __vlen; j++ )
187 ipfile >> ipts[n].ivec[j];
199 std::cout <<
"read in " << count <<
" interest points." << std::endl;
217 int samplingStep,
int octaves,
double thres,
218 bool doubleImageSize,
int initLobe,
219 bool upright,
bool extended,
int indexSize ):
Classifier(
"SurfClassifier")
221 __obj_features.clear();
222 __obj_features.reserve(1000);
224 __min_match = min_match;
225 __min_match_ratio = min_match_ratio;
227 __samplingStep = samplingStep;
230 __doubleImageSize = doubleImageSize;
231 __initLobe = initLobe;
234 __extended = extended;
235 __indexSize = indexSize;
243 __ttc_objconv = __tt->
add_class(
"ObjectConvert");
244 __ttc_objfeat = __tt->
add_class(
"ObjectFeatures");
245 __ttc_imgconv = __tt->
add_class(
"ImageConvert");
246 __ttc_imgfeat = __tt->
add_class(
"ImageFeatures");
247 __ttc_matchin = __tt->
add_class(
"Matching");
248 __ttc_roimerg = __tt->
add_class(
"MergeROIs");
257 if( (dir = opendir( keypoints_dir.c_str() ) ) == NULL ) {
258 char* buffer =
new char[256];
259 sprintf(buffer,
"The directory %s does not exist!", keypoints_dir.c_str() );
264 std::string object_file;
265 int num_obj_index = 0;
268 while( (ent = readdir(dir)) != NULL ) {
270 if ( strcmp( ent->d_name,
".") == 0 || strcmp( ent->d_name,
"..") == 0 || strcmp( ent->d_name,
".svn") == 0 )
273 object_file = keypoints_dir + ent->d_name;
274 std:: cout<<
"SurfClassifier: reading the following descriptor file" << object_file << std::endl;
276 __obj_names.push_back(object_file);
279 bool b_verbose = BVERBOSE;
280 loadIpoints( object_file, __obj_features[num_obj_index], b_verbose, __vlen);
288 __num_obj = num_obj_index;
290 if( num_obj_index != 0 ) {
291 std::cout<<
"SurfClassifier: Reading successful"<< std::endl;
298 std::cout <<
"SurfClassifier: The descriptor directory is probably empty since no objects were read off. Will instantiate a Surfclassifier with the png images directory") << std::endl;
336 unsigned int min_match,
float min_match_ratio,
337 int samplingStep,
int octaves,
double thres,
338 bool doubleImageSize,
int initLobe,
339 bool upright,
bool extended,
int indexSize)
343 __obj_features.clear();
344 __obj_features.reserve(1000);
346 __min_match = min_match;
347 __min_match_ratio = min_match_ratio;
349 __samplingStep = samplingStep;
352 __doubleImageSize = doubleImageSize;
353 __initLobe = initLobe;
356 __extended = extended;
357 __indexSize = indexSize;
366 __ttc_objconv = __tt->
add_class(
"ObjectConvert");
367 __ttc_objfeat = __tt->
add_class(
"ObjectFeatures");
368 __ttc_imgconv = __tt->
add_class(
"ImageConvert");
369 __ttc_imgfeat = __tt->
add_class(
"ImageFeatures");
370 __ttc_matchin = __tt->
add_class(
"Matching");
371 __ttc_roimerg = __tt->
add_class(
"MergeROIs");
381 std::string dir_path = object_dir;
383 if( (dir = opendir( dir_path.c_str() ) ) == NULL )
385 char* buffer =
new char[256];
386 sprintf(buffer,
"The directory %s does not exist!", dir_path.c_str() );
392 std::string object_file;
393 int num_obj_index = 0;
395 while( (ent = readdir(dir)) != NULL ) {
397 if ( strcmp( ent->d_name,
".") == 0 || strcmp( ent->d_name,
"..") == 0 || strcmp( ent->d_name,
".svn") == 0)
400 object_file = dir_path + ent->d_name;
406 std::cout <<
"SurfClassifier(classify): opening object image file '" << object_file <<
"'" << std::endl;
409 unsigned char* buf = malloc_buffer( pngr.colorspace(), pngr.pixel_width(), pngr.pixel_height() );
410 pngr.set_buffer( buf );
413 unsigned int lwidth = pngr.pixel_width();
414 unsigned int lheight = pngr.pixel_height();
415 surf::Image * __simage =
new surf::Image( lwidth, lheight );
416 for (
unsigned int h = 0; h < lheight; ++h) {
417 for (
unsigned int w = 0; w < lwidth ; ++w) {
418 __simage->setPix(w, h, (
double)buf[h * lwidth + w] / 255.f);
422 __obj_img =
new surf::Image(__simage, __doubleImageSize);
445 std::vector<surf::Ipoint> obj_feature;
446 __obj_features.push_back( obj_feature );
447 __obj_features[num_obj_index].clear();
448 __obj_features[num_obj_index].reserve(1000);
449 __obj_num_features = 0;
451 surf::FastHessian fh(__obj_img,
452 __obj_features[num_obj_index],
459 fh.getInterestPoints();
461 surf::Surf des(__obj_img,
468 __vlen = des.getVectLength();
473 for (
unsigned n=0; n < __obj_features[num_obj_index].size(); n++){
475 des.setIpoint(&(__obj_features.at(num_obj_index).at(n)));
477 des.assignOrientation();
479 des.makeDescriptor();
484 __obj_num_features = __obj_features[num_obj_index].size();
485 if ( ! __obj_num_features > 0 ) {
488 std::cout <<
"SurfClassifier(classify): computed '" << __obj_num_features <<
"' features from object" << std::endl;
491 sprintf( buffer,
"descriptors/%s-%d.surf", ent->d_name, num_obj_index );
492 std::string des_file_name = buffer;
494 bool b_verbose = BVERBOSE;
495 bool b_laplacian =
true;
497 __obj_names.push_back( des_file_name );
501 saveIpoints( des_file_name, __obj_features[num_obj_index], b_verbose, b_laplacian, __vlen );
514 __num_obj = num_obj_index;
537 std::list<ROI> rv[__num_obj];
538 float match_ratios[__num_obj];
552 std::cout <<
"SurfClassifier(classify): copy imgdat to SURF Image" << std::endl;
570 for (
unsigned int h = 0; h <
_height; ++h) {
571 for (
unsigned int w = 0; w <
_width; ++w) {
572 __simage->setPix(w, h, (
double)
_src[h * _width + w] / 255.f);
576 __image =
new surf::Image(__simage, __doubleImageSize);
585 //surf::ImLoad::saveImage( "tst.pgm", __simage);
587 //surf::ImLoad::saveImage( "tst.pgm", __image);
589 PNMWriter pnm(PNM_PGM, "fvimg.pgm", _width, _height);
590 pnm.set_buffer(YUV422_PLANAR, _src );
593 PNGWriter pngw("fvimg.png", _width, _height);
594 pngw.set_buffer(YUV422_PLANAR, _src );
603 __img_features.clear();
604 __img_features.reserve(1000);
605 __img_num_features = 0;
607 surf::FastHessian fh(__image,
615 std::cout<<
"surfclassifer/classify : getting interest points"<<std::endl;
616 fh.getInterestPoints();
618 surf::Surf des(__image,
630 for (
unsigned n=0; n < __img_features.size(); n++){
633 des.setIpoint(&__img_features[n]);
635 des.assignOrientation();
637 des.makeDescriptor();
639 __img_num_features = __img_features.size();
644 std::cout <<
"Extracted '" << __img_num_features <<
"' image features" << std::endl;
650 std::cout <<
"SurfClassifier(classify): matching ..." << std::endl;
652 for(
unsigned j = 0; j < __num_obj; j++ )
654 std::vector< int > matches(__obj_features[j].size());
657 for (
unsigned i = 0; i < __obj_features[j].size(); i++) {
658 int match = findMatch((__obj_features[j])[i], __img_features);
663 ROI r( (
int)(__img_features[matches[i]].x)-5, (
int)(__img_features[matches[i]].y )-5, 11, 11,
_width, _height);
674 std::cout <<
"SurfClassifier(classify) matched '" << c <<
fawkes::cnormal <<
"' of '" << __obj_features[j].size() <<
"' features in scene. (for supplied object = " << j << std::endl ;
676 std::cout <<
"SurfClassifier(classify) matched '" <<
fawkes::cblue << c <<
fawkes::cnormal <<
"' of '" << __obj_features[j].size() <<
"' features in scene. (for supplied object = " << j << std::endl ;
679 float match_ratio = ((float)c / (
float)__obj_features[j].size());
680 match_ratios[j] = match_ratio;
682 std::cout <<
"SurfClassifier(classify): match_ratio is '" << match_ratio <<
"' and min_match_ratio is" << __min_match_ratio << std::endl;
684 std::cout <<
"SurfClassifier(classify): computing ROI" << std::endl;
688 for (
unsigned i = 0; i < matches.size(); i++) {
689 if (matches[i] != -1) {
692 if( (
int)__img_features[matches[i]].x < x_min )
693 x_min = (
int)__img_features[matches[i]].x;
694 if( (
int)__img_features[matches[i]].y < y_min )
695 y_min = (
int)__img_features[matches[i]].y;
696 if( (
int)__img_features[matches[i]].x > x_max )
697 x_max = (
int)__img_features[matches[i]].x;
698 if( (
int)__img_features[matches[i]].y > y_max )
699 y_max = (
int)__img_features[matches[i]].y;
702 if( (c != 0) && ((unsigned)c > __min_match) &&
703 (match_ratio > __min_match_ratio) &&
704 (x_max - x_min != 0 ) && (y_max - y_min != 0) ) {
706 std::cout <<
"SurfClassifier(classify): c='" << c <<
"' __min_match='" << __min_match <<
"'." << std::endl;
708 ROI r(x_min, y_min, x_max-x_min, y_max-y_min,
_width, _height);
712 std::cout <<
" clearing ROI-list (no or too few matches or [0,0]-roi!)" << std::endl;
735 float min_ratio_tmp = -1.0;
736 int min_ratio_index = -1;
737 for(
unsigned int i = 0; i < __num_obj; i++ )
739 if( match_ratios[i] > min_ratio_tmp )
741 min_ratio_tmp = match_ratios[i];
746 std::list<ROI> *final_rv =
new std::list<ROI>;
748 final_rv->assign( rv[min_ratio_index].begin(), rv[min_ratio_index].end() );
751 std::string first_not(
".-");
752 int first_not_index = __obj_names[ min_ratio_index ].find_first_of( first_not );
753 std::string obj_name_tmp( __obj_names[ min_ratio_index ] );
754 obj_name_tmp.erase( first_not_index );
757 std::cout <<
"SurfClassifier(classify): done, ... returning '" << rv->size() <<
"' ROIs. The object class is " << min_ratio_index <<
"and object name is " <<
fawkes::cgreen << obj_name_tmp <<
fawkes::cnormal << std::endl;
762 SurfClassifier::findMatch(
const surf::Ipoint& ip1,
const std::vector< surf::Ipoint >& ipts) {
763 double mind = 1e100, second = 1e100;
768 for (
unsigned i = 0; i < ipts.size(); i++) {
770 if (ipts[i].laplace != ip1.laplace)
773 double d = distSquare(ipts[i].ivec, ip1.ivec, __vlen);
779 }
else if (d < second) {
784 if (mind < 0.5 * second)
792 SurfClassifier::distSquare(
double *v1,
double *v2,
int n) {
798 dsq += (*v1 - *v2) * (*v1 - *v2);
void ping_start(unsigned int cls)
Start of given class task.
virtual std::list< ROI > * classify()
Classify image.
unsigned int _width
Width in pixels of _src buffer.
unsigned int _height
Height in pixels of _src buffer.
static std::string cgreen
Print green on console.
static void log_error(const char *component, const char *format,...)
Log error message.
Base class for exceptions in Fawkes.
unsigned int add_class(std::string name)
Add a new class.
void ping_end(unsigned int cls)
End of given class task.
static std::string cnormal
Print normal on console, without colors, depends on console settings.
Classifier to extract regions of interest.
unsigned int num_hint_points
Minimum estimate of points in ROI that are attributed to the ROI hint.
SurfClassifier(std::string keypoints_descriptor_txt_file, unsigned int min_match=5, float min_match_ratio=MIN_MATCH_RATIO, int samplingStep=2, int octaves=4, double thres=4.0, bool doubleImageSize=false, int initLobe=3, bool upright=false, bool extended=false, int indexSize=4)
Constructor.
static std::string cblue
Print blue on console.
unsigned char * _src
Source buffer, encoded as YUV422_PLANAR.
virtual ~SurfClassifier()
Destructor.