|
@@ -1,847 +0,0 @@
|
|
-/**
|
|
|
|
-* @file PHOGFeature.cpp
|
|
|
|
-* @brief Implementation of the PHOG-Features and corresponding Kernel as done by Anna Bosch et al.
|
|
|
|
-* @author Alexander Lütz
|
|
|
|
-* @date 15/11/2011
|
|
|
|
-*/
|
|
|
|
-
|
|
|
|
-#include "PHOGFeature.h"
|
|
|
|
-
|
|
|
|
-using namespace std;
|
|
|
|
-using namespace OBJREC;
|
|
|
|
-using namespace NICE;
|
|
|
|
-
|
|
|
|
-/** protected things*/
|
|
|
|
-/**
|
|
|
|
-* @brief Calculates the PHOG-Pyramide for given gradient images (idea of Anna Bosch and Andrew Zisserman)
|
|
|
|
-* @author Alexander Lütz
|
|
|
|
-* @date 15/11/2011
|
|
|
|
-*/
|
|
|
|
-void PHOGFeature::calculate_PHOG_Pyramide(const NICE::Image & gradient_orientations, const NICE::ImageT<float> & gradient_magnitudes, std::vector< std::vector<float> > & PHOG_descriptor)
|
|
|
|
-{
|
|
|
|
- float sum_of_all = 0.0;
|
|
|
|
- float sum_of_level = 0.0;
|
|
|
|
-
|
|
|
|
- std::vector<float> one_collecting_vector;
|
|
|
|
- one_collecting_vector.clear();
|
|
|
|
- std::vector<float> HoG (number_Of_Bins);
|
|
|
|
- for (int j = 0; j < gradient_orientations.height(); j++)
|
|
|
|
- for (int i = 0; i < gradient_orientations.width(); i++)
|
|
|
|
- {
|
|
|
|
- int orientation (gradient_orientations(i,j));
|
|
|
|
- if (( (orientation<0) || ((uint)orientation>=HoG.size())) && verbose)
|
|
|
|
- {
|
|
|
|
- cerr << "orientation is " << orientation << " and does not fit to HoG.size(): " << HoG.size() << endl;
|
|
|
|
- cerr << "i: " << i << " j: " << j << " gradient_orientations.width() : " << gradient_orientations.width() << " gradient_orientations.height() : " << gradient_orientations.height() << endl;
|
|
|
|
- }
|
|
|
|
- HoG[gradient_orientations(i,j)] += gradient_magnitudes(i,j);
|
|
|
|
- sum_of_all += gradient_magnitudes(i,j);
|
|
|
|
- sum_of_level += gradient_magnitudes(i,j);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- switch(histrogram_concatenation)
|
|
|
|
- {
|
|
|
|
- case 0:
|
|
|
|
- {
|
|
|
|
- if (sum_of_level != 0.0) //normalize the descriptor-entries
|
|
|
|
- {
|
|
|
|
- for (std::vector<float>::iterator HoG_it = HoG.begin(); HoG_it != HoG.end(); HoG_it++)
|
|
|
|
- {
|
|
|
|
- *HoG_it /= sum_of_level;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- PHOG_descriptor.push_back(HoG);
|
|
|
|
- break;
|
|
|
|
- }
|
|
|
|
- case 1:
|
|
|
|
- {
|
|
|
|
- if (sum_of_level != 0.0) //normalize the descriptor-entries
|
|
|
|
- {
|
|
|
|
- for (std::vector<float>::iterator HoG_it = HoG.begin(); HoG_it != HoG.end(); HoG_it++)
|
|
|
|
- {
|
|
|
|
- *HoG_it /= sum_of_level;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- PHOG_descriptor.push_back(HoG);
|
|
|
|
- break;
|
|
|
|
- }
|
|
|
|
- case 2:
|
|
|
|
- {
|
|
|
|
- one_collecting_vector.insert(one_collecting_vector.begin()+one_collecting_vector.size(), HoG.begin(), HoG.end());
|
|
|
|
- break;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- sum_of_all += sum_of_level;
|
|
|
|
-
|
|
|
|
- if (verbose) cerr << "PHOGFeature::calculate_PHOG_Pyramide -- Level 0 calculated, working on finer levels" << endl;
|
|
|
|
- if (verbose) cerr << "gradient_orientations.width(): " << gradient_orientations.width() << " gradient_orientations.height(): " << gradient_orientations.height() << endl;
|
|
|
|
-
|
|
|
|
- //further levels
|
|
|
|
- for (int level = 1; level < number_of_Levels; level++)
|
|
|
|
- {
|
|
|
|
- if (verbose) cerr << "PHOGFeature::calculate_PHOG_Pyramide -- working on level "<< level << endl;
|
|
|
|
- if (like_AnnaBosch)
|
|
|
|
- {
|
|
|
|
- int step_x = (int) floor(gradient_orientations.width() / pow(2,level) );
|
|
|
|
- int step_y = (int) floor(gradient_orientations.height() / pow(2,level) );
|
|
|
|
-
|
|
|
|
- vector<float> PHoG_level;
|
|
|
|
-
|
|
|
|
- int run_y = 0;
|
|
|
|
- for (int y_counter = 0; y_counter < pow(2.0,level) ; y_counter++)
|
|
|
|
- {
|
|
|
|
- int run_x = 0;
|
|
|
|
- for (int x_counter = 0; x_counter < pow(2.0,level) ; x_counter++)
|
|
|
|
- {
|
|
|
|
- vector<float> HoG_local (number_Of_Bins);
|
|
|
|
- float sum_of_hog(0.0);
|
|
|
|
-
|
|
|
|
- //check, wether rectangle lies on the boundary, if so, then correct the max-step
|
|
|
|
- int y_max = (run_y + step_y);
|
|
|
|
- if (gradient_orientations.height() < y_max)
|
|
|
|
- y_max = gradient_orientations.height();
|
|
|
|
-
|
|
|
|
- int x_max = (run_x + step_x);
|
|
|
|
- if (gradient_orientations.width() < x_max)
|
|
|
|
- x_max = gradient_orientations.width();
|
|
|
|
-
|
|
|
|
- for (int j = run_y; j < y_max; j++)
|
|
|
|
- for (int i = run_x; i < x_max; i++)
|
|
|
|
- {
|
|
|
|
- int orientation = 0;
|
|
|
|
- try{ orientation = gradient_orientations(i,j);
|
|
|
|
- }
|
|
|
|
- catch( ... )
|
|
|
|
- {
|
|
|
|
- cerr << "WARNING: PHOGFeature::calculate_PHOG_Pyramide gradient_orientations(i,j) not possible. (i,j): " << i << " " << j << endl;
|
|
|
|
- }
|
|
|
|
- float magnitude = 0.0;
|
|
|
|
- try{ magnitude = gradient_magnitudes(i,j);
|
|
|
|
- }
|
|
|
|
- catch( ... )
|
|
|
|
- {
|
|
|
|
- cerr << "WARNING: PHOGFeature::calculate_PHOG_Pyramide radient_magnitudes(i,j) not possible. (i,j): " << i << " " << j << endl;
|
|
|
|
- }
|
|
|
|
- HoG_local[orientation] += magnitude;
|
|
|
|
- sum_of_hog += magnitude;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- sum_of_level += sum_of_hog;
|
|
|
|
-
|
|
|
|
- switch(histrogram_concatenation)
|
|
|
|
- {
|
|
|
|
- case 0:
|
|
|
|
- {
|
|
|
|
- if (sum_of_hog != 0.0) //normalize the descriptor-entries
|
|
|
|
- {
|
|
|
|
- for (std::vector<float>::iterator hog_it = HoG_local.begin(); hog_it != HoG_local.end(); hog_it++)
|
|
|
|
- {
|
|
|
|
- *hog_it /= sum_of_hog;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- PHOG_descriptor.push_back(HoG_local);
|
|
|
|
- break;
|
|
|
|
- }
|
|
|
|
- case 1:
|
|
|
|
- {
|
|
|
|
- for (std::vector<float>::const_iterator foo = HoG_local.begin(); foo != HoG_local.end(); foo++)
|
|
|
|
- {
|
|
|
|
- PHoG_level.insert(PHoG_level.begin()+PHoG_level.size(), HoG_local.begin(), HoG_local.end());
|
|
|
|
- }
|
|
|
|
- break;
|
|
|
|
- }
|
|
|
|
- case 2:
|
|
|
|
- {
|
|
|
|
- PHoG_level.insert(PHoG_level.begin()+PHoG_level.size(), HoG_local.begin(), HoG_local.end());
|
|
|
|
- break;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- run_x = run_x + step_x;
|
|
|
|
- }
|
|
|
|
- run_y = run_y + step_y;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- sum_of_all += sum_of_level;
|
|
|
|
-
|
|
|
|
- switch(histrogram_concatenation)
|
|
|
|
- {
|
|
|
|
- case 0:
|
|
|
|
- {
|
|
|
|
- break;
|
|
|
|
- }
|
|
|
|
- case 1:
|
|
|
|
- {
|
|
|
|
- if (sum_of_level != 0.0) //normalize the descriptor-entries
|
|
|
|
- {
|
|
|
|
- for (std::vector<float>::iterator Level_it = PHoG_level.begin(); Level_it != PHoG_level.end(); Level_it++)
|
|
|
|
- {
|
|
|
|
- *Level_it /= sum_of_level;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- PHOG_descriptor.push_back(PHoG_level);
|
|
|
|
- break;
|
|
|
|
- }
|
|
|
|
- case 2:
|
|
|
|
- {
|
|
|
|
- one_collecting_vector.insert(one_collecting_vector.begin()+one_collecting_vector.size(), PHoG_level.begin(), PHoG_level.end());
|
|
|
|
- break;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- else //better than anna bosch
|
|
|
|
- {
|
|
|
|
- int step_x = (int) ceil(gradient_orientations.width() / pow(2.0,level) );
|
|
|
|
- int step_y = (int) ceil(gradient_orientations.height() / pow(2.0,level) );
|
|
|
|
- if (verbose) cerr << "step_x: " << step_x << " step_y: " << step_y << endl;
|
|
|
|
-
|
|
|
|
- std::vector<float> PHoG_level;
|
|
|
|
-
|
|
|
|
- int run_y = 0;
|
|
|
|
- for (int y_counter = 0; y_counter < pow(2,level) ; y_counter++)
|
|
|
|
- {
|
|
|
|
- int run_x = 0;
|
|
|
|
- if (verbose) cerr << "run_y: " << run_y << endl;
|
|
|
|
- for (int x_counter = 0; x_counter < pow(2,level) ; x_counter++)
|
|
|
|
- {
|
|
|
|
- if (verbose) cerr << "run_x: " << run_x << endl;
|
|
|
|
- float sum_of_hog(0.0);
|
|
|
|
- vector<float> HoG_local (number_Of_Bins);
|
|
|
|
-
|
|
|
|
- //check, wether rectangle lies on the boundary, if so, then correct the max-step
|
|
|
|
- int y_max = (run_y + step_y);
|
|
|
|
- if (gradient_orientations.height() < y_max)
|
|
|
|
- {
|
|
|
|
- if (verbose) cerr << "y_max old:: " << y_max << " y_max_new: "<<gradient_orientations.height() << endl;
|
|
|
|
- y_max = gradient_orientations.height();
|
|
|
|
-
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- int x_max = (run_x + step_x);
|
|
|
|
- if (gradient_orientations.width() < x_max)
|
|
|
|
- {
|
|
|
|
- if (verbose) cerr << "x_max old:: " << x_max << " x_max_new: "<<gradient_orientations.width() << endl;
|
|
|
|
- x_max = gradient_orientations.width();
|
|
|
|
-
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- for (int j = run_y; j < y_max; j++)
|
|
|
|
- for (int i = run_x; i < x_max; i++)
|
|
|
|
- {
|
|
|
|
- int orientation = 0;
|
|
|
|
- try{ orientation = gradient_orientations.getPixel(i,j);
|
|
|
|
- }
|
|
|
|
- catch( ... )
|
|
|
|
- {
|
|
|
|
- cerr << "WARNING: PHOGFeature::calculate_PHOG_Pyramide gradient_orientations(i,j) not possible. (i,j): " << i << " " << j << endl;
|
|
|
|
- }
|
|
|
|
- float magnitude = 0.0;
|
|
|
|
- try{ magnitude = gradient_magnitudes.getPixel(i,j);
|
|
|
|
- }
|
|
|
|
- catch( ... )
|
|
|
|
- {
|
|
|
|
- cerr << "WARNING: PHOGFeature::calculate_PHOG_Pyramide gradient_magnitudes(i,j) not possible. (i,j): " << i << " " << j << endl;
|
|
|
|
- }
|
|
|
|
- if ( (orientation<0) || ((uint)orientation>=HoG_local.size()))
|
|
|
|
- {
|
|
|
|
- cerr << "orientation is " << orientation << " and does not fit to HoG_local.size(): " << HoG_local.size() << endl;
|
|
|
|
- cerr << "i: " << i << " j: " << j << " gradient_orientations.width() : " << gradient_orientations.width() << " gradient_orientations.height() : " << gradient_orientations.height() << endl;
|
|
|
|
- }
|
|
|
|
- try{
|
|
|
|
- HoG_local[orientation] += magnitude;
|
|
|
|
- }
|
|
|
|
- catch( ... )
|
|
|
|
- {
|
|
|
|
- cerr << "WARNING: PHOGFeature::calculate_PHOG_Pyramide HoG_local[orientation] += magnitude not possible. orientation: " << orientation << " magnitude " << magnitude << endl;
|
|
|
|
- }
|
|
|
|
- sum_of_hog += magnitude;
|
|
|
|
- }
|
|
|
|
- sum_of_level += sum_of_hog;
|
|
|
|
-
|
|
|
|
- switch(histrogram_concatenation)
|
|
|
|
- {
|
|
|
|
- case 0:
|
|
|
|
- {
|
|
|
|
- if (sum_of_hog != 0.0) //normalize the descriptor-entries
|
|
|
|
- {
|
|
|
|
- for (std::vector<float>::iterator hog_it = HoG_local.begin(); hog_it != HoG_local.end(); hog_it++)
|
|
|
|
- {
|
|
|
|
- *hog_it /= sum_of_hog;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- PHOG_descriptor.push_back(HoG_local);
|
|
|
|
- break;
|
|
|
|
- }
|
|
|
|
- case 1:
|
|
|
|
- {
|
|
|
|
- for (std::vector<float>::const_iterator foo = HoG_local.begin(); foo != HoG_local.end(); foo++)
|
|
|
|
- {
|
|
|
|
- PHoG_level.insert(PHoG_level.begin()+PHoG_level.size(), HoG_local.begin(), HoG_local.end());
|
|
|
|
- }
|
|
|
|
- break;
|
|
|
|
- }
|
|
|
|
- case 2:
|
|
|
|
- {
|
|
|
|
- PHoG_level.insert(PHoG_level.begin()+PHoG_level.size(), HoG_local.begin(), HoG_local.end());
|
|
|
|
- break;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- run_x = run_x + step_x;
|
|
|
|
- }
|
|
|
|
- run_y = run_y + step_y;
|
|
|
|
- }
|
|
|
|
- sum_of_all += sum_of_level;
|
|
|
|
-
|
|
|
|
- switch(histrogram_concatenation)
|
|
|
|
- {
|
|
|
|
- case 0:
|
|
|
|
- {
|
|
|
|
- break;
|
|
|
|
- }
|
|
|
|
- case 1:
|
|
|
|
- {
|
|
|
|
- if (sum_of_level != 0.0) //normalize the descriptor-entries
|
|
|
|
- {
|
|
|
|
- for (std::vector<float>::iterator Level_it = PHoG_level.begin(); Level_it != PHoG_level.end(); Level_it++)
|
|
|
|
- {
|
|
|
|
- *Level_it /= sum_of_level;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- PHOG_descriptor.push_back(PHoG_level);
|
|
|
|
- break;
|
|
|
|
- }
|
|
|
|
- case 2:
|
|
|
|
- {
|
|
|
|
- one_collecting_vector.insert(one_collecting_vector.begin()+one_collecting_vector.size(), PHoG_level.begin(), PHoG_level.end());
|
|
|
|
- break;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- if (histrogram_concatenation == ALL)
|
|
|
|
- {
|
|
|
|
- if (sum_of_all != 0.0) //normalize the descriptor-entries
|
|
|
|
- {
|
|
|
|
- for (std::vector<float>::iterator it = one_collecting_vector.begin(); it != one_collecting_vector.end(); it++)
|
|
|
|
- {
|
|
|
|
- *it /= sum_of_all;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- PHOG_descriptor.push_back(one_collecting_vector);
|
|
|
|
- }
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-/**
|
|
|
|
-* @brief Calculates resulting PHOG-Features for the specified ROI in the given image
|
|
|
|
-* @author Alexander Lütz
|
|
|
|
-* @date 15/11/2011
|
|
|
|
-*/
|
|
|
|
-std::vector< std::vector<float> > PHOGFeature::calculate_PHOG_Features(const NICE::Image & orig_Image, const NICE::Rect & roi)
|
|
|
|
-{
|
|
|
|
- if (like_AnnaBosch) //not supported right now!
|
|
|
|
- {
|
|
|
|
- std::cerr << "PHOGFeature::calculate_PHOG_Features is not supported right now" << std::endl;
|
|
|
|
-// //Canny Edge Detector
|
|
|
|
-// Image canny_Image;
|
|
|
|
-// canny_Image = (*canny(orig_Image, 10,30) );
|
|
|
|
-//
|
|
|
|
-// //gradient-calculation
|
|
|
|
-// GrayImage16s* grad_x_Image= sobelX(canny_Image);
|
|
|
|
-// GrayImage16s* grad_y_Image = sobelY(canny_Image);
|
|
|
|
-// if (verbose) cerr << "gradient-calculation done" << endl;
|
|
|
|
-//
|
|
|
|
-// //gradient-orientation-calculation
|
|
|
|
-// NICE::Image gradient_orientations;
|
|
|
|
-// image_tool.calculateGradientOrientations( *grad_x_Image, *grad_y_Image, number_Of_Bins, gradient_orientations, unsignedBins);
|
|
|
|
-// if (verbose) cerr << "gradient-orientation-calculation done" << endl;
|
|
|
|
-//
|
|
|
|
-// //gradient-magnitude-calculation
|
|
|
|
-// //maybe this is not good - implicit cast from int to float in image structure
|
|
|
|
-// NICE::Image* gradient_magnitudes_int = gradientStrength( (*grad_x_Image), (*grad_y_Image) );
|
|
|
|
-// NICE::ImageT<float> gradient_magnitudes(orig_Image.width(), orig_Image.height());
|
|
|
|
-// for (int y = 0; y < orig_Image.height(); y++)
|
|
|
|
-// for (int x = 0; x < orig_Image.width(); x++)
|
|
|
|
-// {
|
|
|
|
-// gradient_magnitudes.setPixel(x,y,(*gradient_magnitudes_int).getPixel(x,y));
|
|
|
|
-// }
|
|
|
|
-// if (verbose) cerr << "gradient-magnitude-calculation done" << endl;
|
|
|
|
-//
|
|
|
|
-// NICE::Image go_roi (gradient_orientations.subImage(roi));
|
|
|
|
-// NICE::ImageT<float> gm_roi (gradient_magnitudes.subImage(roi));
|
|
|
|
-//
|
|
|
|
-// //pyramide-calculation
|
|
|
|
-//
|
|
|
|
- std::vector< std::vector<float> > PHOG_pyramide;
|
|
|
|
-// calculate_PHOG_Pyramide(go_roi, gm_roi, PHOG_pyramide);
|
|
|
|
-//
|
|
|
|
-// if (verbose) cerr << "Pyramide-calculation done" << endl;
|
|
|
|
-
|
|
|
|
- return PHOG_pyramide;
|
|
|
|
-
|
|
|
|
- }
|
|
|
|
- else
|
|
|
|
- {
|
|
|
|
- //gradient-calculation
|
|
|
|
- NICE::ImageT<float> grad_x_Image;
|
|
|
|
- NICE::ImageT<float> grad_y_Image;
|
|
|
|
- image_tool.calculateGradients(orig_Image, grad_x_Image, grad_y_Image );
|
|
|
|
- if (verbose) cerr << "gradient-calculation done" << endl;
|
|
|
|
-
|
|
|
|
- //gradient-orientation-calculation
|
|
|
|
- NICE::Image gradient_orientations;
|
|
|
|
- image_tool.calculateGradientOrientations(grad_x_Image, grad_y_Image, number_Of_Bins, gradient_orientations, unsignedBins);
|
|
|
|
- if (verbose) cerr << "gradient-orientation-calculation done" << endl;
|
|
|
|
-
|
|
|
|
- //gradient-magnitude-calculation
|
|
|
|
- NICE::ImageT<float> gradient_magnitudes;
|
|
|
|
- image_tool.calculateGradientMagnitudes(grad_x_Image, grad_y_Image, gradient_magnitudes);
|
|
|
|
- if (verbose) cerr << "gradient-magnitude-calculation done" << endl;
|
|
|
|
-
|
|
|
|
- NICE::Image go_roi (gradient_orientations.subImage(roi));
|
|
|
|
- NICE::ImageT<float> gm_roi (gradient_magnitudes.subImage(roi));
|
|
|
|
-
|
|
|
|
- //pyramide-calculation
|
|
|
|
-
|
|
|
|
- std::vector< std::vector<float> > PHOG_pyramide;
|
|
|
|
- calculate_PHOG_Pyramide(go_roi, gm_roi, PHOG_pyramide);
|
|
|
|
-
|
|
|
|
- if (verbose) cerr << "Pyramide-calculation done" << endl;
|
|
|
|
-
|
|
|
|
- return PHOG_pyramide;
|
|
|
|
- }
|
|
|
|
-}
|
|
|
|
-//TODO ebenso für Farbbilder, falls das erwünscht ist. Frau Bosch macht einfach nur eine Grauwertkonvertierunt, also auch nicht so schön, wie Dalal und Triggs.!
|
|
|
|
-
|
|
|
|
-
|
|
|
|
-/** public things*/
|
|
|
|
-
|
|
|
|
-/**
|
|
|
|
-* @brief Simple Default Constructor
|
|
|
|
-* @author Alexander Lütz
|
|
|
|
-* @date 15/11/2011
|
|
|
|
-*/
|
|
|
|
-PHOGFeature::PHOGFeature()
|
|
|
|
-{
|
|
|
|
- image_tool = OBJREC::Image_tools();
|
|
|
|
- number_Of_Bins = 9;
|
|
|
|
- unsignedBins = true;
|
|
|
|
- number_of_Levels = 3;
|
|
|
|
- like_AnnaBosch = false;
|
|
|
|
- distances_only_between_levels = true;
|
|
|
|
- histrogram_concatenation = NONE;
|
|
|
|
- verbose = false;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-/**
|
|
|
|
-* @brief Recommended Constructor
|
|
|
|
-* @author Alexander Lütz
|
|
|
|
-* @date 15/11/2011
|
|
|
|
-*/
|
|
|
|
-PHOGFeature::PHOGFeature( const Config *conf, std::string section)
|
|
|
|
-{
|
|
|
|
- image_tool = OBJREC::Image_tools();
|
|
|
|
- number_Of_Bins = conf->gI("PHOGFeature", "number_Of_Bins", 9);
|
|
|
|
- unsignedBins = conf->gB("PHOGFeature", "unsignedBins", true);
|
|
|
|
- number_of_Levels = conf->gI("PHOGFeature", "number_of_Levels", 3);
|
|
|
|
- like_AnnaBosch = conf->gB("PHOGFeature", "like_AnnaBosch", false);
|
|
|
|
- distances_only_between_levels = conf->gB("PHOGFeature", "distances_only_between_levels", true);
|
|
|
|
- switch(conf->gI("PHOGFeature", "histrogram_concatenation", 0) )
|
|
|
|
- {
|
|
|
|
- case 0:
|
|
|
|
- {histrogram_concatenation = NONE; break;}
|
|
|
|
- case 1:
|
|
|
|
- {histrogram_concatenation = LEVELWISE; break;}
|
|
|
|
- case 2:
|
|
|
|
- {histrogram_concatenation = ALL; break;}
|
|
|
|
- }
|
|
|
|
- verbose = conf->gB("PHOGFeature", "verbose", false);
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-/**
|
|
|
|
-* @brief Simple Destructor
|
|
|
|
-* @author Alexander Lütz
|
|
|
|
-* @date 15/11/2011
|
|
|
|
-*/
|
|
|
|
-PHOGFeature::~PHOGFeature()
|
|
|
|
-{
|
|
|
|
-
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-
|
|
|
|
-/**
|
|
|
|
-* @brief Creating the PHOG-featureVectores of all trainingexamples
|
|
|
|
-* @author Alexander Lütz
|
|
|
|
-* @date 15/11/2011
|
|
|
|
-*/
|
|
|
|
-// std::vector<std::vector< std::vector<float> > > PHOGFeature::createAllFeatureVectors(const OBJREC::LabeledSet::Permutation & order)
|
|
|
|
-// {
|
|
|
|
-//
|
|
|
|
-// std::vector<std::vector< std::vector<float> > > PHOG_Features_all_images;
|
|
|
|
-//
|
|
|
|
-// ProgressBar pb_createFV ("PHOGFeature::createAllFeatureVectors");
|
|
|
|
-// pb_createFV.show();
|
|
|
|
-//
|
|
|
|
-// uint k = 0;
|
|
|
|
-// for ( LabeledSet::Permutation::const_iterator i = order.begin(); i != order.end(); i++,k++ )
|
|
|
|
-// {
|
|
|
|
-// string imgfilename = (*i).second->img();
|
|
|
|
-//
|
|
|
|
-// NICE::Image img(imgfilename);
|
|
|
|
-//
|
|
|
|
-// NICE::Rect roi = NICE::Rect(0,0,img.width(),img.height());
|
|
|
|
-// vector<vector<float> > PHOG = calculate_PHOG_Features(img, roi);
|
|
|
|
-//
|
|
|
|
-// PHOG_Features_all_images.push_back ( PHOG );
|
|
|
|
-//
|
|
|
|
-// pb_createFV.update ( order.size() );
|
|
|
|
-// }
|
|
|
|
-//
|
|
|
|
-// // hide the last progress bar
|
|
|
|
-// pb_createFV.hide();
|
|
|
|
-//
|
|
|
|
-// return PHOG_Features_all_images;
|
|
|
|
-// }
|
|
|
|
-
|
|
|
|
-
|
|
|
|
-/**
|
|
|
|
-* @brief Creating the PHOG-featureVectores of all trainingexamples
|
|
|
|
-* @author Alexander Lütz
|
|
|
|
-* @date 15/11/2011
|
|
|
|
-*/
|
|
|
|
-// std::vector<std::vector< std::vector<float> > > PHOGFeature::createAllFeatureVectors(const OBJREC::LabeledSet::Permutation & order, std::vector< NICE::Image > & gradient_orientations, std::vector<NICE::ImageT<float> > & gradient_magnitudes)
|
|
|
|
-// {
|
|
|
|
-//
|
|
|
|
-// std::vector<std::vector< std::vector<float> > > PHOG_Features_all_images;
|
|
|
|
-//
|
|
|
|
-// cerr << "Calculating gradient orientations." << endl;
|
|
|
|
-// gradient_orientations = calculate_gradient_orientations(order);
|
|
|
|
-// cerr << "Calculating gradient magnitudes." << endl;
|
|
|
|
-// gradient_magnitudes = calculate_gradient_magnitudes(order);
|
|
|
|
-//
|
|
|
|
-// ProgressBar pb_quantization ("PHOGFeature::createAllFeatureVectors");
|
|
|
|
-// pb_quantization.show();
|
|
|
|
-//
|
|
|
|
-// uint k = 0;
|
|
|
|
-// for ( LabeledSet::Permutation::const_iterator i = order.begin(); i != order.end(); i++,k++ )
|
|
|
|
-// {
|
|
|
|
-// std::string imgfilename = (*i).second->img();
|
|
|
|
-//
|
|
|
|
-// NICE::Image img(imgfilename);
|
|
|
|
-//
|
|
|
|
-// std::vector<std::vector<float> > PHOG;
|
|
|
|
-// calculate_PHOG_Pyramide(gradient_orientations[k], gradient_magnitudes[k], PHOG);
|
|
|
|
-//
|
|
|
|
-// PHOG_Features_all_images.push_back ( PHOG );
|
|
|
|
-//
|
|
|
|
-// pb_quantization.update ( order.size() );
|
|
|
|
-// }
|
|
|
|
-//
|
|
|
|
-// // hide the last progress bar
|
|
|
|
-// pb_quantization.hide();
|
|
|
|
-//
|
|
|
|
-// return PHOG_Features_all_images;
|
|
|
|
-// }
|
|
|
|
-
|
|
|
|
-/**
|
|
|
|
-* @brief Creating the PHOG-featureVectores of all trainingexamples
|
|
|
|
-* @author Alexander Lütz
|
|
|
|
-* @date 15/11/2011
|
|
|
|
-*/
|
|
|
|
-// // // std::vector<std::vector< std::vector<float> > > PHOGFeature::createAllFeatureVectors(const OBJREC::LabeledSet::Permutation & order, const std::vector<int> & trainSelection)
|
|
|
|
-// // // {
|
|
|
|
-// // //
|
|
|
|
-// // // std::vector<std::vector< std::vector<float> > > PHOG_Features_all_images;
|
|
|
|
-// // //
|
|
|
|
-// // // ProgressBar pb_quantization ("PHOGFeature::createAllFeatureVectors");
|
|
|
|
-// // // pb_quantization.show();
|
|
|
|
-// // //
|
|
|
|
-// // // uint k = 0;
|
|
|
|
-// // // for ( std::vector<int>::const_iterator i = trainSelection.begin(); i != trainSelection.end(); i++,k++ )
|
|
|
|
-// // // {
|
|
|
|
-// // // if (verbose) cerr << " Image number " << *i << " will be treated now" << endl;
|
|
|
|
-// // // string imgfilename = order[*i].second->img();
|
|
|
|
-// // //
|
|
|
|
-// // // NICE::Image img(imgfilename);
|
|
|
|
-// // //
|
|
|
|
-// // // NICE::Rect roi = NICE::Rect(0,0,img.width(),img.height());
|
|
|
|
-// // // vector<vector<float> > PHOG = calculate_PHOG_Features(img, roi);
|
|
|
|
-// // //
|
|
|
|
-// // // PHOG_Features_all_images.push_back ( PHOG );
|
|
|
|
-// // //
|
|
|
|
-// // // pb_quantization.update ( trainSelection.size() );
|
|
|
|
-// // // }
|
|
|
|
-// // //
|
|
|
|
-// // // // hide the last progress bar
|
|
|
|
-// // // pb_quantization.hide();
|
|
|
|
-// // //
|
|
|
|
-// // // return PHOG_Features_all_images;
|
|
|
|
-// // // }
|
|
|
|
-// //
|
|
|
|
-// //
|
|
|
|
-// //
|
|
|
|
-/**
|
|
|
|
-* @brief Creating the PHOG-featureVectore for one trainingexample
|
|
|
|
-* @author Alexander Lütz
|
|
|
|
-* @date 15/11/2011
|
|
|
|
-*/
|
|
|
|
-std::vector<std::vector<float> > PHOGFeature::createOneFeatureVector(const std::string & imgfilename, const NICE::Rect & ROI)
|
|
|
|
-{
|
|
|
|
- NICE::Image img(imgfilename);
|
|
|
|
-
|
|
|
|
- std::vector<std::vector<float> > PHOG (calculate_PHOG_Features(img, ROI));
|
|
|
|
-
|
|
|
|
- return PHOG;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-/**
|
|
|
|
-* @brief Creating the PHOG-featureVectore for one trainingexample
|
|
|
|
-* @author Alexander Lütz
|
|
|
|
-* @date 15/11/2011
|
|
|
|
-*/
|
|
|
|
-std::vector<std::vector<float> > PHOGFeature::createOneFeatureVector(const std::string & imgfilename)
|
|
|
|
-{
|
|
|
|
- NICE::Image img(imgfilename);
|
|
|
|
- NICE::Rect ROI(0,0,img.width(), img.height());
|
|
|
|
-
|
|
|
|
- std::vector<std::vector<float> > PHOG (calculate_PHOG_Features(img, ROI));
|
|
|
|
-
|
|
|
|
- return PHOG;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-/**
|
|
|
|
-* @brief Creating the PHOG-featureVectore for one trainingexample
|
|
|
|
-* @author Alexander Lütz
|
|
|
|
-* @date 15/11/2011
|
|
|
|
-*/
|
|
|
|
-std::vector<std::vector<float> > PHOGFeature::createOneFeatureVector(const NICE::Image img, const NICE::Rect & ROI)
|
|
|
|
-{
|
|
|
|
- std::vector<std::vector<float> > PHOG (calculate_PHOG_Features(img, ROI));
|
|
|
|
-
|
|
|
|
- return PHOG;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-/**
|
|
|
|
-* @brief Creating the PHOG-featureVectore for one trainingexample
|
|
|
|
-* @author Alexander Lütz
|
|
|
|
-* @date 15/11/2011
|
|
|
|
-*/
|
|
|
|
-std::vector<std::vector<float> > PHOGFeature::createOneFeatureVector(const NICE::Image img)
|
|
|
|
-{
|
|
|
|
- NICE::Rect ROI(0,0,img.width(), img.height());
|
|
|
|
- std::vector<std::vector<float> > PHOG (calculate_PHOG_Features(img, ROI));
|
|
|
|
-
|
|
|
|
- return PHOG;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-/**
|
|
|
|
-* @brief computes the featurevector for the given image, which is already converted to a gradient-image, just considering features in the specified ROI
|
|
|
|
-* @author Alexander Lütz
|
|
|
|
-* @date 15/11/2011
|
|
|
|
-*/
|
|
|
|
-std::vector< std::vector<float> > PHOGFeature::createOneFeatureVectorDirect(NICE::Image & gradient_orientations, NICE::ImageT<float> & gradient_magnitudes, const NICE::Rect & ROI)
|
|
|
|
-{
|
|
|
|
- NICE::Image ROI_go (gradient_orientations.subImage(ROI));
|
|
|
|
- NICE::ImageT<float> ROI_gm (gradient_magnitudes.subImage(ROI));
|
|
|
|
-
|
|
|
|
- std::vector< std::vector<float> > PHOG_pyramide;
|
|
|
|
- calculate_PHOG_Pyramide(ROI_go, ROI_gm, PHOG_pyramide);
|
|
|
|
-
|
|
|
|
- return PHOG_pyramide;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-/**
|
|
|
|
-* @brief computes the featurevector for the given image, which is already converted to a gradient-image, considering the whole image
|
|
|
|
-* @author Alexander Lütz
|
|
|
|
-* @date 15/11/2011
|
|
|
|
-*/
|
|
|
|
-std::vector< std::vector<float> > PHOGFeature::createOneFeatureVectorDirect(NICE::Image & gradient_orientations, NICE::ImageT<float> & gradient_magnitudes)
|
|
|
|
-{
|
|
|
|
- NICE::Image ROI_go (gradient_orientations);
|
|
|
|
- NICE::ImageT<float> ROI_gm (gradient_magnitudes);
|
|
|
|
-
|
|
|
|
- std::vector< std::vector<float> > PHOG_pyramide;
|
|
|
|
- calculate_PHOG_Pyramide(ROI_go, ROI_gm, PHOG_pyramide );
|
|
|
|
-
|
|
|
|
- return PHOG_pyramide;
|
|
|
|
-}
|
|
|
|
-// //
|
|
|
|
-// // /**
|
|
|
|
-// // * @brief computes the gradient-orientation-images of all training-images
|
|
|
|
-// // * @author Alexander Lütz
|
|
|
|
-// // * @date 15/11/2011
|
|
|
|
-// // */
|
|
|
|
-// // std::vector< NICE::Image> PHOGFeature::calculate_gradient_orientations(const OBJREC::LabeledSet::Permutation & order)
|
|
|
|
-// // {
|
|
|
|
-// // std::vector< NICE::Image> gradient_orientations;
|
|
|
|
-// //
|
|
|
|
-// // for(OBJREC::LabeledSet::Permutation::const_iterator i = order.begin(); i != order.end(); i++)
|
|
|
|
-// // {
|
|
|
|
-// // string filename = (*i).second->img();
|
|
|
|
-// // NICE::Image img (filename);
|
|
|
|
-// // //gradient-calculation
|
|
|
|
-// // NICE::ImageT<float> grad_x_Image;
|
|
|
|
-// // NICE::ImageT<float> grad_y_Image;
|
|
|
|
-// // image_tool.calculateGradients(img, grad_x_Image, grad_y_Image );
|
|
|
|
-// //
|
|
|
|
-// // //gradient-orientation-calculation
|
|
|
|
-// // NICE::Image gradient_orientation_image;
|
|
|
|
-// // image_tool.calculateGradientOrientations(grad_x_Image, grad_y_Image, number_Of_Bins, gradient_orientation_image, unsignedBins);
|
|
|
|
-// //
|
|
|
|
-// // gradient_orientations.push_back(gradient_orientation_image);
|
|
|
|
-// // }
|
|
|
|
-// //
|
|
|
|
-// // return gradient_orientations;
|
|
|
|
-// // }
|
|
|
|
-//
|
|
|
|
-// /**
|
|
|
|
-// * @brief computes the gradient-magnitudes-images of all training-images
|
|
|
|
-// * @author Alexander Lütz
|
|
|
|
-// * @date 15/11/2011
|
|
|
|
-// */
|
|
|
|
-// std::vector< NICE::ImageT<float> > PHOGFeature::calculate_gradient_magnitudes(const OBJREC::LabeledSet::Permutation & order)
|
|
|
|
-// {
|
|
|
|
-// std::vector< NICE::ImageT<float> > gradient_magnitudes;
|
|
|
|
-//
|
|
|
|
-// for(OBJREC::LabeledSet::Permutation::const_iterator i = order.begin(); i != order.end(); i++)
|
|
|
|
-// {
|
|
|
|
-// string filename = (*i).second->img();
|
|
|
|
-// Image img (filename);
|
|
|
|
-// //gradient-calculation
|
|
|
|
-// NICE::ImageT<float> grad_x_Image;
|
|
|
|
-// NICE::ImageT<float> grad_y_Image;
|
|
|
|
-// image_tool.calculateGradients(img, grad_x_Image, grad_y_Image );
|
|
|
|
-//
|
|
|
|
-// //gradient-orientation-calculation
|
|
|
|
-// NICE::ImageT<float> gradient_magnitude_image;
|
|
|
|
-// image_tool.calculateGradientMagnitudes(grad_x_Image, grad_y_Image, gradient_magnitude_image);
|
|
|
|
-//
|
|
|
|
-// gradient_magnitudes.push_back(gradient_magnitude_image);
|
|
|
|
-// }
|
|
|
|
-//
|
|
|
|
-// return gradient_magnitudes;
|
|
|
|
-// }
|
|
|
|
-
|
|
|
|
-/**
|
|
|
|
-* @brief computes the gradient-orientation-images of all training-images
|
|
|
|
-* @author Alexander Lütz
|
|
|
|
-* @date 15/11/2011
|
|
|
|
-*/
|
|
|
|
-NICE::Image PHOGFeature::calculate_gradient_orientations(const std::string & imgfilenam)
|
|
|
|
-{
|
|
|
|
- NICE::Image gradient_orientations;
|
|
|
|
-
|
|
|
|
- NICE::Image img (imgfilenam);
|
|
|
|
- //gradient-calculation
|
|
|
|
- NICE::ImageT<float> grad_x_Image;
|
|
|
|
- NICE::ImageT<float> grad_y_Image;
|
|
|
|
- image_tool.calculateGradients(img, grad_x_Image, grad_y_Image );
|
|
|
|
-
|
|
|
|
- //gradient-orientation-calculation
|
|
|
|
- NICE::Image gradient_orientation_image;
|
|
|
|
- image_tool.calculateGradientOrientations(grad_x_Image, grad_y_Image, number_Of_Bins, gradient_orientation_image, unsignedBins);
|
|
|
|
-
|
|
|
|
- return gradient_orientations;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-/**
|
|
|
|
-* @brief computes the gradient-magnitudes-images of all training-images
|
|
|
|
-* @author Alexander Lütz
|
|
|
|
-* @date 15/11/2011
|
|
|
|
-*/
|
|
|
|
-NICE::ImageT<float> PHOGFeature::calculate_gradient_magnitudes(const std::string & imgfilename)
|
|
|
|
-{
|
|
|
|
- NICE::ImageT<float> gradient_magnitudes;
|
|
|
|
-
|
|
|
|
- Image img (imgfilename);
|
|
|
|
- //gradient-calculation
|
|
|
|
- NICE::ImageT<float> grad_x_Image;
|
|
|
|
- NICE::ImageT<float> grad_y_Image;
|
|
|
|
- image_tool.calculateGradients(img, grad_x_Image, grad_y_Image );
|
|
|
|
-
|
|
|
|
- //gradient-orientation-calculation
|
|
|
|
- NICE::ImageT<float> gradient_magnitude_image;
|
|
|
|
- image_tool.calculateGradientMagnitudes(grad_x_Image, grad_y_Image, gradient_magnitude_image);
|
|
|
|
-
|
|
|
|
- return gradient_magnitudes;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-/**
|
|
|
|
-* @brief Compute the resulting kernel measuring the distance between the given feature-vectores
|
|
|
|
-* @author Alexander Lütz
|
|
|
|
-* @date 15/11/2011
|
|
|
|
-*/
|
|
|
|
-void PHOGFeature::calculate_Kernel_from_Features(const std::vector<std::vector< std::vector<float> > > & PHoG_Features, NICE::Matrix & PHoG_Kernel){
|
|
|
|
-
|
|
|
|
-// ProgressBar pb_kernelcalc ("PHOGFeature::Kernel Calculation");
|
|
|
|
-// pb_kernelcalc.show();
|
|
|
|
- PHoG_Kernel = NICE::Matrix(PHoG_Features.size(), PHoG_Features.size(), 0.0);
|
|
|
|
- uint ik = 0;
|
|
|
|
- for ( std::vector< std::vector < std::vector<float> > >::const_iterator i = PHoG_Features.begin();i != PHoG_Features.end(); i++,ik++ )
|
|
|
|
- {
|
|
|
|
- uint jk = ik;
|
|
|
|
- for ( std::vector< std::vector< std::vector<float> > >::const_iterator j = i;
|
|
|
|
- j != PHoG_Features.end(); j++,jk++ )
|
|
|
|
- {
|
|
|
|
- double kernelValue (measureDistance(*i,*j));
|
|
|
|
-
|
|
|
|
- PHoG_Kernel(ik,jk) = kernelValue;
|
|
|
|
- PHoG_Kernel(jk,ik) = kernelValue;
|
|
|
|
- }
|
|
|
|
-// pb_kernelcalc.update ( PHoG_Features.size() );
|
|
|
|
- }
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-/**
|
|
|
|
-* @brief function which computes the exp^(-Chi^2)-kernel of two PHOG-feature-vectores a and b
|
|
|
|
-* @author Alexander Lütz
|
|
|
|
-* @date 15/11/2011
|
|
|
|
-*/
|
|
|
|
-double PHOGFeature::measureDistance ( const std::vector<std::vector<float> > & a, const std::vector<std::vector<float> > & b )
|
|
|
|
-{
|
|
|
|
- double expChi_value = 0.0;
|
|
|
|
-
|
|
|
|
- if (a.size() != b.size() ) {
|
|
|
|
- cerr << "a.size(): " << a.size() << " and b.size(): " << b.size() << endl;
|
|
|
|
- fthrow(IOException, "Sizes of PHOG-Feature-vectores do not fit!");
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- for (uint i = 0; i < a.size(); i++) //run over every HoG-Level
|
|
|
|
- {
|
|
|
|
- std::vector<float> a_intern = a[i];
|
|
|
|
- std::vector<float> b_intern = b[i];
|
|
|
|
-
|
|
|
|
- double chi_value = 0.0;
|
|
|
|
-
|
|
|
|
- if (a_intern.size() != b_intern.size() ) {
|
|
|
|
- cerr << "a_intern.size(): " << a_intern.size() << " and b_intern.size(): " << b_intern.size() << endl;
|
|
|
|
- fthrow(IOException, "Sizes of PHOG-Feature-vectores do not fit!");
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- for (uint j = 0; j < a_intern.size(); j++) //run over every HoG-entry of this level
|
|
|
|
- {
|
|
|
|
- float u = a_intern[j];
|
|
|
|
- float v = b_intern[j];
|
|
|
|
- float s = ( u + v );
|
|
|
|
- if ( fabs(s) < 10e-6 ) continue;
|
|
|
|
- float d = u-v;
|
|
|
|
- chi_value += d*d / s;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- chi_value *= 0.5;
|
|
|
|
- expChi_value += exp(-chi_value);
|
|
|
|
- }
|
|
|
|
- expChi_value /= a.size(); //normalize to be in between zero and one
|
|
|
|
-
|
|
|
|
- return expChi_value;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-/**
|
|
|
|
-* @brief Simply set the verbose-flag
|
|
|
|
-* @author Alexander Lütz
|
|
|
|
-* @date 15/11/2011
|
|
|
|
-*/
|
|
|
|
-void PHOGFeature::set_verbose(const bool & new_verbose){
|
|
|
|
- verbose = new_verbose;
|
|
|
|
-}
|
|
|