27 #include <fvclassifiers/siftpp.h> 30 #include <utils/time/clock.h> 31 #include <utils/time/tracker.h> 34 #include <core/exception.h> 35 #include <core/exceptions/software.h> 36 #include <fvutils/color/colorspaces.h> 37 #include <fvutils/color/conversions.h> 38 #include <fvutils/readers/png.h> 72 SiftppClassifier::SiftppClassifier(
const char * object_file,
73 int samplingStep,
int octaves,
int levels,
74 float magnif,
int noorient,
int unnormalized)
78 __samplingStep = samplingStep;
83 __threshold = 0.04f / __levels / 2.0f ;
84 __edgeThreshold = 10.0f;
86 __noorient = noorient;
87 __unnormalized = unnormalized;
96 __ttc_objconv = __tt->
add_class(
"ObjectConvert");
97 __ttc_objfeat = __tt->
add_class(
"ObjectFeatures");
98 __ttc_imgconv = __tt->
add_class(
"ImageConvert");
99 __ttc_imgfeat = __tt->
add_class(
"ImageFeatures");
100 __ttc_matchin = __tt->
add_class(
"Matching");
101 __ttc_roimerg = __tt->
add_class(
"MergeROIs");
115 VL::pixel_t * im_pt =
new VL::pixel_t [lwidth * lheight ];
116 VL::pixel_t * start = im_pt;
118 for (
unsigned int h = 0; h < lheight; ++h) {
119 for (
unsigned int w = 0; w < lwidth ; ++w) {
120 int i = (buf[h * lwidth + w] );
121 VL::pixel_t norm = VL::pixel_t( 255 );
122 *start++ = VL::pixel_t( i ) / norm;
126 __obj_img =
new VL::PgmBuffer();
127 __obj_img->width = lwidth;
128 __obj_img->height = lheight;
129 __obj_img->data = im_pt;
132 throw Exception(
"Could not load object file");
147 __obj_features.clear();
149 __obj_num_features = 0;
152 __sigma0 = 1.6 * powf(2.0f, 1.0f / __levels) ;
154 std::cout <<
"SiftppClassifier(ctor): init scalespace" << std::endl;
156 VL::Sift sift(__obj_img->data, __obj_img->width, __obj_img->height,
157 __sigman, __sigma0, __octaves, __levels, __first, -1, __levels+1) ;
159 std::cout <<
"SiftppClassifier(ctor): detect object keypoints" << std::endl;
161 sift.detectKeypoints(__threshold, __edgeThreshold) ;
163 __obj_num_features = sift.keypointsEnd() - sift.keypointsBegin();
164 std::cout <<
"SiftppClassifier(ctor): computed '" << __obj_num_features <<
"' object-keypoints" << std::endl;
167 sift.setNormalizeDescriptor( ! __unnormalized ) ;
168 sift.setMagnification( __magnif ) ;
170 std::cout <<
"SiftppClassifier(ctor): run detector, compute ori and des ..." << std::endl;
172 for( VL::Sift::KeypointsConstIter iter = sift.keypointsBegin() ;
173 iter != sift.keypointsEnd() ; ++iter ) {
182 VL::float_t angles [4] ;
185 nangles = sift.computeKeypointOrientations(angles, *iter) ;
188 angles[0] = VL::float_t(0) ;
191 feat.
descs =
new VL::float_t*[nangles];
195 for(
int a = 0 ; a < nangles ; ++a) {
199 feat.
descs[a] =
new VL::float_t[__vlen];
200 sift.computeKeypointDescriptor(feat.
descs[a], *iter, angles[a]) ;
205 __obj_features.push_back( feat );
209 __obj_num_features = __obj_features.size();
210 if ( ! __obj_num_features > 0 ) {
211 throw Exception(
"Could not compute object features");
213 std::cout <<
"SiftppClassifier(ctor): computed '" << __obj_num_features <<
"' features from object" << std::endl;
227 __obj_features.clear();
230 __img_features.clear();
242 std::list< ROI > *rv =
new std::list< ROI >();
253 std::cout <<
"SiftppClassifier(classify): copy imgdat to SIFTPP Image" << std::endl;
256 VL::pixel_t * start = im_pt;
257 for (
unsigned int h = 0; h <
_height; ++h) {
258 for (
unsigned int w = 0; w <
_width ; ++w) {
259 int i = (
_src[h * _width + w] );
260 VL::pixel_t norm = VL::pixel_t( 255 );
261 *start++ = VL::pixel_t( i ) / norm;
265 __image =
new VL::PgmBuffer();
268 __image->data = im_pt;
282 __img_features.clear();
283 __img_num_features = 0;
286 std::cout <<
"SiftppClassifier(classify): init scalespace" << std::endl;
288 VL::Sift sift(__image->data, __image->width, __image->height,
289 __sigman, __sigma0, __octaves, __levels, __first, -1, __levels+1) ;
291 std::cout <<
"SiftppClassifier(classify): detect image keypoints" << std::endl;
293 sift.detectKeypoints(__threshold, __edgeThreshold) ;
296 __img_num_features = sift.keypointsEnd() - sift.keypointsBegin();
297 std::cout <<
"SiftppClassifier(classify): Extracted '" << __img_num_features <<
"' image keypoints" << std::endl;
300 sift.setNormalizeDescriptor( ! __unnormalized ) ;
301 sift.setMagnification( __magnif ) ;
303 std::cout <<
"SiftppClassifier(classify): run detector, compute ori and des ..." << std::endl;
305 for( VL::Sift::KeypointsConstIter iter = sift.keypointsBegin() ;
306 iter != sift.keypointsEnd() ; ++iter ) {
315 VL::float_t angles [4] ;
318 nangles = sift.computeKeypointOrientations(angles, *iter) ;
321 angles[0] = VL::float_t(0) ;
324 feat.
descs =
new VL::float_t*[nangles];
328 for(
int a = 0 ; a < nangles ; ++a) {
330 feat.
descs[a] =
new VL::float_t[__vlen] ;
331 sift.computeKeypointDescriptor(feat.
descs[a], *iter, angles[a]) ;
336 __img_features.push_back( feat );
341 __img_num_features = __img_features.size();
347 std::cout <<
"SiftppClassifier(classify): Extracted '" << __img_num_features <<
"' image features" << std::endl;
352 std::cout <<
"SiftppClassifier(classify): matching ..." << std::endl;
354 std::vector< int > matches(__obj_features.size());
356 for (
unsigned i = 0; i < __obj_features.size(); i++) {
357 int match = findMatch(__obj_features[i], __img_features);
360 std::cout <<
"SiftppClassifier(classify): Matched feature " << i <<
" in object image with feature " << match <<
" in image." << std::endl;
362 ROI r( (
int)(__img_features[matches[i]].key.x)-5, (
int)(__img_features[matches[i]].key.y )-5, 11, 11,
_width, _height);
372 std::cout <<
"SiftppClassifier(classify) matched '" << m <<
"' of '" << __obj_features.size() <<
"' features in scene." << std::endl;
374 std::cout <<
"SiftppClassifier(classify): computing ROI" << std::endl;
379 for (
unsigned i = 0; i < matches.size(); i++) {
380 if (matches[i] != -1) {
381 if( (
int)__img_features[matches[i]].key.x < x_min )
382 x_min = (
int)__img_features[matches[i]].key.x;
383 if( (
int)__img_features[matches[i]].key.y < y_min )
384 y_min = (
int)__img_features[matches[i]].key.y;
385 if( (
int)__img_features[matches[i]].key.x > x_max )
386 x_max = (
int)__img_features[matches[i]].key.x;
387 if( (
int)__img_features[matches[i]].key.y > y_max )
388 y_max = (
int)__img_features[matches[i]].key.y;
392 ROI r(x_min, y_min, x_max-x_min, y_max-y_min,
_width, _height);
411 std::cout <<
"SiftppClassifier(classify): done ... returning '" << rv->size() <<
"' ROIs." << std::endl;
416 SiftppClassifier::findMatch(
const Feature & ip1,
const std::vector< Feature > & ipts) {
417 double mind = 1e100, second = 1e100;
420 for (
unsigned i = 0; i < ipts.size(); i++) {
426 double d = distSquare(ipts[i].descs[j], ip1.
descs[j], __vlen);
432 }
else if (d < second) {
438 if (mind < 0.5 * second)
446 SiftppClassifier::distSquare(VL::float_t *v1, VL::float_t *v2,
int n) {
449 dsq += (v1[n-1] - v2[n-1]) * (v1[n-1] - v2[n-1]);
virtual unsigned int pixel_height()
Get height of read image in pixels.
virtual ~SiftppClassifier()
Destructor.
void ping_start(unsigned int cls)
Start of given class task.
VL::float_t ** descs
descriptors
Fawkes library namespace.
virtual unsigned int pixel_width()
Get width of read image in pixels.
virtual void read()
Read data from file.
virtual void set_buffer(unsigned char *yuv422planar_buffer)
Set buffer that the read image should be written to.
unsigned int _width
Width in pixels of _src buffer.
VL::Sift::Keypoint key
keypoint
unsigned int _height
Height in pixels of _src buffer.
int number_of_desc
number of descriptors
Base class for exceptions in Fawkes.
virtual std::list< ROI > * classify()
Classify image.
unsigned int add_class(std::string name)
Add a new class.
void ping_end(unsigned int cls)
End of given class task.
void print_to_stdout()
Print results to stdout.
Classifier to extract regions of interest.
unsigned char * _src
Source buffer, encoded as YUV422_PLANAR.
virtual colorspace_t colorspace()
Get colorspace from the just read image.