openni_listener.cpp
Go to the documentation of this file.
00001 #include "includes/CovarianceMatrix.h"
00002 #include "float.h"
00003 #include "math.h"
00004 #include <iostream>
00005 #include <fstream>
00006 #include "pcl/io/pcd_io.h"
00007 #include "includes/point_types.h"
00008 #include "includes/genericUtils.h"
00009 #include "pcl/filters/passthrough.h"
00010 #include "pcl/filters/extract_indices.h"
00011 #include "pcl/features/intensity_spin.h"
00012 #include "pcl/features/normal_3d.h"
00013 //#include "descriptors_3d/all_descriptors.h"
00014 #include <opencv/cv.h>
00015 #include <opencv/highgui.h>
00016 #include "moveRobot.h"
00017 //#include <point_cloud_mapping/kdtree/kdtree_ann.h>
00018 #include <vector>
00019 #include "sensor_msgs/point_cloud_conversion.h"
00020 #include "includes/color.cpp"
00021 #include "pcl/kdtree/kdtree.h"
00022 #include "pcl/kdtree/tree_types.h"
00023 //#include <point_cloud_mapping/geometry/nearest.h>
00024 #include <pcl_ros/io/bag_io.h>
00025 #include "HOG.cpp"
00026 typedef pcl::PointXYZRGBCamSL PointT;
00027 #include "includes/CombineUtils.h"
00028 #include<boost/numeric/ublas/matrix.hpp>
00029 #include<boost/numeric/ublas/io.hpp>
00030 #include<boost/dynamic_bitset.hpp>
00031 #include "pcl_visualization/pcl_visualizer.h"
00032 typedef pcl_visualization::PointCloudColorHandler<sensor_msgs::PointCloud2> ColorHandler;
00033 typedef ColorHandler::Ptr ColorHandlerPtr;
00034 #include "time.h"
00035 typedef pcl::KdTree<PointT> KdTree;
00036 typedef pcl::KdTree<PointT>::Ptr KdTreePtr;
00037 using namespace boost;
00038 #include "includes/segmentAndLabel.h"
00039 #include "openni_listener.h"
00040 #include <octomap/octomap.h>
00041 #include <octomap_ros/OctomapROS.h>
00042 #include <octomap_ros/conversions.h>
00043 #include <boost/foreach.hpp>
00044 #include <boost/tokenizer.hpp>
00045 using namespace std;
00046 using namespace boost;
00047 using namespace octomap;
00048 #include "wallDistance.h"
00049 ros::Publisher pub;
00050 TransformG globalTransform;
00051 typedef pcl::KdTree<PointT> KdTree;
00052 typedef pcl::KdTree<PointT>::Ptr KdTreePtr;
00053 bool UseVolFeats = false;
00054 bool BinFeatures = true;
00055 static const string nodeBinFile = "binStumpsN.txt";
00056 static const string edgeBinFile = "binStumpsE.txt";
00057 string environment;
00058 
00059 map<int, int> invLabelMap;
00060 map<int, int> labelMap;
00061 pcl::PCDWriter writer;
00062 #define NUM_CLASSES 17
00063 
00064 using namespace Eigen;
00065 Matrix<float, Dynamic, Dynamic> *nodeWeights;
00066 Matrix<float, Dynamic, Dynamic> *edgeWeights[NUM_CLASSES];
00067 vector<int> nodeFeatIndices;
00068 vector<int> edgeFeatIndices;
00069 
00070 
00071 class SpectralProfile {
00072     vector<float> eigenValues; // sorted in ascending order
00073 public:
00074     pcl::PointCloud<PointT>::Ptr cloudPtr;
00075     HOGFeaturesOfBlock avgHOGFeatsOfSegment;
00076     float avgH;
00077     float avgS;
00078     float avgV;
00079     int count;
00080 
00081     geometry_msgs::Point32 centroid;
00082     Eigen::Vector3d normal;
00083 
00084     void setEigValues(Eigen::Vector3d eigenValues_) {
00085         eigenValues.clear();
00086         //Assuming the values are sorted
00087         assert(eigenValues_(0) <= eigenValues_(1));
00088         assert(eigenValues_(1) <= eigenValues_(2));
00089 
00090         for (int i = 0; i < 3; i++)
00091             eigenValues.push_back(eigenValues_(i));
00092         //  std::sort (eigenValues.begin (),eigenValues.end ()); // sorted in ascending order
00093     }
00094 
00095     float getDescendingLambda(int index) const {
00096         return eigenValues[2 - index];
00097     }
00098 
00099     void addCentroid(const SpectralProfile & other)
00100     {        
00101         centroid.x+=other.centroid.x;
00102         centroid.y+=other.centroid.y;
00103         centroid.z+=other.centroid.z;
00104         count++; // will be used for computing average
00105     }
00106     
00107     void transformCentroid(TransformG & trans)
00108     {        
00109         trans.transformPointInPlace(centroid);
00110     }
00111     
00112     void setCentroid(const SpectralProfile & other)
00113     {
00114         centroid=other.centroid;
00115         count=1;
00116     }
00117 
00118     void setAvgCentroid()
00119     {
00120         centroid.x/=count;
00121         centroid.y/=count;
00122         centroid.z/=count;
00123     }
00124     
00125     pcl::PointXYZ getCentroid() {
00126         pcl::PointXYZ ret;
00127         ret.x = centroid.x;
00128         ret.y = centroid.y;
00129         ret.z = centroid.z;
00130         return ret;
00131     }
00132 
00133     PointT getCentroidSL() {
00134         PointT ret;
00135         ret.x = centroid.x;
00136         ret.y = centroid.y;
00137         ret.z = centroid.z;
00138         return ret;
00139     }
00140     
00141     float getScatter() const {
00142         return getDescendingLambda(0);
00143     }
00144 
00145     float getLinearNess() const {
00146         return (getDescendingLambda(0) - getDescendingLambda(1));
00147     }
00148 
00149     float getPlanarNess() const {
00150         return (getDescendingLambda(1) - getDescendingLambda(2));
00151     }
00152 
00153     float getNormalZComponent() const {
00154         return normal[2];
00155     }
00156 
00157     float getAngleWithVerticalInRadians() const {
00158         return acos(getNormalZComponent());
00159     }
00160 
00161     float getHorzDistanceBwCentroids(const SpectralProfile & other) const {
00162         return sqrt(pow(centroid.x - other.centroid.x, 2) + pow(centroid.y - other.centroid.y, 2));
00163     }
00164 
00165     float getDistanceSqrBwCentroids(const SpectralProfile & other) const {
00166         return pow(centroid.x - other.centroid.x, 2) + pow(centroid.y - other.centroid.y, 2) + pow(centroid.z - other.centroid.z, 2);
00167     }
00168 
00169     float getVertDispCentroids(const SpectralProfile & other) {
00170         return (centroid.z - other.centroid.z);
00171     }
00172 
00173     float getHDiffAbs(const SpectralProfile & other) {
00174         return fabs(avgH - other.avgH);
00175     }
00176 
00177     float getSDiff(const SpectralProfile & other) {
00178         return (avgS - other.avgS);
00179     }
00180 
00181     float getVDiff(const SpectralProfile & other) {
00182         return (avgV - other.avgV);
00183     }
00184 
00185     float getAngleDiffInRadians(const SpectralProfile & other) {
00186         return (getAngleWithVerticalInRadians() - other.getAngleWithVerticalInRadians());
00187     }
00188 
00189     float getNormalDotProduct(const SpectralProfile & other) {
00190         return fabs(normal(0) * other.normal(0) + normal(1) * other.normal(1) + normal(2) * other.normal(2));
00191     }
00192 
00193     float getInnerness(const SpectralProfile & other) {
00194         float r1 = sqrt(centroid.x * centroid.x + centroid.y * centroid.y);
00195         float r2 = sqrt(other.centroid.x * other.centroid.x + other.centroid.y * other.centroid.y);
00196         return r1 - r2;
00197     }
00198 
00199     float pushHogDiffFeats(const SpectralProfile & other, vector<float> & feats) {
00200         avgHOGFeatsOfSegment.pushBackAllDiffFeats(other.avgHOGFeatsOfSegment, feats);
00201     }
00202 
00203     float getCoplanarity(const SpectralProfile & other) {
00204         float dotproduct = getNormalDotProduct(other);
00205         if (fabs(dotproduct) > 0.9) // if the segments are coplanar return the displacement between centroids in the direction of the normal
00206         {
00207             float distance = (centroid.x - other.centroid.x) * normal[0] + (centroid.y - other.centroid.y) * normal[1] + (centroid.z - other.centroid.z) * normal[2];
00208             if (distance == 0 || fabs(distance) < (1 / 1000)) {
00209                 return 1000;
00210             }
00211             return fabs(1 / distance);
00212         } else // else return -1
00213             return -1;
00214     }
00215 
00216     int getConvexity(const SpectralProfile & other, float mindistance) {
00217         VectorG centroid1(centroid.x, centroid.y, centroid.z);
00218         VectorG centroid2(other.centroid.x, other.centroid.y, other.centroid.z);
00219 
00220         VectorG c1c2 = centroid2.subtract(centroid1);
00221         VectorG c2c1 = centroid1.subtract(centroid2);
00222         VectorG normal1(normal[0], normal[1], normal[2]);
00223         VectorG normal2(other.normal[0], other.normal[1], other.normal[2]);
00224         if (mindistance < 0.04 && ((normal1.dotProduct(c1c2) <= 0 && normal2.dotProduct(c2c1) <= 0) || fabs(normal1.dotProduct(normal2)) > 0.95)) // refer local convexity criterion paper
00225         {
00226             return 1;
00227         }
00228         // else return 0
00229         return 0;
00230     }
00231 
00232 };
00233 // global variables related to moving the robot and finding the lables
00234 MoveRobot * robot;
00235 #define MAX_TURNS 2
00236 #define MAX_TRYS 20
00237 int turnCount = 0;
00238 vector<int> labelsToFind; // list of classes to find
00239 boost::dynamic_bitset<> labelsFound(NUM_CLASSES); // if the class label is found or not
00240 boost::dynamic_bitset<> labelsToFindBitset(NUM_CLASSES);
00241 vector<pcl::PointCloud<pcl::PointXYZRGBCamSL> > cloudVector;
00242 std::vector<std::map<int, int> > segIndex2LabelVector;
00243 vector<vector<SpectralProfile> >  spectralProfilesVector;
00244 vector<vector<pcl::PointCloud<PointT> > > segment_cloudsVector;
00245 vector<int > sceneNumVector;
00246 bool all_done = false;
00247 std::ofstream labelsFoundFile;
00248 double currentAngle = 0;
00249 vector<double> rotations;
00250 vector<double> translations;
00251 int objCount = 0;
00252 vector<int> labelsToLookFor; 
00253 vector< vector<pcl::PointXYZI> > locations;
00254 vector<pcl::PointXYZI> maximas(NUM_CLASSES);
00255 bool originalScan = true;
00256 boost::dynamic_bitset<> labelsAlreadyLookedFor(NUM_CLASSES);
00257 boost::dynamic_bitset<> maximaChanged(NUM_CLASSES);
00258 bool foundAny = false;
00259 bool translationState = false;
00260 map<int, double> sceneToAngleMap;
00261 #define SPAN 30
00262 
00263 vector<int> maximaFrames(NUM_CLASSES,0);
00264 class BinStumps {
00265 public:
00266     static const int NUM_BINS = 10;
00267     double binStumps[NUM_BINS];
00268 
00269     BinStumps(string line) {
00270         char_separator<char> sep("\t");
00271         tokenizer<char_separator<char> > tokens(line, sep);
00272         int count = 0;
00273 
00274         BOOST_FOREACH(string t, tokens) {
00275             binStumps[count] = (lexical_cast<double>(t.data()));
00276             //    cout<<t<<":"<<count <<endl;
00277             count++;
00278         }
00279         assert(count == NUM_BINS);
00280     }
00281 
00282     void writeBinnedValues(double value, std::ofstream & file, int featIndex) {
00283         int binv, bindex;
00284         for (int i = 0; i < NUM_BINS; i++) {
00285             binv = 0;
00286             if (value <= binStumps[i])
00287                 binv = 1;
00288             bindex = featIndex * NUM_BINS + i + 1;
00289             file << " " << bindex << ":" << binv;
00290         }
00291     }
00292 
00293     void storeBinnedValues(double value, Matrix<float, Dynamic, 1 > & mat, int featIndex) {
00294         int binv, bindex;
00295         for (int i = 0; i < NUM_BINS; i++) {
00296             binv = 0;
00297             if (value <= binStumps[i])
00298                 binv = 1;
00299             bindex = featIndex * NUM_BINS + i;
00300             mat(bindex) = binv;
00301         }
00302     }
00303 
00304     void print() {
00305         for (int i = 0; i < NUM_BINS; i++)
00306             cout << "," << binStumps[i];
00307         cout << endl;
00308     }
00309 };
00310 
00311 void createTrees(const std::vector<pcl::PointCloud<PointT> > &segment_clouds, std::vector< pcl::KdTreeFLANN<PointT>::Ptr > &trees) {
00312 
00313     for (size_t i = 0; i < segment_clouds.size(); i++) {
00314         pcl::PointCloud<PointT>::Ptr cloud_ptr(new pcl::PointCloud<PointT > (segment_clouds[i]));
00315         pcl::KdTreeFLANN<PointT>::Ptr tree(new pcl::KdTreeFLANN<PointT>); //= boost::make_shared<pcl::KdTreeFLANN<PointT> > ();
00316         //initTree (0, tree);
00317         tree->setInputCloud(cloud_ptr);
00318         trees.push_back(tree);
00319     }
00320 }
00321 
00322 pair<float, int> getSmallestDistance(PointT centroid, pcl::KdTreeFLANN<PointT>::Ptr tree) {
00323     float min_distance = FLT_MAX;
00324     int min_index = 0;
00325 
00326 
00327     std::vector<int> nn_indices;
00328     nn_indices.resize(2);
00329     std::vector<float> nn_distances;
00330     nn_distances.resize(2);
00331     //float tolerance = 0.3;
00332 
00333     tree->nearestKSearch(centroid, 2, nn_indices, nn_distances);
00334 
00335     for (size_t j = 0; j < nn_indices.size(); ++j) // nn_indices[0] should be sq_idx
00336     {
00337         if (min_distance > nn_distances[j]) {
00338             min_distance = nn_distances[j];
00339             min_index = nn_indices[j];
00340             //   cout << "changing min_distance to "  << min_distance<< endl;
00341 
00342         }
00343     }
00344 
00345     return make_pair(sqrt(min_distance), min_index);
00346 }
00347 
00348 int findNeighbors(PointT centroid, const std::vector<pcl::PointCloud<PointT> > &segment_clouds, const std::vector< pcl::KdTreeFLANN<PointT>::Ptr > &trees, vector <int> &neighbor_map) {
00349     neighbor_map.clear();
00350     float tolerance = 0.6;
00351     map< int, float > distance_matrix;
00352     // get distance matrix
00353     for (size_t i = 0; i < segment_clouds.size(); i++) {
00354 
00355         pair<float, int> dist_pair = getSmallestDistance(centroid, trees[i]);
00356         distance_matrix[i] = dist_pair.first;
00357 
00358     }
00359     // get neighbour map
00360     int num_neighbors = 0;
00361     for (map< int, float >::iterator it = distance_matrix.begin(); it != distance_matrix.end(); it++) {
00362         if ((*it).second < tolerance) {
00363             neighbor_map.push_back((*it).first);
00364             num_neighbors++;
00365         }
00366     }
00367     return num_neighbors;
00368 }
00369 
00370 vector<BinStumps> nodeFeatStumps;
00371 vector<BinStumps> edgeFeatStumps;
00372 
00373 void readStumpValues(vector<BinStumps> & featBins, const string & file) {
00374     //    char lineBuf[1000]; // assuming a line is less than 
00375     string line;
00376     ifstream myfile(file.data());
00377 
00378     if (!myfile.is_open()) {
00379         cerr << "cound not find the file:" << file << " which stores the ranges for binning the features .. you should run this program from the folder scene_processing(do roscd scene_processing), or put the binning info files: binStumpsN.txt(for node features) and binStumpsE.txt(for edge features) in current folder and rerun ... exiting with assertion failure" << endl;
00380     }
00381     assert(myfile.is_open());
00382 
00383     while (myfile.good()) {
00384         getline(myfile, line);
00385         //        cout << line << endl;
00386         if (line.length() > 0)
00387             featBins.push_back(BinStumps(line));
00388     }
00389     myfile.close();
00390 
00391 }
00392 
00393 void readWeightVectors() {
00394     nodeFeatIndices.push_back(15);
00395     nodeFeatIndices.push_back(51);
00396     edgeFeatIndices.push_back(5);
00397     edgeFeatIndices.push_back(6);
00398     edgeFeatIndices.push_back(7);
00399     edgeFeatIndices.push_back(10);
00400     nodeWeights = new Matrix<float, Dynamic, Dynamic > (NUM_CLASSES, 10 * nodeFeatIndices.size());
00401     readCSV("weights/node_weights.csv", NUM_CLASSES, 10 * nodeFeatIndices.size(), ",", *nodeWeights);
00402     //      readCSV("weights/node_weights.csv",nodeWeights->rows(),10*nodeFeatIndices.size()," ",*nodeWeights);
00403     //    char lineBuf[1000]; // assuming a line is less than 
00404     for (size_t i = 0; i < NUM_CLASSES; i++) {
00405         edgeWeights[i] = new Matrix<float, Dynamic, Dynamic > (NUM_CLASSES, 10 * edgeFeatIndices.size());
00406         readCSV("weights/edge_weights_" + boost::lexical_cast<std::string > (i) + ".csv", NUM_CLASSES, 10 * edgeFeatIndices.size(), ",", *edgeWeights[i]);
00407     }
00408 
00409 }
00410 
00411 void readInvLabelMap(map<int, int> & invLabelMap, const string & file) {
00412     //    char lineBuf[1000]; // assuming a line is less than 
00413     string line;
00414     ifstream myfile(file.data());
00415 
00416     if (!myfile.is_open()) {
00417         cerr << "cound not find the file:" << file << " which stores the labelmap .. you should run this program from the folder scene_processing(do roscd scene_processing), or put the missing file in current folder and rerun ... exiting with assertion failure" << endl;
00418     }
00419     assert(myfile.is_open());
00420 
00421     int origLabel, svmLabel;
00422     while (myfile.good()) {
00423 
00424         myfile >> origLabel >> svmLabel;
00425         //        getline(myfile, line);
00426         //        cout << line << endl;
00427         invLabelMap[svmLabel] = origLabel;
00428         labelMap[origLabel]=svmLabel;
00429     }
00430     myfile.close();
00431 }
00432 
00433 void readAllStumpValues() {
00434     readStumpValues(nodeFeatStumps, environment + "/" + nodeBinFile);
00435     readStumpValues(edgeFeatStumps, environment + "/" + edgeBinFile);
00436 }
00437 
00438 using namespace pcl;
00439 
00440 class OriginalFrameInfo {
00441     HOG hogDescriptors;
00442     TransformG cameraTrans;
00443     bool cameraTransSet;
00444 
00445 public:
00446     pcl::PointCloud<pcl::PointXYZRGBCamSL>::ConstPtr RGBDSlamFrame; // required to get 2D pixel positions
00447 
00448     void saveImage(int segmentId, int label, vector<Point2DAbhishek>points) {
00449         CvSize size;
00450         size.height = 480;
00451         size.width = 640;
00452         IplImage * image = cvCreateImage(size, IPL_DEPTH_32F, 3);
00453 
00454         pcl::PointXYZRGBCamSL tmp;
00455         for (int x = 0; x < size.width; x++)
00456             for (int y = 0; y < size.height; y++) {
00457                 int index = x + y * size.width;
00458                 tmp = RGBDSlamFrame->points[index];
00459                 ColorRGB tmpColor(tmp.rgb);
00460                 CV_IMAGE_ELEM(image, float, y, 3 * x) = tmpColor.b;
00461                 CV_IMAGE_ELEM(image, float, y, 3 * x + 1) = tmpColor.g;
00462                 CV_IMAGE_ELEM(image, float, y, 3 * x + 2) = tmpColor.r;
00463             }
00464 
00465         ColorRGB tmpColor(0.0, 1.0, 0.0);
00466         for (int i = 0; i < points.size(); i++) {
00467             int x = points[i].x;
00468             int y = points[i].y;
00469 
00470             CV_IMAGE_ELEM(image, float, y, 3 * x) = tmpColor.b;
00471             CV_IMAGE_ELEM(image, float, y, 3 * x + 1) = tmpColor.g;
00472             CV_IMAGE_ELEM(image, float, y, 3 * x + 2) = tmpColor.r;
00473 
00474         }
00475 
00476         char filename[30];
00477         sprintf(filename, "s%d_l%d.png", segmentId, label);
00478         HOG::saveFloatImage(filename, image);
00479         cvReleaseImage(&image);
00480 
00481 
00482     }
00483 
00484     OriginalFrameInfo(pcl::PointCloud<pcl::PointXYZRGBCamSL>::ConstPtr RGBDSlamFrame_) {
00485         cameraTransSet = false;
00486         RGBDSlamFrame = RGBDSlamFrame_;
00487         CvSize size;
00488         size.height = 480;
00489         size.width = 640;
00490         cout << "RGBslam size:" << RGBDSlamFrame->size() << endl;
00491         if (RGBDSlamFrame->size() == 0)
00492             return; // can be 0 for dummy pcds of manually transformed
00493 
00494         assert(RGBDSlamFrame->size() == size.width * size.height); // can be 0 for dummy pcds of manually transformed
00495 
00496         IplImage * image = cvCreateImage(size, IPL_DEPTH_32F, 3);
00497 
00498         pcl::PointXYZRGBCamSL tmp;
00499 
00500         for (int x = 0; x < size.width; x++)
00501             for (int y = 0; y < size.height; y++) {
00502                 int index = x + y * size.width;
00503                 tmp = RGBDSlamFrame->points[index];
00504                 ColorRGB tmpColor(tmp.rgb);
00505                 CV_IMAGE_ELEM(image, float, y, 3 * x) = tmpColor.b;
00506                 CV_IMAGE_ELEM(image, float, y, 3 * x + 1) = tmpColor.g;
00507                 CV_IMAGE_ELEM(image, float, y, 3 * x + 2) = tmpColor.r;
00508             }
00509 
00510         hogDescriptors.computeHog(image);
00511 
00512         cvReleaseImage(&image);
00513     }
00514 
00515     static Point2DAbhishek getPixelFromIndex(int index) {
00516         //assuming size is 640*480;
00517         int width = 640;
00518         Point2DAbhishek ret;
00519         ret.y = index / width;
00520         ret.x = index % width;
00521         assert(index == ret.x + ret.y * width);
00522         return ret;
00523     }
00524 
00525     static void findHog(vector<size_t> & pointIndices, pcl::PointCloud<PointT> &incloud, HOGFeaturesOfBlock &hogSegment, OriginalFrameInfo* targetFrame) {
00526         static int rejectCout = 0;
00527         assert(targetFrame->RGBDSlamFrame->size() > 0);
00528         assert(targetFrame->cameraTransSet);
00529 
00530         vector<Point2DAbhishek> pointsInImageLyingOnSegment;
00531         for (size_t i = 0; i < pointIndices.size(); i++) {
00532             pointsInImageLyingOnSegment.push_back(getPixelFromIndex(pointIndices[i]));
00533         }
00534 
00535         assert(pointsInImageLyingOnSegment.size() > 0);
00536         targetFrame->hogDescriptors.getFeatValForPixels(pointsInImageLyingOnSegment, hogSegment);
00537         // targetFrame->saveImage (incloud.points[pointIndices[1]].segment,incloud.points[pointIndices[1]].label,pointsInImageLyingOnSegment);
00538 
00539     }
00540 
00541     void
00542     setCameraTrans(TransformG cameraTrans) {
00543         this->cameraTrans = cameraTrans;
00544         cameraTransSet = true;
00545     }
00546 
00547     void
00548     applyPostGlobalTrans(TransformG globalTrans) {
00549         //post => premultiply coz point is towards right;
00550         if (cameraTransSet)
00551             cameraTrans = cameraTrans.preMultiply(globalTrans);
00552     }
00553 
00554     TransformG
00555     getCameraTrans() const {
00556         assert(cameraTransSet);
00557         return cameraTrans;
00558     }
00559 
00560     void
00561     setCameraTransSet(bool cameraTransSet) {
00562         this->cameraTransSet = cameraTransSet;
00563     }
00564 
00565     bool
00566     isCameraTransSet() const {
00567         return cameraTransSet;
00568     }
00569 
00570     bool
00571     isEmpty() const {
00572         return RGBDSlamFrame->size() == 0;
00573     }
00574 
00575 };
00576 OriginalFrameInfo * originalFrame;
00577 class BinningInfo {
00578     float max;
00579     float min;
00580     int numBins;
00581     float binSize;
00582 public:
00583 
00584     BinningInfo(float min_, float max_, int numBins_) {
00585         max = max_;
00586         min = min_;
00587         numBins = numBins_;
00588         assert(max > min);
00589         binSize = (max - min) / numBins;
00590 
00591     }
00592 
00593     int
00594     getBinIndex(float value) {
00595         assert(value >= min);
00596         assert(value <= max);
00597 
00598         int bin = ((value - min) / binSize);
00599 
00600         assert(bin <= numBins);
00601 
00602         if (bin == numBins) {
00603             bin = numBins - 1;
00604         }
00605 
00606         return bin;
00607 
00608     }
00609 
00610     float
00611     GetBinSize() const {
00612         return binSize;
00613     }
00614 
00615     int
00616     GetNumBins() const {
00617         return numBins;
00618     }
00619 
00620     float
00621     GetMin() const {
00622         return min;
00623     }
00624 
00625     float
00626     GetMax() const {
00627         return max;
00628     }
00629 };
00630 pcl::PointCloud<PointT> cloudUntransformed;
00631 pcl::PointCloud<PointT> cloudUntransformedUnfiltered;
00632 bool addNodeHeader = true;
00633 bool addEdgeHeader = true;
00634 vector<std::string> nodeFeatNames;
00635 vector<std::string> edgeFeatNames;
00636 void addToNodeHeader(std::string featName, size_t numTimes = 1) {
00637     //char featNameBuf[50];
00638     // assert(featName.length ()<40);
00639     if (addNodeHeader) {
00640         for (size_t i = 0; i < numTimes; i++) {
00641             //       sprintf (featNameBuf,"%s%d",featName,i);
00642             nodeFeatNames.push_back(featName + boost::lexical_cast<std::string > (i));
00643         }
00644     }
00645 }
00646 inline void addToEdgeHeader(std::string featName, size_t numTimes = 1) {
00647     //char featNameBuf[50];
00648     //assert(featName.length ()<40);
00649     if (addEdgeHeader) {
00650         for (size_t i = 0; i < numTimes; i++) {
00651             //sprintf (featNameBuf,"%s%d",featName,i);
00652             edgeFeatNames.push_back(featName + boost::lexical_cast<std::string > (i));
00653         }
00654     }
00655 }
00656 void buildOctoMap(const pcl::PointCloud<PointT> &cloud, OcTreeROS & tree) {
00657 
00658 
00659 
00660     pcl::PointCloud<PointT>::Ptr cloud_ptr(new pcl::PointCloud<PointT > (cloud));
00661     pcl::PointCloud<PointT>::Ptr cloud_cam(new pcl::PointCloud<PointT > ());
00662 
00663 
00664 
00665     // convert to  pointXYZ format
00666     sensor_msgs::PointCloud2 cloud_blob;
00667     pcl::toROSMsg(*cloud_ptr, cloud_blob);
00668     pcl::PointCloud<pcl::PointXYZ> xyzcloud;
00669     pcl::fromROSMsg(cloud_blob, xyzcloud);
00670     // find the camera co-ordinate
00671     VectorG cam_coordinates = originalFrame->getCameraTrans().getOrigin();
00672     pcl::PointXYZ origin(cam_coordinates.v[0], cam_coordinates.v[1], cam_coordinates.v[2]);
00673     // insert to the tree
00674     tree.insertScan(xyzcloud, origin, -1, true);
00675 }
00676 void apply_segment_filter(pcl::PointCloud<PointT> &incloud, pcl::PointCloud<PointT> &outcloud, int segment) {
00677     //ROS_INFO("applying filter");
00678 
00679     outcloud.points.erase(outcloud.points.begin(), outcloud.points.end());
00680 
00681     outcloud.header.frame_id = incloud.header.frame_id;
00682     //    outcloud.points = incloud.points;
00683     outcloud.points.resize(incloud.points.size());
00684 
00685     int j = -1;
00686     for (size_t i = 0; i < incloud.points.size(); ++i) {
00687 
00688         if (incloud.points[i].segment == segment) {
00689             j++;
00690             outcloud.points[j].x = incloud.points[i].x;
00691             outcloud.points[j].y = incloud.points[i].y;
00692             outcloud.points[j].z = incloud.points[i].z;
00693             outcloud.points[j].rgb = incloud.points[i].rgb;
00694             outcloud.points[j].segment = incloud.points[i].segment;
00695             outcloud.points[j].label = incloud.points[i].label;
00696             outcloud.points[j].cameraIndex = incloud.points[i].cameraIndex;
00697             outcloud.points[j].distance = incloud.points[i].distance;
00698 
00699             //     std::cerr<<segment_cloud.points[j].label<<",";
00700         }
00701     }
00702 
00703     // cout<<j << ","<<segment<<endl;
00704     if (j >= 0)
00705         outcloud.points.resize(j + 1);
00706     else
00707         outcloud.points.clear();
00708 }
00709 int MIN_SEG_SIZE = 300;
00710 void apply_segment_filter_and_compute_HOG(pcl::PointCloud<PointT> &incloud, pcl::PointCloud<PointT> &outcloud, int segment, SpectralProfile & feats) {
00711     //ROS_INFO("applying filter");
00712 
00713     outcloud.points.erase(outcloud.points.begin(), outcloud.points.end());
00714 
00715     outcloud.header.frame_id = incloud.header.frame_id;
00716     //    outcloud.points = incloud.points;
00717     outcloud.points.resize(incloud.points.size());
00718 
00719 
00720 
00721 
00722     vector<size_t> indices;
00723     int j = -1;
00724     for (size_t i = 0; i < incloud.points.size(); ++i) {
00725 
00726         if (incloud.points[i].segment == segment) {
00727             j++;
00728             outcloud.points[j].x = incloud.points[i].x;
00729             outcloud.points[j].y = incloud.points[i].y;
00730             outcloud.points[j].z = incloud.points[i].z;
00731             outcloud.points[j].rgb = incloud.points[i].rgb;
00732             outcloud.points[j].segment = incloud.points[i].segment;
00733             outcloud.points[j].label = incloud.points[i].label;
00734             outcloud.points[j].cameraIndex = incloud.points[i].cameraIndex;
00735             outcloud.points[j].distance = incloud.points[i].distance;
00736             //  cerr<<incloud.points[i].cameraIndex<<","<<numFrames<<endl;
00737             indices.push_back(i);
00738 
00739             //     std::cerr<<segment_cloud.points[j].label<<",";
00740         }
00741     }
00742 
00743     // cout<<j << ","<<segment<<endl;
00744     if (j >= MIN_SEG_SIZE) {
00745         outcloud.points.resize(j + 1);
00746         OriginalFrameInfo::findHog(indices, incloud, feats.avgHOGFeatsOfSegment, originalFrame);
00747     } else {
00748         outcloud.points.clear();
00749         return;
00750     }
00751 
00752 }
00753 void apply_segment_filter(pcl::PointCloud<PointT> &incloud, pcl::PointCloud<PointT> &outcloud, int segment, SpectralProfile & feats) {
00754     //ROS_INFO("applying filter");
00755 
00756     outcloud.points.erase(outcloud.points.begin(), outcloud.points.end());
00757 
00758     outcloud.header.frame_id = incloud.header.frame_id;
00759     //    outcloud.points = incloud.points;
00760     outcloud.points.resize(incloud.points.size());
00761 
00762 
00763 
00764 
00765     vector<size_t> indices;
00766     int j = -1;
00767     for (size_t i = 0; i < incloud.points.size(); ++i) {
00768 
00769         if (incloud.points[i].segment == segment) {
00770             j++;
00771             outcloud.points[j].x = incloud.points[i].x;
00772             outcloud.points[j].y = incloud.points[i].y;
00773             outcloud.points[j].z = incloud.points[i].z;
00774             outcloud.points[j].rgb = incloud.points[i].rgb;
00775             outcloud.points[j].segment = incloud.points[i].segment;
00776             outcloud.points[j].label = incloud.points[i].label;
00777             outcloud.points[j].cameraIndex = incloud.points[i].cameraIndex;
00778             outcloud.points[j].distance = incloud.points[i].distance;
00779             //  cerr<<incloud.points[i].cameraIndex<<","<<numFrames<<endl;
00780             indices.push_back(i);
00781 
00782             //     std::cerr<<segment_cloud.points[j].label<<",";
00783         }
00784     }
00785 
00786     // cout<<j << ","<<segment<<endl;
00787     if (j >= MIN_SEG_SIZE) {
00788         outcloud.points.resize(j + 1);
00789        // OriginalFrameInfo::findHog(indices, incloud, feats.avgHOGFeatsOfSegment, originalFrame);
00790     } else {
00791         outcloud.points.clear();
00792         return;
00793     }
00794 
00795 }
00796 void apply_notsegment_filter(const pcl::PointCloud<PointT> &incloud, pcl::PointCloud<PointT> &outcloud, int segment) {
00797     //ROS_INFO("applying filter");
00798 
00799     outcloud.points.erase(outcloud.points.begin(), outcloud.points.end());
00800 
00801     outcloud.header.frame_id = incloud.header.frame_id;
00802     //    outcloud.points = incloud.points;
00803     outcloud.points.resize(incloud.points.size());
00804 
00805     int j = -1;
00806     for (size_t i = 0; i < incloud.points.size(); ++i) {
00807 
00808         if (incloud.points[i].segment != segment) {
00809             j++;
00810             outcloud.points[j].x = incloud.points[i].x;
00811             outcloud.points[j].y = incloud.points[i].y;
00812             outcloud.points[j].z = incloud.points[i].z;
00813             outcloud.points[j].rgb = incloud.points[i].rgb;
00814             outcloud.points[j].segment = incloud.points[i].segment;
00815             outcloud.points[j].label = incloud.points[i].label;
00816             outcloud.points[j].cameraIndex = incloud.points[i].cameraIndex;
00817             outcloud.points[j].distance = incloud.points[i].distance;
00818 
00819             //     std::cerr<<segment_cloud.points[j].label<<",";
00820         }
00821     }
00822     // cout<<j << ","<<segment<<endl;
00823     assert(j >= 0);
00824     outcloud.points.resize(j + 1);
00825 }
00826 void apply_camera_filter(const pcl::PointCloud<PointT> &incloud, pcl::PointCloud<PointT> &outcloud, int camera) {
00827     //ROS_INFO("applying filter");
00828 
00829     outcloud.points.erase(outcloud.points.begin(), outcloud.points.end());
00830 
00831     outcloud.header.frame_id = incloud.header.frame_id;
00832     //    outcloud.points = incloud.points;
00833     outcloud.points.resize(incloud.points.size());
00834 
00835     int j = -1;
00836     for (size_t i = 0; i < incloud.points.size(); ++i) {
00837 
00838         if (incloud.points[i].cameraIndex == camera) {
00839             j++;
00840             outcloud.points[j].x = incloud.points[i].x;
00841             outcloud.points[j].y = incloud.points[i].y;
00842             outcloud.points[j].z = incloud.points[i].z;
00843             outcloud.points[j].rgb = incloud.points[i].rgb;
00844             outcloud.points[j].segment = incloud.points[i].segment;
00845             outcloud.points[j].label = incloud.points[i].label;
00846             outcloud.points[j].cameraIndex = incloud.points[i].cameraIndex;
00847             outcloud.points[j].distance = incloud.points[i].distance;
00848 
00849             //     std::cerr<<segment_cloud.points[j].label<<",";
00850         }
00851     }
00852     // cout<<j << ","<<segment<<endl;
00853     assert(j >= 0);
00854     outcloud.points.resize(j + 1);
00855 }
00856 float getDistanceToBoundary(const pcl::PointCloud<PointT> &cloud1, const pcl::PointCloud<PointT> &cloud2) {
00857     float max_distance = 0;
00858     for (size_t i = 0; i < cloud1.points.size(); ++i) {
00859         float pdist = 0;
00860         for (size_t j = 0; j < cloud2.points.size(); ++j) {
00861             float point_dist = pow((cloud1.points[i].x - cloud2.points[j].x), 2) + pow((cloud1.points[i].y - cloud2.points[j].y), 2) + pow((cloud1.points[i].z - cloud2.points[j].z), 2);
00862             float distance = (pow(cloud2.points[j].distance, 2) - pow(cloud1.points[i].distance, 2) - (point_dist)) / (2 * cloud1.points[i].distance);
00863             if (pdist < distance) pdist = distance;
00864             if (max_distance < distance) max_distance = distance;
00865             // cout << distance << " " << pdist<< " " << max_distance<< endl;
00866         }
00867         // cloud1.points[i].distance = pdist;
00868     }
00869     return max_distance;
00870 }
00871 pair<float, int> getSmallestDistance(const pcl::PointCloud<PointT> &cloud1, const pcl::PointCloud<PointT> &cloud2) {
00872     float min_distance = FLT_MAX;
00873     int min_index = 0;
00874     pcl::PointCloud<PointT>::Ptr small_cloud;
00875     pcl::PointCloud<PointT>::Ptr big_cloud;
00876     if (cloud1.points.size() > cloud2.points.size()) {
00877         pcl::PointCloud<PointT>::Ptr cloud_ptr1(new pcl::PointCloud<PointT > (cloud1));
00878         pcl::PointCloud<PointT>::Ptr cloud_ptr2(new pcl::PointCloud<PointT > (cloud2));
00879         small_cloud = cloud_ptr2;
00880         big_cloud = cloud_ptr1;
00881     } else {
00882         pcl::PointCloud<PointT>::Ptr cloud_ptr1(new pcl::PointCloud<PointT > (cloud1));
00883         pcl::PointCloud<PointT>::Ptr cloud_ptr2(new pcl::PointCloud<PointT > (cloud2));
00884         small_cloud = cloud_ptr1;
00885         big_cloud = cloud_ptr2;
00886     }
00887 
00888     pcl::KdTreeFLANN<PointT>::Ptr tree(new pcl::KdTreeFLANN<PointT>); //= boost::make_shared<pcl::KdTreeFLANN<PointT> > ();
00889     //initTree (0, tree);
00890     tree->setInputCloud(big_cloud); // ,indicesp);
00891     std::vector<int> nn_indices;
00892     nn_indices.resize(2);
00893     std::vector<float> nn_distances;
00894     nn_distances.resize(2);
00895     //float tolerance = 0.3;
00896 
00897     for (size_t i = 0; i < small_cloud->points.size(); ++i) {
00898 
00899         //if (!tree->radiusSearch ((*small_cloud).points[i], tolerance, nn_indices, nn_distances))
00900         tree->nearestKSearch(small_cloud->points[i], 2, nn_indices, nn_distances);
00901 
00902         for (size_t j = 0; j < nn_indices.size(); ++j) // nn_indices[0] should be sq_idx
00903         {
00904 
00905             //float distance = pow(cloud1.points[i].x - cloud2.points[nn_indices[j]].x,2) + pow(cloud1.points[i].y - cloud2.points[ nn_indices[j]].y,2) + pow(cloud1.points[i].z - cloud2.points[ nn_indices[j]].z,2);
00906             //cout<< "i,j = " << i << "," << j<< " dist = " <<distance << endl;
00907             //float a = nn_distances[j];
00908             //cout<< nn_distances[j] << " "<< a << endl;
00909             if (min_distance > nn_distances[j]) {
00910                 min_distance = nn_distances[j];
00911                 min_index = nn_indices[j];
00912                 //   cout << "changing min_distance to "  << min_distance<< endl;
00913 
00914             }
00915         }
00916     }
00917 
00918     /*
00919       for (size_t i = 0; i < cloud1.points.size (); ++i)
00920       { 
00921        for (size_t j = 0; j < cloud2.points.size (); ++j)
00922        {
00923           float distance = pow(cloud1.points[i].x - cloud2.points[j].x,2) + pow(cloud1.points[i].y - cloud2.points[j].y,2) + pow(cloud1.points[i].z - cloud2.points[j].z,2);
00924          // cerr<< "i,j = " << i << "," << j<< " dist = " <<distance << endl;
00925           if (min_distance > distance) min_distance = distance;
00926        }
00927       }
00928      */
00929     return make_pair(sqrt(min_distance), min_index);
00930 }
00931 
00939 int get_neighbors(const std::vector<pcl::PointCloud<PointT> > &segment_clouds, map< pair <int, int>, float > &distance_matrix, map <int, vector <int> > &neighbor_map) {
00940     float tolerance = 0.6;
00941     // get distance matrix
00942     for (size_t i = 0; i < segment_clouds.size(); i++) {
00943         for (size_t j = i + 1; j < segment_clouds.size(); j++) {
00944             pair<float, int> dist_pair = getSmallestDistance(segment_clouds[i], segment_clouds[j]);
00945             distance_matrix[make_pair(segment_clouds[i].points[1].segment, segment_clouds[j].points[1].segment)] = dist_pair.first;
00946             distance_matrix[make_pair(segment_clouds[j].points[1].segment, segment_clouds[i].points[1].segment)] = dist_pair.first;
00947         }
00948         //     std::cerr<< "size of segment " << i << " : " << segment_clouds[i].points.size() << "\t and label is: " << segment_clouds[i].points[1].label <<"\n";
00949     }
00950     // get neighbour map
00951     int num_neighbors = 0;
00952     for (map< pair <int, int>, float >::iterator it = distance_matrix.begin(); it != distance_matrix.end(); it++) {
00953         if ((*it).second < tolerance) {
00954             neighbor_map[(*it).first.first].push_back((*it).first.second);
00955             num_neighbors++;
00956         }
00957         //     cout << (*it).first.first << "," << (*it).first.second <<" => " << (*it).second << endl;
00958     }
00959     /*
00960     // printing the neighbor_map
00961         for ( map< int, vector <int> >::iterator it=neighbor_map.begin() ; it != neighbor_map.end(); it++ )
00962         {
00963           cout << (*it).first << " => ";
00964           for (vector<int>::iterator it2 = (*it).second.begin(); it2 != (*it).second.end(); it2++)
00965             cout << "," << (*it2) ;
00966           cout << endl;
00967         }*/
00968     return num_neighbors;
00969 }
00970 void getSegmentDistanceToBoundary(const pcl::PointCloud<PointT> &cloud, map<int, float> &segment_boundary_distance) {
00971     pcl::PointCloud<PointT>::Ptr cloud_rest(new pcl::PointCloud<PointT > ());
00972     pcl::PointCloud<PointT>::Ptr cloud_cam(new pcl::PointCloud<PointT > ());
00973     pcl::PointCloud<PointT>::Ptr cloud_seg(new pcl::PointCloud<PointT > ());
00974     pcl::PointCloud<PointT>::Ptr cloud_ptr(new pcl::PointCloud<PointT > (cloud));
00975 
00976     int cnt = 0;
00977     // find all the camera indices// find the max segment number
00978 
00979     map<int, int> camera_indices;
00980     for (size_t i = 0; i < cloud.points.size(); ++i) {
00981         camera_indices[(int) cloud.points[i].cameraIndex] = 1;
00982     }
00983     // for every camera index .. apply filter anf get the point cloud
00984     for (map<int, int>::iterator it = camera_indices.begin(); it != camera_indices.end(); it++) {
00985         int ci = (*it).first;
00986         apply_camera_filter(*cloud_ptr, *cloud_cam, ci);
00987 
00988         // find the segment list
00989         map<int, int> segments;
00990         for (size_t i = 0; i < cloud_cam->points.size(); ++i) {
00991             //  if( cloud_cam->points[i].label != 0)
00992             segments[(int) cloud_cam->points[i].segment] = 1;
00993         }
00994         for (map<int, int>::iterator it2 = segments.begin(); it2 != segments.end(); it2++) {
00995             cnt++;
00996             int segnum = (*it2).first;
00997             apply_segment_filter(*cloud_cam, *cloud_seg, segnum);
00998             apply_notsegment_filter(*cloud_cam, *cloud_rest, segnum);
00999             float bdist = getDistanceToBoundary(*cloud_seg, *cloud_rest);
01000 
01001             map<int, float>::iterator segit = segment_boundary_distance.find(segnum);
01002             if (segit == segment_boundary_distance.end() || bdist > segment_boundary_distance[segnum])
01003                 segment_boundary_distance[segnum] = bdist;
01004             // if(cnt == 1)  outcloud = *cloud_seg;
01005             // else outcloud += *cloud_seg;
01006         }
01007 
01008     }
01009 
01010     //for(map<int,float>::iterator it = )
01011 }
01012 void getMinMax(const pcl::PointCloud<PointT> &cloud, const pcl::PointIndices &indices, Eigen::Vector4f &min_p, Eigen::Vector4f &max_p) {
01013     min_p.setConstant(FLT_MAX);
01014     max_p.setConstant(-FLT_MAX);
01015     min_p[3] = max_p[3] = 0;
01016 
01017     for (size_t i = 0; i < indices.indices.size(); ++i) {
01018         if (cloud.points[indices.indices[i]].x < min_p[0]) min_p[0] = cloud.points[indices.indices[i]].x;
01019         if (cloud.points[indices.indices[i]].y < min_p[1]) min_p[1] = cloud.points[indices.indices[i]].y;
01020         if (cloud.points[indices.indices[i]].z < min_p[2]) min_p[2] = cloud.points[indices.indices[i]].z;
01021 
01022         if (cloud.points[indices.indices[i]].x > max_p[0]) max_p[0] = cloud.points[indices.indices[i]].x;
01023         if (cloud.points[indices.indices[i]].y > max_p[1]) max_p[1] = cloud.points[indices.indices[i]].y;
01024         if (cloud.points[indices.indices[i]].z > max_p[2]) max_p[2] = cloud.points[indices.indices[i]].z;
01025     }
01026 }
01027 void getMinMax(const pcl::PointCloud<PointT> &cloud, Eigen::Vector4f &min_p, Eigen::Vector4f &max_p) {
01028     min_p.setConstant(FLT_MAX);
01029     max_p.setConstant(-FLT_MAX);
01030     min_p[3] = max_p[3] = 0;
01031 
01032     for (size_t i = 0; i < cloud.points.size(); ++i) {
01033         if (cloud.points[i].x < min_p[0]) min_p[0] = cloud.points[i].x;
01034         if (cloud.points[i].y < min_p[1]) min_p[1] = cloud.points[i].y;
01035         if (cloud.points[i].z < min_p[2]) min_p[2] = cloud.points[i].z;
01036 
01037         if (cloud.points[i].x > max_p[0]) max_p[0] = cloud.points[i].x;
01038         if (cloud.points[i].y > max_p[1]) max_p[1] = cloud.points[i].y;
01039         if (cloud.points[i].z > max_p[2]) max_p[2] = cloud.points[i].z;
01040     }
01041 }
01042 void getCentroid(const pcl::PointCloud<PointT> &cloud, Eigen::Vector4f &centroid) {
01043     centroid[0] = 0;
01044     centroid[1] = 0;
01045     centroid[2] = 0;
01046     for (size_t i = 0; i < cloud.points.size(); ++i) {
01047         //assert(cloud.points[i].z>=0);
01048         centroid[0] += cloud.points[i].x;
01049         centroid[1] += cloud.points[i].y;
01050         centroid[2] += cloud.points[i].z;
01051         //assert(centroid[2]>=0);
01052     }
01053     centroid[0] = centroid[0] / (cloud.points.size() - 1);
01054     centroid[1] = centroid[1] / (cloud.points.size() - 1);
01055     centroid[2] = centroid[2] / (cloud.points.size() - 1);
01056 }
01057 void getSpectralProfile(const pcl::PointCloud<PointT> &cloud, SpectralProfile &spectralProfile) {
01058     Eigen::Matrix3d eigen_vectors;
01059     Eigen::Vector3d eigen_values;
01060     sensor_msgs::PointCloud2 cloudMsg2;
01061     pcl::toROSMsg(cloud, cloudMsg2);
01062     sensor_msgs::PointCloud cloudMsg;
01063     sensor_msgs::convertPointCloud2ToPointCloud(cloudMsg2, cloudMsg);
01064     //    cloud_geometry::nearest::computePatchEigenNormalized(cloudMsg, eigen_vectors, eigen_values, spectralProfile.centroid);
01065 
01066     Eigen::Matrix3d covariance_matrix;
01067     computeCovarianceMatrix (cloudMsg, covariance_matrix, spectralProfile.centroid);
01068     for (unsigned int i = 0 ; i < 3 ; i++)
01069       {
01070         for (unsigned int j = 0 ; j < 3 ; j++)
01071           {
01072             covariance_matrix(i, j) /= static_cast<double> (cloudMsg.points.size ());
01073           }
01074       }
01075     Eigen::SelfAdjointEigenSolver<Eigen::Matrix3d> ei_symm (covariance_matrix);
01076     eigen_values = ei_symm.eigenvalues ();
01077     eigen_vectors = ei_symm.eigenvectors ();    
01078 
01079     spectralProfile.setEigValues(eigen_values);
01080     float minEigV = FLT_MAX;
01081 
01082     for (int i = 0; i < 3; i++) {
01083 
01084         //      cout<<"eig value:"<<eigen_values(i)<<endl;
01085         if (minEigV > eigen_values(i)) {
01086             minEigV = eigen_values(i);
01087             //    cout<<"min eig value:"<<minEigV<<endl;
01088             spectralProfile.normal = eigen_vectors.col(i);
01089             // check the angle with line joining the centroid to origin
01090             VectorG centroid(spectralProfile.centroid.x, spectralProfile.centroid.y, spectralProfile.centroid.z);
01091             VectorG camera = originalFrame->getCameraTrans().getOrigin();
01092             VectorG cent2cam = camera.subtract(centroid);
01093             VectorG normal(spectralProfile.normal[0], spectralProfile.normal[1], spectralProfile.normal[2]);
01094             if (normal.dotProduct(cent2cam) < 0) {
01095                 // flip the sign of the normal
01096                 spectralProfile.normal[0] = -spectralProfile.normal[0];
01097                 spectralProfile.normal[1] = -spectralProfile.normal[1];
01098                 spectralProfile.normal[2] = -spectralProfile.normal[2];
01099             }
01100         }
01101     }
01102     assert(minEigV == spectralProfile.getDescendingLambda(2));
01103 }
01104 void getSpectralProfileCent(const pcl::PointCloud<PointT> &cloud, SpectralProfile &spectralProfile) {
01105     assert(1==2); // last line needs to be fixed
01106     Eigen::Matrix3d eigen_vectors;
01107     Eigen::Vector3d eigen_values;
01108     sensor_msgs::PointCloud2 cloudMsg2;
01109     pcl::toROSMsg(cloud, cloudMsg2);
01110     sensor_msgs::PointCloud cloudMsg;
01111     sensor_msgs::convertPointCloud2ToPointCloud(cloudMsg2, cloudMsg);
01112 //    cloud_geometry::nearest::computePatchEigenNormalized(cloudMsg, eigen_vectors, eigen_values, spectralProfile.centroid);
01113 }
01114 void get_feature_average(vector<vector<float> > &descriptor_results, vector<float> &avg_feats) {
01115 
01116     vector<vector<float> >::iterator it = descriptor_results.begin();
01117     while (it->size() == 0) it++;
01118     avg_feats.resize(it->size());
01119 
01120     int count = 0;
01121     for (vector<vector<float> >::iterator it = descriptor_results.begin(); it < descriptor_results.end(); it++) {
01122         if (it->size() > 0) {
01123             count++;
01124         }
01125         vector<float>::iterator i = avg_feats.begin();
01126         for (vector<float>::iterator it2 = it->begin(); it2 < it->end(); it2++, i++) {
01127             *i = *i + *it2;
01128         }
01129 
01130     }
01131     // std::cerr << "average features" << std::endl;
01132     int c = 0;
01133     for (vector<float>::iterator i = avg_feats.begin(); i < avg_feats.end(); i++) {
01134         c++;
01135         *i = *i / count;
01136         //     std::cerr << c << " : " << *i << ",\t";
01137     }
01138     std::cerr << std::endl;
01139 }
01140 void get_feature_histogram(vector<vector<float> > &descriptor_results, vector< vector<float> > &result, vector<BinningInfo> binningInfos) {
01141 
01142     // num_bin = 5;
01143     vector<vector<float> >::iterator it = descriptor_results.begin();
01144     int numFeats = it->size();
01145     result.resize(numFeats);
01146     // set size of result vector
01147 
01148     vector<BinningInfo>::iterator binningInfo = binningInfos.begin();
01149     for (vector<vector<float> >::iterator ires = result.begin(); ires < result.end(); ires++, binningInfo++) {
01150         ires->resize(binningInfo->GetNumBins());
01151     }
01152      for (vector<vector<float> >::iterator it_point = descriptor_results.begin(); it_point < descriptor_results.end(); it_point++) { // iterate over points
01153         vector<BinningInfo>::iterator binningInfo = binningInfos.begin();
01154 
01155         vector<vector<float> >::iterator ires = result.begin();
01156 
01157         assert(numFeats == it_point->size()); //missing features NOT allowed for now.
01158 
01159         for (vector<float>::iterator it_feature = it_point->begin(); it_feature < it_point->end(); it_feature++, binningInfo++, ires++) { // iterate over features of the point
01160 
01161             int bin = binningInfo->getBinIndex(*it_feature);
01162 
01163             //   ROS_INFO("%f %d %d",bin_size,bin,(*ires).size());
01164 
01165             (*ires)[bin] += 1;
01166         }
01167     }
01168 
01169     // normalize and print histogram
01170     //   std::cerr << "historam \n";
01171 
01172     int numPoints = descriptor_results.size();
01173 
01174     int c1 = 0, c2 = 0;
01175     for (vector< vector<float> >::iterator i = result.begin(); i < result.end(); i++) {
01176         c1++;
01177         //     std::cerr << "histogram for feature:" << c1 << "\n";
01178         for (vector<float>::iterator i2 = i->begin(); i2 < i->end(); i2++) {
01179             c2++;
01180             *i2 = *i2 / numPoints;
01181             assert(*i2 <= 1.0);
01182             //  std::cerr << c2 << " : " << *i2 << ",\t";
01183         }
01184         //      std::cerr << std::endl;
01185     }
01186     //  std::cerr << std::endl;
01187 
01188 }
01189 // concat feats (vector-wise) to features vector
01190 void concat_feats(vector<float> &features, vector<vector<float> > &feats) {
01191     for (vector<vector<float> >::iterator it = feats.begin(); it < feats.end(); it++) {
01192 
01193         //       vector<float>::iterator i = features.end();
01194         for (vector<float>::iterator it2 = it->begin(); it2 < it->end(); it2++) {
01195             features.push_back(*it2);
01196         }
01197     }
01198 }
01199 // concat feats vector to features vector
01200 void concat_feats(vector<float> &features, vector<float> &feats) {
01201     for (vector<float>::iterator it = feats.begin(); it < feats.end(); it++) {
01202 
01203         features.push_back(*it);
01204 
01205     }
01206 }
01207 void get_color_features(const pcl::PointCloud<PointT> &cloud, vector<float> &features, SpectralProfile & spectralProfileOfSegment) {
01208     int num_bin_H = 6;
01209     int num_bin_S = 2;
01210     int num_bin_V = 2;
01211     // histogram and average of hue and intensity
01212 
01213     vector<vector<float> > hist_features;
01214     vector<float> avg_features;
01215     vector < vector <float> > color_features(cloud.points.size());
01216     vector <vector <float> >::iterator it = color_features.begin();
01217     for (size_t i = 0; i < cloud.points.size(); ++i, it++) {
01218         ColorRGB c(cloud.points[i].rgb);
01219         (*it).push_back(c.H);
01220         (*it).push_back(c.S);
01221         (*it).push_back(c.V);
01222     }
01223 
01224     vector<BinningInfo> binnigInfos;
01225     binnigInfos.push_back(BinningInfo(0, 360, num_bin_H));
01226     binnigInfos.push_back(BinningInfo(0, 1, num_bin_S));
01227     binnigInfos.push_back(BinningInfo(0, 1, num_bin_V));
01228     get_feature_histogram(color_features, hist_features, binnigInfos);
01229     get_feature_average(color_features, avg_features);
01230 
01231     spectralProfileOfSegment.avgH = avg_features[0];
01232     spectralProfileOfSegment.avgS = avg_features[1];
01233     spectralProfileOfSegment.avgV = avg_features[2];
01234 
01235     concat_feats(features, hist_features);
01236     addToNodeHeader("H_hist", num_bin_H);
01237     addToNodeHeader("S_hist", num_bin_S);
01238     addToNodeHeader("V_hist", num_bin_V);
01239 
01240     concat_feats(features, avg_features);
01241     addToNodeHeader("HAvg");
01242     addToNodeHeader("SAvg");
01243     addToNodeHeader("VAvg");
01244 }
01245 void get_global_features(const pcl::PointCloud<PointT> &cloud, vector<float> &features, SpectralProfile & spectralProfileOfSegment) {
01246 
01247     Eigen::Vector4f min_p;
01248     Eigen::Vector4f max_p;
01249 
01250 
01251 
01252     // get bounding box features
01253     getSpectralProfile(cloud, spectralProfileOfSegment);
01254 
01255     getMinMax(cloud, min_p, max_p);
01256     float xExtent = max_p[0] - min_p[0];
01257     float yExtent = max_p[1] - min_p[1];
01258     float horizontalExtent = sqrt(xExtent * xExtent + yExtent * yExtent);
01259     float zExtent = max_p[2] - min_p[2];
01260 
01261     features.push_back(horizontalExtent);
01262     addToNodeHeader("horizontalExtent");
01263 
01264     features.push_back(zExtent);
01265     addToNodeHeader("zExtent");
01266 
01267     features.push_back(spectralProfileOfSegment.centroid.z);
01268     addToNodeHeader("centroid_z");
01269 
01270 
01271     features.push_back(spectralProfileOfSegment.getNormalZComponent());
01272     addToNodeHeader("normal_z");
01273 
01274     //spectral saliency features
01275     features.push_back((spectralProfileOfSegment.getLinearNess()));
01276     addToNodeHeader("linearness");
01277     features.push_back((spectralProfileOfSegment.getPlanarNess()));
01278     addToNodeHeader("planarness");
01279     features.push_back((spectralProfileOfSegment.getScatter()));
01280     addToNodeHeader("scatter");
01281     spectralProfileOfSegment.avgHOGFeatsOfSegment.pushBackAllFeats(features);
01282     addToNodeHeader("HOG", 31);
01283 
01284 
01285 
01286 
01287 }
01288 float get_occupancy_feature(const pcl::PointCloud<PointT> &cloud1, const pcl::PointCloud<PointT> &cloud2, OcTreeROS & tree) {
01289     //
01290     OcTreeROS::NodeType* treeNode;
01291     int occCount = 0;
01292     int totalCount = 0;
01293     int unknownCount = 0;
01294     for (int i = 0; i < 100; i++) {
01295         int p1Index = rand() % cloud1.points.size();
01296         int p2Index = rand() % cloud2.points.size();
01297         VectorG p1(cloud1.points[p1Index]);
01298         VectorG p2(cloud2.points[p2Index]);
01299         double distance = (p2.subtract(p1)).getNorm();
01300         int count = 0;
01301         for (double r = 0.05; r <= distance - 0.05; r += 0.05) {
01302             count++;
01303             VectorG point = p1.add((p2.subtract(p1).normalizeAndReturn()).multiply(r));
01304             pcl::PointXYZ pt(point.v[0], point.v[1], point.v[2]);
01305             treeNode = tree.search(pt);
01306             if (treeNode) {
01307                 if (treeNode->getOccupancy() > 0.5) {
01308                     occCount++;
01309                 }
01310                 //cout << "Occupancy of node at ("<< pt.x << "," << pt.y<< "," << pt.z << ") = " << treeNode->getOccupancy() << " \n";
01311             } else {
01312                 unknownCount++;
01313                 //cout << "ERROR: OcTreeNode not found (NULL)\n";
01314             }
01315 
01316         }
01317         if (count == 0) {
01318             VectorG point = p1.add(p2.subtract(p1).multiply(0.5));
01319             pcl::PointXYZ pt(point.v[0], point.v[1], point.v[2]);
01320             treeNode = tree.search(pt);
01321             if (treeNode) {
01322                 if (treeNode->getOccupancy() > 0.5) {
01323                     occCount++;
01324                 }
01325                 //cout << "Occupancy of node at ("<< pt.x << "," << pt.y<< "," << pt.z << ") = " << treeNode->getOccupancy() << " \n";
01326             } else {
01327                 unknownCount++;
01328                 //cout << "ERROR: OcTreeNode not found (NULL)\n";
01329             }
01330             count++;
01331         }
01332         totalCount += count;
01333     }
01334     cout << "seg1:" << cloud1.points[1].segment << " label1: " << cloud1.points[1].label << " seg2:" << cloud2.points[1].segment << " label2: " << cloud2.points[1].label << endl;
01335     cout << "total:" << totalCount << " unknown:" << unknownCount << " occupied:" << occCount << endl;
01336     return (float) unknownCount / (float) totalCount;
01337 }
01338 int NUM_ASSOCIATIVE_FEATS = 4 + 1;
01339 void get_pair_features(int segment_id, vector<int> &neighbor_list,
01340         map< pair <int, int>, float > &distance_matrix,
01341         std::map<int, int> &segment_num_index_map,
01342         vector<SpectralProfile> & spectralProfiles,
01343         map < int, vector<float> > &edge_features,
01344         OcTreeROS & tree) {
01345 
01346     SpectralProfile segment1Spectral = spectralProfiles[segment_num_index_map[segment_id]];
01347 
01348     for (vector<int>::iterator it = neighbor_list.begin(); it != neighbor_list.end(); it++) {
01349 
01350         int seg2_id = *it;
01351         SpectralProfile segment2Spectral = spectralProfiles[segment_num_index_map[seg2_id]];
01352 
01353 
01354 
01355 
01356 
01357         //here goes the associative features:
01358         //   segment1Spectral.pushHogDiffFeats (segment2Spectral,edge_features[seg2_id]); addToEdgeHeader ("HOGDiff",31);
01359 
01360         edge_features[seg2_id].push_back(segment1Spectral.getHDiffAbs(segment2Spectral));
01361         addToEdgeHeader("HDiffAbs");
01362 
01363         edge_features[seg2_id].push_back(segment1Spectral.getSDiff(segment2Spectral));
01364         addToEdgeHeader("SDiff");
01365 
01366         edge_features[seg2_id].push_back(segment1Spectral.getVDiff(segment2Spectral));
01367         addToEdgeHeader("Viff");
01368 
01369         edge_features[seg2_id].push_back(segment1Spectral.getCoplanarity(segment2Spectral));
01370         addToEdgeHeader("Coplanarity");
01371 
01372         edge_features[seg2_id].push_back(segment1Spectral.getConvexity(segment2Spectral, distance_matrix[make_pair(segment_id, seg2_id)]));
01373         addToEdgeHeader("convexity");
01374 
01375         assert(edge_features[seg2_id].size() == NUM_ASSOCIATIVE_FEATS);
01376 
01377         //here goes the non-associative features
01378 
01379 
01380         edge_features[seg2_id].push_back(segment1Spectral.getHorzDistanceBwCentroids(segment2Spectral));
01381         addToEdgeHeader("centroid_horz_diff");
01382         // difference in z coordinates of the centroids
01383         edge_features[seg2_id].push_back(segment1Spectral.getVertDispCentroids(segment2Spectral));
01384         addToEdgeHeader("centroid_z_diff");
01385         //cerr << "edge feature for edge (" << seg1_id << "," << seg2_id << ")  = " << centroid_z_diff << endl;
01386 
01387         // distance between closest points
01388         edge_features[seg2_id].push_back(distance_matrix[make_pair(segment_id, seg2_id)]);
01389         addToEdgeHeader("dist_closest");
01390 
01391         // difference of angles with vertical
01392         edge_features[seg2_id].push_back(segment1Spectral.getAngleDiffInRadians(segment2Spectral));
01393         addToEdgeHeader("AngleDiff");
01394 
01395         // dot product of normals
01396         edge_features[seg2_id].push_back(segment1Spectral.getNormalDotProduct(segment2Spectral));
01397         addToEdgeHeader("NormalDotProduct");
01398 
01399 
01400         edge_features[seg2_id].push_back(segment1Spectral.getInnerness(segment2Spectral));
01401         addToEdgeHeader("Innerness");
01402 
01403         // occupancy fraction feature
01404         if (UseVolFeats) {
01405             edge_features[seg2_id].push_back(get_occupancy_feature(*(segment1Spectral.cloudPtr), *(segment2Spectral.cloudPtr), tree));
01406             addToEdgeHeader("Occupancy");
01407         }
01408 
01409         // this line should be in the end
01410         addEdgeHeader = false;
01411     }
01412 
01413 }
01414 void parseAndApplyLabels(std::ifstream & file, pcl::PointCloud<pcl::PointXYZRGBCamSL> & cloud, std::vector<pcl::PointCloud<PointT> > & segment_clouds, map<int, int> & segIndex2label) {
01415     string tokens[3];
01416     char_separator<char> sep1(" ");
01417     char_separator<char> sep2(":");
01418     string line;
01419     getline(file, line);
01420     int count;
01421     tokenizer<char_separator<char> > tokens1(line, sep1);
01422     map<int, int> segId2label;
01423     foundAny = false;
01424     BOOST_FOREACH(string t, tokens1) {
01425         count = 0;
01426         tokenizer<char_separator<char> > tokens2(t, sep2);
01427 
01428         BOOST_FOREACH(string t2, tokens2) {
01429             assert(count < 3);
01430             tokens[count] = t2;
01431             count++;
01432         }
01433         int segmentIndex = (lexical_cast<int>(tokens[0])) - 1;
01434         int segmentId = segment_clouds[segmentIndex].points[1].segment;
01435         int label = lexical_cast<int>(tokens[1]);
01436         segId2label[segmentId] = label;
01437         segIndex2label[segmentIndex] = label;
01438         if (!labelsFound.test(label-1)){
01439             labelsFound.set(label-1, true);
01440             foundAny = true;
01441             cout << "Found label:"<< label-1  <<" in scene" <<  sceneNumVector.back() << "  at :" << currentAngle << endl; 
01442         }
01443         
01444 
01445     }
01446 
01447     for (int i = 0; i < cloud.size(); i++) {
01448         cloud.points[i].label = invLabelMap[segId2label[cloud.points[i].segment]];
01449     }
01450 }
01451 void saveOriginalImages(const pcl::PointCloud<pcl::PointXYZRGBCamSL> &cloud, pcl::PointXYZ max, pcl::PointXYZ min, pcl::PointXYZ steps, int scene_num) {
01452     int numBins[3];
01453     for (int i = 0; i < 3; i++) {
01454         numBins[i] = int((max.data[i] - min.data[i]) / steps.data[i]) + 1;
01455         cout << i << " " << max.data[i] << " " << min.data[i] << " " << steps.data[i] << " " << numBins[i] << endl;
01456     }
01457     CvSize size;
01458 
01459     size.height = numBins[1];
01460     size.width = numBins[0];
01461     IplImage * topImageOriginal = cvCreateImage(size, IPL_DEPTH_32F, 3);
01462     cout << "size of image " << numBins[0] << "x" << numBins[1] << endl;
01463 
01464     size.height = numBins[2];
01465     size.width = numBins[1];
01466     IplImage * frontImageOriginal = cvCreateImage(size, IPL_DEPTH_32F, 3);
01467 
01468     int indexMatrix[numBins[1]][numBins[0]];
01469     for (size_t i = 0; i < numBins[1]; i++)
01470         for (size_t j = 0; j < numBins[0]; j++) {
01471             indexMatrix[i][j] = -1;
01472         }
01473 
01474     int frontIndexMatrix[numBins[2]][numBins[1]];
01475     for (size_t i = 0; i < numBins[2]; i++)
01476         for (size_t j = 0; j < numBins[1]; j++) {
01477             frontIndexMatrix[i][j] = -1;
01478         }
01479 
01480     for (size_t i = 0; i < cloud.points.size(); i++) {
01481         if (isnan(cloud.points[i].x) || isnan(cloud.points[i].y) || isnan(cloud.points[i].z)) {
01482             continue;
01483         }
01484         int xbin = int((cloud.points[i].x - min.data[0]) / steps.data[0]);
01485         int ybin = int((cloud.points[i].y - min.data[1]) / steps.data[1]);
01486         int zbin = int((cloud.points[i].z - min.data[2]) / steps.data[2]);
01487         // cout << "x:" << xbin << " y:" << ybin <<endl;
01488         if (indexMatrix[ybin][xbin] != -1) {
01489             //   cout << "indexMatrix[xbin][ybin]= " << indexMatrix[xbin][ybin] << endl;
01490             if (cloud.points[indexMatrix[ybin][xbin]].z < cloud.points[i].z) {
01491                 indexMatrix[ybin][xbin] = i;
01492             }
01493         } else {
01494             indexMatrix[ybin][xbin] = i;
01495         }
01496         if (frontIndexMatrix[zbin][ybin] != -1) {
01497             //   cout << "indexMatrix[xbin][ybin]= " << indexMatrix[xbin][ybin] << endl;
01498             if (cloud.points[frontIndexMatrix[zbin][ybin]].x > cloud.points[i].x) {
01499                 frontIndexMatrix[zbin][ybin] = i;
01500             }
01501         } else {
01502             frontIndexMatrix[zbin][ybin] = i;
01503         }
01504 
01505 
01506     }
01507     ColorRGB tmpColor;
01508     for (size_t i = 0; i < numBins[0]; i++)
01509         for (size_t j = 0; j < numBins[1]; j++) {
01510             int x = numBins[1] - j - 1;
01511             int y = i;
01512             if (indexMatrix[x][y] != -1) {
01513                 tmpColor.assignColor(cloud.points[indexMatrix[x][y]].rgb);
01514             } else {
01515                 tmpColor.assignColor(0, 0, 0);
01516             }
01517             CV_IMAGE_ELEM(topImageOriginal, float, j, 3 * i) = tmpColor.b;
01518             CV_IMAGE_ELEM(topImageOriginal, float, j, 3 * i + 1) = tmpColor.g;
01519             CV_IMAGE_ELEM(topImageOriginal, float, j, 3 * i + 2) = tmpColor.r;
01520 
01521         }
01522     char filename[30];
01523     sprintf(filename, "top0riginal.png");
01524     HOG::saveFloatImage(filename, topImageOriginal);
01525 
01526     for (size_t i = 0; i < numBins[1]; i++)
01527         for (size_t j = 0; j < numBins[2]; j++) {
01528             int x = numBins[2] - 1 - j;
01529             int y = i;
01530             if (frontIndexMatrix[x][y] != -1) {
01531                 tmpColor.assignColor(cloud.points[frontIndexMatrix[x][y]].rgb);
01532             } else {
01533                 tmpColor.assignColor(0, 0, 0);
01534             }
01535             CV_IMAGE_ELEM(frontImageOriginal, float, j, 3 * i) = tmpColor.b;
01536             CV_IMAGE_ELEM(frontImageOriginal, float, j, 3 * i + 1) = tmpColor.g;
01537             CV_IMAGE_ELEM(frontImageOriginal, float, j, 3 * i + 2) = tmpColor.r;
01538 
01539         }
01540     // char filename[30];
01541     sprintf(filename, "front0riginal%d.png",scene_num);
01542     HOG::saveFloatImage(filename, frontImageOriginal);
01543 
01544 }
01545 int getBinIndex(double value, double min, double step) {
01546     return (value - min) / step;
01547 }
01548 int getBinIndex(pcl::PointXYZ value, pcl::PointXYZ min, pcl::PointXYZ step, int index) {
01549     return (value.data[index] - min.data[index]) / step.data[index];
01550 }
01551 void lookForClassInOriginalFrameOrthographic(vector<int> & classes, pcl::PointCloud<pcl::PointXYZRGBCamSL> & cloud, vector<SpectralProfile> & spectralProfiles, map<int, int> & segIndex2label, const std::vector<pcl::PointCloud<PointT> > &segment_clouds, int scene_num, vector<pcl::PointXYZI> & maximas)
01552 {
01553     pcl::PointXYZ steps(0.01, 0.01, 0.01);
01554     std::vector< pcl::KdTreeFLANN<PointT>::Ptr > trees;
01555 
01556     maximas.resize(classes.size());
01557     createTrees(segment_clouds, trees);
01558     /* find bounding box and discretize
01559      */
01560     pcl::PointXYZ max;
01561     pcl::PointXYZ min;
01562     TransformG invTrans=globalTransform.inverse();
01563     pcl::PointCloud<pcl::PointXYZRGBCamSL>  cloudOriginal=cloud;
01564     invTrans.transformPointCloudInPlaceAndSetOrigin(cloudOriginal);
01565     
01566     for (int i = 0; i < 3; i++)
01567     {
01568         max.data[i] = FLT_MIN;
01569         min.data[i] = FLT_MAX;
01570     }
01571     for (size_t i = 0; i < cloud.size(); i++)
01572     {
01573         for (int j = 0; j < 3; j++)
01574         {
01575             if (max.data[j] < cloudOriginal.points[i].data[j])
01576                 max.data[j] = cloudOriginal.points[i].data[j];
01577 
01578             if (min.data[j] > cloudOriginal.points[i].data[j])
01579                 min.data[j] = cloudOriginal.points[i].data[j];
01580         }
01581     }
01582     saveOriginalImages(cloudOriginal, max, min, steps, scene_num);
01583     int numBins[3];
01584     for (int i = 0; i < 3; i++)
01585     {
01586         numBins[i] = (int) ((max.data[i] - min.data[i]) / steps.data[i]) + 1;
01587     }
01588 
01589     Matrix<float, Dynamic, 1 > nodeFeatsB(nodeFeatIndices.size()*10);
01590     Matrix<float, Dynamic, 1 > edgeFeatsB(edgeFeatIndices.size()*10);
01591     vector<float> nodeFeats(nodeFeatIndices.size(), 0.0);
01592     vector<float> edgeFeats(edgeFeatIndices.size(), 0.0);
01593     cout << "max:" << max << endl;
01594     cout << "min:" << min << endl;
01595     double maxDist[360];
01596     getMaxRanges(maxDist, cloud);
01597     double cost;
01598     double maxCost[classes.size()];
01599     double minCost[classes.size()];
01600     SpectralProfile maxS[classes.size()];
01601     Matrix<float, Dynamic, Dynamic> heatMapTop[classes.size()];
01602     Matrix<float, Dynamic, Dynamic> heatMapFront[classes.size()];
01603 
01604     for (int oclass = 0; oclass < classes.size(); oclass++)
01605     {
01606         minCost[oclass] = DBL_MAX;
01607         maxCost[oclass] = -DBL_MAX;
01608         heatMapTop[oclass].setConstant(numBins[1], numBins[0], -FLT_MAX);
01609         heatMapFront[oclass].setConstant(numBins[2], numBins[1], -FLT_MAX);
01610     }
01611 
01612 
01613 
01614 
01615     int countx = 0;
01616     int county = 0;
01617     int countz = 0;
01618     int k;
01619     float x;
01620     float y;
01621     float z;
01622     for (x = min.x, countx = 0; x < max.x; countx++, x += steps.x)
01623         for (y = min.y, county = 0; y < max.y; county++, y += steps.y)
01624             for (z = min.z, countz = 0; z < max.z; countz++, z += steps.z)
01625             {
01626                 vector<int> neighbors;
01627                     SpectralProfile target;
01628                     target.centroid.x = x;
01629                     target.centroid.y = y;
01630                     target.centroid.z = z;
01631                     
01632                     target.transformCentroid(globalTransform);
01633                     
01634                 PointT centroid=target.getCentroidSL();
01635                 double dist = getWallDistanceCent(maxDist, centroid);
01636                 
01637                     nodeFeats.at(0) = target.centroid.z;
01638                     nodeFeats.at(1) = dist;
01639                     
01640                 if (dist < 0)
01641                     continue;
01642                 findNeighbors(centroid, segment_clouds, trees, neighbors);
01643                 
01644                 for (int oclass = 0; oclass < classes.size(); oclass++)
01645                 {
01646                     k = classes[oclass];
01647                     cost = 0.0;
01648                     //compute feats
01649                     //                nodeFeats.at(1)=0;//dummy for now
01650 
01651 
01652                     for (size_t i = 0; i < nodeFeatIndices.size(); i++)
01653                     {
01654                         nodeFeatStumps[nodeFeatIndices.at(i)].storeBinnedValues(nodeFeats[i], nodeFeatsB, i);
01655                     }
01656 
01657                     cost += nodeFeatsB.dot(nodeWeights->row(k));
01658 
01659                     for (size_t i = 0; i < neighbors.size(); i++)
01660                     {
01661                         int nbrIndex = neighbors.at(i);
01662                         int nbrLabel = segIndex2label[nbrIndex] - 1;
01663                         
01664                         if(nbrLabel<0) // this neighbor was not labeled by the classifier(probably it is using sum<1)
01665                             continue;
01666                         
01667                         //cerr << nbrIndex<<","<<nbrLabel << ",nl - k," << k << endl;
01668                         //assert(nbrLabel != k);
01669                         edgeFeats.at(0) = target.getHorzDistanceBwCentroids(spectralProfiles.at(nbrIndex));
01670                         edgeFeats.at(1) = target.getVertDispCentroids(spectralProfiles.at(nbrIndex));
01671                         edgeFeats.at(2) = target.getDistanceSqrBwCentroids(spectralProfiles.at(nbrIndex));
01672                         edgeFeats.at(3) = target.getInnerness(spectralProfiles.at(nbrIndex));
01673                         //  cout<<"edge feats "<<edgeFeats[0]<<","<<edgeFeats[1]<<","<<edgeFeats[2]<<endl;
01674 
01675                         for (size_t j = 0; j < edgeFeatIndices.size(); j++)
01676                         {
01677                             edgeFeatStumps[edgeFeatIndices.at(j)].storeBinnedValues(edgeFeats[j], edgeFeatsB, j);
01678                         }
01679                         cost += edgeFeatsB.dot(edgeWeights[k]->row(nbrLabel));
01680 
01681                         edgeFeats.at(0) = spectralProfiles.at(nbrIndex).getHorzDistanceBwCentroids(target);
01682                         edgeFeats.at(1) = spectralProfiles.at(nbrIndex).getVertDispCentroids(target);
01683                         edgeFeats.at(2) = spectralProfiles.at(nbrIndex).getDistanceSqrBwCentroids(target);
01684                         edgeFeats.at(3) = spectralProfiles.at(nbrIndex).getInnerness(target);
01685 
01686                         for (size_t j = 0; j < edgeFeatIndices.size(); j++)
01687                         {
01688                             edgeFeatStumps[edgeFeatIndices.at(j)].storeBinnedValues(edgeFeats[j], edgeFeatsB, j);
01689                         }
01690 
01691                         assert(nbrLabel >= 0);
01692                         assert(nbrLabel < NUM_CLASSES);
01693                         assert(k >= 0);
01694                         assert(k < NUM_CLASSES);
01695                         cost += edgeFeatsB.dot(edgeWeights[nbrLabel]->row(k));
01696                     }
01697 
01698                     //     cout<<x<<","<<y<<","<<z<<","<<dist<<","<<cost<<endl;
01699                     if (maxCost[oclass] < cost)
01700                     {
01701                         maxCost[oclass] = cost;
01702                         maxS[oclass].setCentroid( target);
01703                       //  maximas[oclass].x = x;
01704                       //  maximas[oclass].y = y;
01705                       //  maximas[oclass].z = z;
01706                       //  maximas[oclass].intensity = cost;
01707                         //   cout<<"nodeFeats \n"<<nodeFeatsB<<endl;                    
01708                     } 
01709                     else if(maxCost[oclass] == cost)
01710                     {
01711                         maxS[oclass].addCentroid(target);                        
01712                     }
01713 
01714                     if (minCost[oclass] > cost)
01715                     {
01716                         minCost[oclass] = cost;
01717                     }
01718 
01719                     if (heatMapTop[oclass](numBins[1] - 1 - county, countx) < cost)
01720                     {
01721                         heatMapTop[oclass](numBins[1] - 1 - county, countx) = cost;
01722                     }
01723 
01724                     if (heatMapFront[oclass](numBins[2] - 1 - countz, county) < cost)
01725                     {
01726                         heatMapFront[oclass](numBins[2] - 1 - countz, county) = cost;
01727                     }
01728                 }
01729 
01730                 // all feats can be computed using SpectralProfile
01731                 // wall distance will take time
01732                 //use octomap to filter out occluded regions
01733 
01734             }
01735 
01736     for (size_t oclass = 0; oclass < classes.size(); oclass++)
01737     {
01738         //   replace<float>(heatMapTop[oclass], -FLT_MAX, minCost);
01739         //    replace<float>(heatMapFront[oclass], -FLT_MAX, minCost);
01740         maxS[oclass].setAvgCentroid();
01741         maxS[oclass].transformCentroid(invTrans); // come back to original
01742         
01743         maximas[oclass].x = maxS[oclass].centroid.x;
01744         maximas[oclass].y = maxS[oclass].centroid.y;
01745         maximas[oclass].z = maxS[oclass].centroid.z;
01746         maximas[oclass].intensity = maxCost[oclass];
01747         
01748         writeHeatMap<float>((lexical_cast<string > (classes[oclass]) + "_topHeat" + lexical_cast<string > (scene_num) + ".png").data(), heatMapTop[oclass], maxCost[oclass], minCost[oclass], numBins[1] - 1 - getBinIndex(maxS[oclass].getCentroid(), min, steps, 1), getBinIndex(maxS[oclass].getCentroid(), min, steps, 0));
01749         writeHeatMap<float>((lexical_cast<string > (classes[oclass]) + "frontHeat" + lexical_cast<string > (scene_num) + ".png").data(), heatMapFront[oclass], maxCost[oclass], minCost[oclass], numBins[2] - 1 - getBinIndex(maxS[oclass].getCentroid(), min, steps, 2), getBinIndex(maxS[oclass].getCentroid(), min, steps, 1));
01750         //cout << "optimal point" << maxS.centroid.x << "," << maxS.centroid.y << "," << maxS.centroid.z << " with cost:" << minCost << endl;
01751     }
01752     exit(1);
01753 
01754 
01755 }
01756 void lookForClassInOriginalFrameProjective(vector<int> & classes, pcl::PointCloud<pcl::PointXYZRGBCamSL> & cloud, vector<SpectralProfile> & spectralProfiles, map<int, int> & segIndex2label, const std::vector<pcl::PointCloud<PointT> > &segment_clouds, int scene_num, vector<pcl::PointXYZI> & maximas)
01757 {
01758     pcl::PointXYZ steps(0.01, 0.01, 0.01);
01759     std::vector< pcl::KdTreeFLANN<PointT>::Ptr > trees;
01760 
01761     maximas.resize(classes.size());
01762     createTrees(segment_clouds, trees);
01763     /* find bounding box and discretize
01764      */
01765     pcl::PointXYZ max;
01766     pcl::PointXYZ min;
01767     TransformG invTrans=globalTransform.inverse();
01768     pcl::PointCloud<pcl::PointXYZRGBCamSL>  cloudOriginal=cloud;
01769     invTrans.transformPointCloudInPlaceAndSetOrigin(cloudOriginal);
01770     
01771     for (int i = 0; i < 3; i++)
01772     {
01773         max.data[i] = FLT_MIN;
01774         min.data[i] = FLT_MAX;
01775     }
01776     for (size_t i = 0; i < cloud.size(); i++)
01777     {
01778         for (int j = 0; j < 3; j++)
01779         {
01780             if (max.data[j] < cloudOriginal.points[i].data[j])
01781                 max.data[j] = cloudOriginal.points[i].data[j];
01782 
01783             if (min.data[j] > cloudOriginal.points[i].data[j])
01784                 min.data[j] = cloudOriginal.points[i].data[j];
01785         }
01786     }
01787     
01788     saveOriginalImages(cloudOriginal, max, min, steps, scene_num);
01789     int numBins[3];
01790     for (int i = 0; i < 3; i++)
01791     {
01792         numBins[i] = (int) ((max.data[i] - min.data[i]) / steps.data[i]) + 1;
01793     }
01794 
01795     Matrix<float, Dynamic, 1 > nodeFeatsB(nodeFeatIndices.size()*10);
01796     Matrix<float, Dynamic, 1 > edgeFeatsB(edgeFeatIndices.size()*10);
01797     vector<float> nodeFeats(nodeFeatIndices.size(), 0.0);
01798     vector<float> edgeFeats(edgeFeatIndices.size(), 0.0);
01799     cout << "max:" << max << endl;
01800     cout << "min:" << min << endl;
01801     double maxDist[360];
01802     getMaxRanges(maxDist, cloud);
01803     double cost;
01804     double maxCost[classes.size()];
01805     double minCost[classes.size()];
01806     SpectralProfile maxS[classes.size()];
01807     Matrix<float, Dynamic, Dynamic> heatMapTop[classes.size()];
01808     //Matrix<float, Dynamic, Dynamic> heatMapFront[classes.size()];
01809 
01810     int imageWidth=640;
01811     int imageHeight=480;
01812     for (int oclass = 0; oclass < classes.size(); oclass++)
01813     {
01814         minCost[oclass] = DBL_MAX;
01815         maxCost[oclass] = -DBL_MAX;
01816         heatMapTop[oclass].setConstant(imageHeight, imageWidth, -FLT_MAX);
01817        // heatMapFront[oclass].setConstant(numBins[2], numBins[1], -FLT_MAX);
01818     }
01819 
01820     int countx = 0;
01821     int county = 0;
01822     int countz = 0;
01823     int k;
01824     float x;
01825     float y;
01826     float z;
01827                     int imageX;
01828                     int imageY;
01829     for (x = min.x, countx = 0; x < max.x; countx++, x += steps.x)
01830         for (y = min.y, county = 0; y < max.y; county++, y += steps.y)
01831             for (z = min.z, countz = 0; z < max.z; countz++, z += steps.z)
01832             {
01833                 vector<int> neighbors;
01834                     SpectralProfile target;
01835                     target.centroid.x = x;
01836                     target.centroid.y = y;
01837                     target.centroid.z = z;
01838                     
01839                     target.transformCentroid(globalTransform);
01840                     
01841                 PointT centroid=target.getCentroidSL();
01842                 double dist = getWallDistanceCent(maxDist, centroid);
01843                 
01844                     nodeFeats.at(0) = target.centroid.z;
01845                     nodeFeats.at(1) = dist;
01846                     
01847                 if (dist < 0)
01848                     continue;
01849                 findNeighbors(centroid, segment_clouds, trees, neighbors);
01850                 
01851                 for (int oclass = 0; oclass < classes.size(); oclass++)
01852                 {
01853                     k = classes[oclass];
01854                     cost = 0.0;
01855                     //compute feats
01856                     //                nodeFeats.at(1)=0;//dummy for now
01857 
01858 
01859                     for (size_t i = 0; i < nodeFeatIndices.size(); i++)
01860                     {
01861                         nodeFeatStumps[nodeFeatIndices.at(i)].storeBinnedValues(nodeFeats[i], nodeFeatsB, i);
01862                     }
01863 
01864                     cost += nodeFeatsB.dot(nodeWeights->row(k));
01865 
01866                     for (size_t i = 0; i < neighbors.size(); i++)
01867                     {
01868                         int nbrIndex = neighbors.at(i);
01869                         int nbrLabel = segIndex2label[nbrIndex] - 1;
01870                         
01871                         if(nbrLabel<0) // this neighbor was not labeled by the classifier(probably it is using sum<1)
01872                             continue;
01873                         
01874                         //cerr << nbrIndex<<","<<nbrLabel << ",nl - k," << k << endl;
01875                         //assert(nbrLabel != k);
01876                         edgeFeats.at(0) = target.getHorzDistanceBwCentroids(spectralProfiles.at(nbrIndex));
01877                         edgeFeats.at(1) = target.getVertDispCentroids(spectralProfiles.at(nbrIndex));
01878                         edgeFeats.at(2) = target.getDistanceSqrBwCentroids(spectralProfiles.at(nbrIndex));
01879                         edgeFeats.at(3) = target.getInnerness(spectralProfiles.at(nbrIndex));
01880                         //  cout<<"edge feats "<<edgeFeats[0]<<","<<edgeFeats[1]<<","<<edgeFeats[2]<<endl;
01881 
01882                         for (size_t j = 0; j < edgeFeatIndices.size(); j++)
01883                         {
01884                             edgeFeatStumps[edgeFeatIndices.at(j)].storeBinnedValues(edgeFeats[j], edgeFeatsB, j);
01885                         }
01886                         cost += edgeFeatsB.dot(edgeWeights[k]->row(nbrLabel));
01887 
01888                         edgeFeats.at(0) = spectralProfiles.at(nbrIndex).getHorzDistanceBwCentroids(target);
01889                         edgeFeats.at(1) = spectralProfiles.at(nbrIndex).getVertDispCentroids(target);
01890                         edgeFeats.at(2) = spectralProfiles.at(nbrIndex).getDistanceSqrBwCentroids(target);
01891                         edgeFeats.at(3) = spectralProfiles.at(nbrIndex).getInnerness(target);
01892 
01893                         for (size_t j = 0; j < edgeFeatIndices.size(); j++)
01894                         {
01895                             edgeFeatStumps[edgeFeatIndices.at(j)].storeBinnedValues(edgeFeats[j], edgeFeatsB, j);
01896                         }
01897 
01898                         assert(nbrLabel >= 0);
01899                         assert(nbrLabel < NUM_CLASSES);
01900                         assert(k >= 0);
01901                         assert(k < NUM_CLASSES);
01902                         cost += edgeFeatsB.dot(edgeWeights[nbrLabel]->row(k));
01903                     }
01904 
01905                     //     cout<<x<<","<<y<<","<<z<<","<<dist<<","<<cost<<endl;
01906                     if (maxCost[oclass] < cost)
01907                     {
01908                         maxCost[oclass] = cost;
01909                         maxS[oclass].setCentroid( target);
01910                       //  maximas[oclass].x = x;
01911                       //  maximas[oclass].y = y;
01912                       //  maximas[oclass].z = z;
01913                       //  maximas[oclass].intensity = cost;
01914                       //  cout<<"nodeFeats \n"<<nodeFeatsB<<endl;                    
01915                     } 
01916                     else if(maxCost[oclass] == cost)
01917                     {
01918                         maxS[oclass].addCentroid(target);                        
01919                     }
01920 
01921                     if (minCost[oclass] > cost)
01922                     {
01923                         minCost[oclass] = cost;
01924                     }
01925                     
01926                         imageX=(640*x/z/1.1147 + 640*0.5)/2.0  ;
01927                         imageY=(480*0.5 -460*y/z/0.8336)/2.0  ; 
01928                         
01929                         assert(imageX>=0);
01930                         assert(imageY>=0);
01931                         assert(imageX<imageWidth);
01932                         assert(imageY>imageHeight);
01933 
01934                     if (heatMapTop[oclass](imageY, imageX) < cost)
01935                     {
01936                         heatMapTop[oclass](imageY, imageX) = cost;
01937                     }
01938 
01939                 }
01940 
01941                 // all feats can be computed using SpectralProfile
01942                 // wall distance will take time
01943                 //use octomap to filter out occluded regions
01944 
01945             }
01946 
01947     for (size_t oclass = 0; oclass < classes.size(); oclass++)
01948     {
01949         //   replace<float>(heatMapTop[oclass], -FLT_MAX, minCost);
01950         //    replace<float>(heatMapFront[oclass], -FLT_MAX, minCost);
01951         maxS[oclass].setAvgCentroid();
01952         maxS[oclass].transformCentroid(invTrans); // come back to original
01953                         imageX=(640*maxS[oclass].centroid.x/maxS[oclass].centroid.z/1.1147 + 640*0.5)/2.0  ;
01954                         imageY=(480*0.5 -460*maxS[oclass].centroid.y/maxS[oclass].centroid.z/0.8336)/2.0  ; 
01955         
01956         maximas[oclass].x = maxS[oclass].centroid.x;
01957         maximas[oclass].y = maxS[oclass].centroid.y;
01958         maximas[oclass].z = maxS[oclass].centroid.z;
01959         maximas[oclass].intensity = maxCost[oclass];
01960         
01961         writeHeatMap<float>((lexical_cast<string > (classes[oclass]) + "_topHeat" + lexical_cast<string > (scene_num) + ".png").data(), heatMapTop[oclass], maxCost[oclass], minCost[oclass],imageY, imageX);
01962       //  writeHeatMap<float>((lexical_cast<string > (classes[oclass]) + "frontHeat" + lexical_cast<string > (scene_num) + ".png").data(), heatMapFront[oclass], maxCost[oclass], minCost[oclass], numBins[2] - 1 - getBinIndex(maxS[oclass].getCentroid(), min, steps, 2), getBinIndex(maxS[oclass].getCentroid(), min, steps, 1));
01963         //cout << "optimal point" << maxS.centroid.x << "," << maxS.centroid.y << "," << maxS.centroid.z << " with cost:" << minCost << endl;
01964     }
01965     exit(1);
01966 
01967 
01968 }
01969 void lookForClass(vector<int> & classes, pcl::PointCloud<pcl::PointXYZRGBCamSL> & cloud, vector<SpectralProfile> & spectralProfiles, map<int, int> & segIndex2label, const std::vector<pcl::PointCloud<PointT> > &segment_clouds, int scene_num, vector<pcl::PointXYZI> & maximas)
01970 {
01971     pcl::PointXYZ steps(0.005, 0.005, 0.005);
01972     std::vector< pcl::KdTreeFLANN<PointT>::Ptr > trees;
01973 
01974     maximas.resize(classes.size());
01975     createTrees(segment_clouds, trees);
01976     /* find bounding box and discretize
01977      */
01978     pcl::PointXYZ max;
01979     pcl::PointXYZ min;
01980     for (int i = 0; i < 3; i++)
01981     {
01982         max.data[i] = FLT_MIN;
01983         min.data[i] = FLT_MAX;
01984     }
01985     for (size_t i = 0; i < cloud.size(); i++)
01986     {
01987         for (int j = 0; j < 3; j++)
01988         {
01989             if (max.data[j] < cloud.points[i].data[j])
01990                 max.data[j] = cloud.points[i].data[j];
01991 
01992             if (min.data[j] > cloud.points[i].data[j])
01993                 min.data[j] = cloud.points[i].data[j];
01994         }
01995     }
01996     saveOriginalImages(cloud, max, min, steps, scene_num);
01997     int numBins[3];
01998     for (int i = 0; i < 3; i++)
01999     {
02000         numBins[i] = (int) ((max.data[i] - min.data[i]) / steps.data[i]) + 1;
02001     }
02002 
02003     Matrix<float, Dynamic, 1 > nodeFeatsB(nodeFeatIndices.size()*10);
02004     Matrix<float, Dynamic, 1 > edgeFeatsB(edgeFeatIndices.size()*10);
02005     vector<float> nodeFeats(nodeFeatIndices.size(), 0.0);
02006     vector<float> edgeFeats(edgeFeatIndices.size(), 0.0);
02007     cout << "max:" << max << endl;
02008     cout << "min:" << min << endl;
02009     double maxDist[360];
02010     getMaxRanges(maxDist, cloud);
02011     double cost;
02012     double maxCost[classes.size()];
02013     double minCost[classes.size()];
02014     SpectralProfile maxS[classes.size()];
02015     Matrix<float, Dynamic, Dynamic> heatMapTop[classes.size()];
02016     Matrix<float, Dynamic, Dynamic> heatMapFront[classes.size()];
02017 
02018     for (int oclass = 0; oclass < classes.size(); oclass++)
02019     {
02020         minCost[oclass] = DBL_MAX;
02021         maxCost[oclass] = -DBL_MAX;
02022         heatMapTop[oclass].setConstant(numBins[1], numBins[0], -FLT_MAX);
02023         heatMapFront[oclass].setConstant(numBins[2], numBins[1], -FLT_MAX);
02024     }
02025 
02026 
02027 
02028 
02029     int countx = 0;
02030     int county = 0;
02031     int countz = 0;
02032     int k;
02033     float x;
02034     float y;
02035     float z;
02036     for (x = min.x, countx = 0; x < max.x; countx++, x += steps.x)
02037         for (y = min.y, county = 0; y < max.y; county++, y += steps.y)
02038             for (z = min.z, countz = 0; z < max.z; countz++, z += steps.z)
02039             {
02040                 vector<int> neighbors;
02041                 PointT centroid;
02042                 centroid.x = x;
02043                 centroid.y = y;
02044                 centroid.z = z;
02045                 double dist = getWallDistanceCent(maxDist, centroid);
02046                 if (dist < 0)
02047                     continue;
02048                 findNeighbors(centroid, segment_clouds, trees, neighbors);
02049                 
02050                 for (int oclass = 0; oclass < classes.size(); oclass++)
02051                 {
02052                     k = classes[oclass];
02053                     cost = 0.0;
02054                     //compute feats
02055                     nodeFeats.at(0) = z;
02056                     nodeFeats.at(1) = dist;
02057                     //                nodeFeats.at(1)=0;//dummy for now
02058 
02059                     SpectralProfile target;
02060                     target.centroid.x = x;
02061                     target.centroid.y = y;
02062                     target.centroid.z = z;
02063 
02064                     for (size_t i = 0; i < nodeFeatIndices.size(); i++)
02065                     {
02066                         nodeFeatStumps[nodeFeatIndices.at(i)].storeBinnedValues(nodeFeats[i], nodeFeatsB, i);
02067                     }
02068 
02069                     cost += nodeFeatsB.dot(nodeWeights->row(k));
02070 
02071                     for (size_t i = 0; i < neighbors.size(); i++)
02072                     {
02073                         int nbrIndex = neighbors.at(i);
02074                         int nbrLabel = segIndex2label[nbrIndex] - 1;
02075                         
02076                         if(nbrLabel<0) // this neighbor was not labeled by the classifier(probably it is using sum<1)
02077                             continue;
02078                         
02079                         //cerr << nbrIndex<<","<<nbrLabel << ",nl - k," << k << endl;
02080                         //assert(nbrLabel != k);
02081                         edgeFeats.at(0) = target.getHorzDistanceBwCentroids(spectralProfiles.at(nbrIndex));
02082                         edgeFeats.at(1) = target.getVertDispCentroids(spectralProfiles.at(nbrIndex));
02083                         edgeFeats.at(2) = target.getDistanceSqrBwCentroids(spectralProfiles.at(nbrIndex));
02084                         edgeFeats.at(3) = target.getInnerness(spectralProfiles.at(nbrIndex));
02085                         //  cout<<"edge feats "<<edgeFeats[0]<<","<<edgeFeats[1]<<","<<edgeFeats[2]<<endl;
02086 
02087                         for (size_t j = 0; j < edgeFeatIndices.size(); j++)
02088                         {
02089                             edgeFeatStumps[edgeFeatIndices.at(j)].storeBinnedValues(edgeFeats[j], edgeFeatsB, j);
02090                         }
02091                         cost += edgeFeatsB.dot(edgeWeights[k]->row(nbrLabel));
02092 
02093                         edgeFeats.at(0) = spectralProfiles.at(nbrIndex).getHorzDistanceBwCentroids(target);
02094                         edgeFeats.at(1) = spectralProfiles.at(nbrIndex).getVertDispCentroids(target);
02095                         edgeFeats.at(2) = spectralProfiles.at(nbrIndex).getDistanceSqrBwCentroids(target);
02096                         edgeFeats.at(3) = spectralProfiles.at(nbrIndex).getInnerness(target);
02097 
02098                         for (size_t j = 0; j < edgeFeatIndices.size(); j++)
02099                         {
02100                             edgeFeatStumps[edgeFeatIndices.at(j)].storeBinnedValues(edgeFeats[j], edgeFeatsB, j);
02101                         }
02102 
02103                         assert(nbrLabel >= 0);
02104                         assert(nbrLabel < NUM_CLASSES);
02105                         assert(k >= 0);
02106                         assert(k < NUM_CLASSES);
02107                         cost += edgeFeatsB.dot(edgeWeights[nbrLabel]->row(k));
02108                     }
02109 
02110                     //     cout<<x<<","<<y<<","<<z<<","<<dist<<","<<cost<<endl;
02111                     if (maxCost[oclass] < cost)
02112                     {
02113                         maxCost[oclass] = cost;
02114                         maxS[oclass].setCentroid( target);
02115                       //  maximas[oclass].x = x;
02116                       //  maximas[oclass].y = y;
02117                       //  maximas[oclass].z = z;
02118                       //  maximas[oclass].intensity = cost;
02119                         //   cout<<"nodeFeats \n"<<nodeFeatsB<<endl;                    
02120                     } 
02121                     else if(maxCost[oclass] == cost)
02122                     {
02123                         maxS[oclass].addCentroid(target);                        
02124                     }
02125 
02126                     if (minCost[oclass] > cost)
02127                     {
02128                         minCost[oclass] = cost;
02129                     }
02130 
02131                     if (heatMapTop[oclass](numBins[1] - 1 - county, countx) < cost)
02132                     {
02133                         heatMapTop[oclass](numBins[1] - 1 - county, countx) = cost;
02134                     }
02135 
02136                     if (heatMapFront[oclass](numBins[2] - 1 - countz, county) < cost)
02137                     {
02138                         heatMapFront[oclass](numBins[2] - 1 - countz, county) = cost;
02139                     }
02140                 }
02141 
02142                 // all feats can be computed using SpectralProfile
02143                 // wall distance will take time
02144                 //use octomap to filter out occluded regions
02145 
02146             }
02147 
02148     for (size_t oclass = 0; oclass < classes.size(); oclass++)
02149     {
02150         //   replace<float>(heatMapTop[oclass], -FLT_MAX, minCost);
02151         //    replace<float>(heatMapFront[oclass], -FLT_MAX, minCost);
02152         maxS[oclass].setAvgCentroid();
02153         
02154         maximas[oclass].x = maxS[oclass].centroid.x;
02155         maximas[oclass].y = maxS[oclass].centroid.y;
02156         maximas[oclass].z = maxS[oclass].centroid.z;
02157         maximas[oclass].intensity = maxCost[oclass];
02158         
02159         writeHeatMap<float>((lexical_cast<string > (classes[oclass]) + "_topHeat" + lexical_cast<string > (scene_num) + ".png").data(), heatMapTop[oclass], maxCost[oclass], minCost[oclass], numBins[1] - 1 - getBinIndex(maxS[oclass].getCentroid(), min, steps, 1), getBinIndex(maxS[oclass].getCentroid(), min, steps, 0));
02160         writeHeatMap<float>((lexical_cast<string > (classes[oclass]) + "frontHeat" + lexical_cast<string > (scene_num) + ".png").data(), heatMapFront[oclass], maxCost[oclass], minCost[oclass], numBins[2] - 1 - getBinIndex(maxS[oclass].getCentroid(), min, steps, 2), getBinIndex(maxS[oclass].getCentroid(), min, steps, 1));
02161         //cout << "optimal point" << maxS.centroid.x << "," << maxS.centroid.y << "," << maxS.centroid.z << " with cost:" << minCost << endl;
02162     }
02163 
02164 
02165 
02166 }
02167 int counts[640 * 480];
02168 int write_feats(TransformG transG, pcl::PointCloud<pcl::PointXYZRGBCamSL>::Ptr & cloud_ptr, int scene_num) {
02169     std::ofstream featfile;
02170     pcl::PointCloud<pcl::PointXYZRGBCamSL> & cloud = *cloud_ptr;
02171     originalFrame = new OriginalFrameInfo(cloud_ptr);
02172 
02173     //labelfile.open("data_labels.txt",ios::app);
02174     string featfilename = "data_scene_labelling_full_" + lexical_cast<string > (scene_num);
02175     featfile.open(featfilename.data());
02176 
02177     // read the pcd file
02178 
02179 
02180     // convert to templated message type
02181 
02182     originalFrame->setCameraTrans(transG);
02183 
02184 
02185 
02186     OcTreeROS tree(0.01);
02187     if (UseVolFeats) {
02188         OcTreeROS::NodeType* treeNode;
02189         buildOctoMap(cloud, tree);
02190     }
02191 
02192 
02193 
02194     pcl::PointCloud<PointT>::Ptr cloud_filtered(new pcl::PointCloud<PointT > ());
02195     pcl::PointCloud<PointT>::Ptr cloud_seg(new pcl::PointCloud<PointT > ());
02196     //pcl::PointCloud<PointXYZI>::Ptr cloud_seg (new pcl::PointCloud<PointXYZI> ());
02197     std::vector<pcl::PointCloud<PointT> > segment_clouds;
02198     std::map<int, int> segment_num_index_map;
02199     pcl::PointIndices::Ptr segment_indices(new pcl::PointIndices());
02200 
02201     // get segments
02202 
02203     // find the max segment number
02204 
02205     int max_segment_num = 0;
02206     for (size_t i = 0; i < cloud.points.size(); ++i) {
02207         counts[cloud.points[i].segment]++;
02208         if (max_segment_num < cloud.points[i].segment) {
02209             max_segment_num = (int) cloud.points[i].segment;
02210         }
02211     }
02212 
02213     ExtractIndices<PointT> extract;
02214 
02215     int index_ = 0;
02216     vector<SpectralProfile> spectralProfiles;
02217     std::cerr << "max_seg num:" << max_segment_num << "," << cloud.points.size() << endl;
02218     for (int seg = 1; seg <= max_segment_num; seg++) {
02219          if(counts[seg]<=MIN_SEG_SIZE)
02220            continue;
02221         //vector<float> features;
02222         //int label;
02223         //segment_indices->indices.clear();
02224         //int sizec = 0;
02225         //for (size_t i = 0; i < cloud.points.size(); ++i) {
02226         //assert(cloud.points[i].z>=0);
02227         //  if (cloud.points[i].segment == seg) {
02228         //    sizec++;
02229         //  segment_indices->indices.push_back(i);
02230         // label = cloud.points[i].label;
02231         // }
02232         // }
02233         // if(label!=0) cout << "segment: "<< seg << " label: " << label  << " size: " << sizec << endl;
02234         //extract.setInputCloud(cloud_ptr);
02235         //extract.setIndices(segment_indices);
02236         //extract.setNegative(false);
02237         //extract.filter(*cloud_seg);
02238         SpectralProfile temp;
02239         apply_segment_filter_and_compute_HOG(*cloud_ptr, *cloud_seg, seg, temp);
02240 
02241         //if (label!=0) cout << "segment: "<< seg << " label: " << label << " size: " << cloud_seg->points.size() << endl;
02242         if (!cloud_seg->points.empty() && cloud_seg->points.size() > MIN_SEG_SIZE) {
02243             //std::cout << seg << ". Cloud size after extracting : " << cloud_seg->points.size() << std::endl;
02244             segment_clouds.push_back(*cloud_seg);
02245             pcl::PointCloud<PointT>::Ptr tempPtr(new pcl::PointCloud<PointT > (segment_clouds[segment_clouds.size() - 1]));
02246             temp.cloudPtr = tempPtr;
02247 
02248             spectralProfiles.push_back(temp);
02249             segment_num_index_map[cloud_seg->points[1].segment] = index_;
02250             index_++;
02251         }
02252     }
02253     map< pair <int, int>, float > distance_matrix;
02254     map <int, vector <int> > neighbor_map;
02255     cerr << "computing neighbores" << endl;
02256     clock_t start_time = clock();
02257     int num_edges = get_neighbors(segment_clouds, distance_matrix, neighbor_map);
02258     clock_t elapsed = clock() - start_time;
02259     cerr << "computing neighbores" << elapsed / ((double) CLOCKS_PER_SEC) << endl;
02260 
02261     //    cerr<<"done adding wall distance features"<<endl;
02262 
02263 
02264     // for each segment compute node featuers
02265     int num_bin_shape = 3;
02266     map < int, vector<float> > features;
02267     bool isFirstFrame = addNodeHeader;
02268     for (size_t i = 0; i < segment_clouds.size(); i++) {
02269         //   vector<float> features;
02270         int seg_id = segment_clouds[i].points[1].segment;
02271         // get color features
02272         //cout << "computing color features" << std::endl;
02273         get_color_features(segment_clouds[i], features[seg_id], spectralProfiles[i]);
02274 
02275         // get shape features - now in global features
02276         //   get_shape_features(segment_clouds[i], features[seg_id], num_bin_shape);
02277 
02278         // get bounding box and centroid point features
02279         get_global_features(segment_clouds[i], features[seg_id], spectralProfiles[i]);
02280         addNodeHeader = false;
02281 
02282     }
02283     cerr << "adding wall distance features" << endl;
02284     start_time = clock();
02285     add_distance_features(cloud, features, segment_clouds);
02286     if (isFirstFrame) nodeFeatNames.push_back("distance_from_wall0");
02287     elapsed = clock() - start_time;
02288     cerr << "time for computing wall" << elapsed / ((double) CLOCKS_PER_SEC) << endl;
02289 
02290     cerr << "done adding wall distance features" << endl;
02291 
02292     //  vector<pcl::Normal> cloud_normals;
02293     // get_avg_normals(segment_clouds,cloud_normals);
02294     // print the node features
02295     //   assert(nodeFeatNames.size ()<100); // some error in setting flag can cause trouble
02296     //for(size_t i=0;i<nodeFeatNames.size ();i++)
02297     //featfile<<"#"<<nodeFeatNames[i]<<endl;
02298     int totatAssocFeats = NUM_ASSOCIATIVE_FEATS;
02299     if (BinFeatures)
02300         totatAssocFeats = NUM_ASSOCIATIVE_FEATS * BinStumps::NUM_BINS;
02301     featfile << segment_clouds.size() << " " << num_edges << " " << 17/*should not matter ... it is read from modelfile*/ << " " << totatAssocFeats << endl;
02302 
02303     for (map< int, vector<float> >::iterator it = features.begin(); it != features.end(); it++) {
02304         assert(nodeFeatNames.size() == (*it).second.size());
02305         //cerr << (*it).first << ":\t";
02306         featfile << segment_clouds[segment_num_index_map[(*it).first]].points[1].label << " " << (*it).first;
02307         int featIndex = 0;
02308         for (vector<float>::iterator it2 = (*it).second.begin(); it2 != (*it).second.end(); it2++) {
02309             if (BinFeatures) {
02310                 nodeFeatStumps[featIndex].writeBinnedValues(*it2, featfile, featIndex);
02311             } else {
02312                 featfile << " " << featIndex << ":" << *it2;
02313             }
02314             featIndex++;
02315         }
02316         //cerr << endl;
02317         featfile << "\n";
02318     }
02319     cerr << "\n";
02320     map < int, vector <float> > edge_features;
02321     // find pairwise features
02322     // assert(edgeFeatNames.size ()<100); // some error in setting flag can cause trouble
02323     //   efeatfile<<"#"<<NUM_ASSOCIATIVE_FEATS<<endl;
02324     int edgecount = 0;
02325     for (map< int, vector<int> >::iterator it = neighbor_map.begin(); it != neighbor_map.end(); it++) {
02326 
02327         edge_features.clear();
02328         get_pair_features((*it).first, (*it).second, distance_matrix, segment_num_index_map, spectralProfiles, edge_features, tree);
02329         edgecount++;
02330         //   if(edgecount==1)
02331         //   {
02332         //       for(size_t i=0;i<edgeFeatNames.size ();i++)
02333         //           featfile<<"#"<<edgeFeatNames[i]<<endl;
02334         //}
02335 
02336         // print pair-wise features
02337         for (map< int, vector<float> >::iterator it2 = edge_features.begin(); it2 != edge_features.end(); it2++) {
02338             //  cerr << "edge: ("<< (*it).first << "," << (*it2).first << "):\t";
02339             featfile << segment_clouds[segment_num_index_map[(*it).first]].points[1].label << " " << segment_clouds[segment_num_index_map[(*it2).first]].points[1].label << " " << (*it).first << " " << (*it2).first;
02340             assert(edgeFeatNames.size() == (*it2).second.size());
02341 
02342             int featIndex = 0;
02343             for (vector<float>::iterator it3 = (*it2).second.begin(); it3 != (*it2).second.end(); it3++) {
02344                 //    cerr << *it3 << "\t";
02345                 if (BinFeatures) {
02346                     edgeFeatStumps[featIndex].writeBinnedValues(*it3, featfile, featIndex);
02347                 } else {
02348                     featfile << " " << featIndex << ":" << *it3;
02349                 }
02350                 featIndex++;
02351 
02352                 //                efeatfile << "\t" <<*it3 ;
02353             }
02354             //cerr << endl;
02355             featfile << endl;
02356         }
02357 
02358     }
02359 
02360 
02361     //    cout << "DONE!!\n";
02362     // write features to file
02363     /*    for (vector<float>::iterator it = features.begin(); it < features.end(); it++) {
02364           outfile << *it << "\t";
02365         }
02366         outfile << "\n";
02367      */
02368     //labelfile.close();
02369     featfile.close();
02370     //    std::ofstream  featfile;
02371     featfile.open(("temp." + featfilename).data());
02372     featfile << featfilename;
02373     featfile.close();
02374     string command = "../svm-python-v204/svm_python_classify --m svmstruct_mrf --l micro --lm nonassoc --cm sumLE1.IP --omf ../svm-python-v204/" + environment + "_objectMap.txt temp." + featfilename + " ../svm-python-v204/" + environment + "Model pred." + featfilename + " > out." + featfilename;
02375     system(command.data());
02376 
02377     std::ifstream predLabels;
02378     predLabels.open(("pred." + featfilename).data()); // open the file containing predictions
02379     map<int, int> segIndex2Label;
02380     
02381 /*    vector<int> classes;
02382     classes.push_back(7);
02383     classes.push_back(13);
02384     vector<PointXYZI> maximas;
02385     lookForClass(classes, cloud, spectralProfiles, segIndex2Label, segment_clouds, scene_num, maximas);
02386  */ 
02387     cloudVector.push_back(cloud);
02388     spectralProfilesVector.push_back(spectralProfiles);
02389     segment_cloudsVector.push_back(segment_clouds);
02390     sceneNumVector.push_back(scene_num);
02391     parseAndApplyLabels(predLabels, cloud, segment_clouds, segIndex2Label);
02392     segIndex2LabelVector.push_back(segIndex2Label);
02393     predLabels.close();
02394     writer.write<pcl::PointXYZRGBCamSL > (featfilename + ".pcd", cloud, true);
02395     sensor_msgs::PointCloud2 cloudMsg;
02396     toROSMsg(cloud, cloudMsg);
02397     pub.publish(cloudMsg);
02398 
02399 
02400     //   efeatfile.close();
02401 
02402 
02403 
02404 }
02405 
02406 void readLabelList(const string & file) {
02407     string line;
02408     ifstream myfile(file.data());
02409 
02410     if (!myfile.is_open()) {
02411         cerr << "cound not find the file:" << file << " which stores the ranges for binning the features .. you should run this program from the folder scene_processing(do roscd scene_processing), or put the binning info files: binStumpsN.txt(for node features) and binStumpsE.txt(for edge features) in current folder and rerun ... exiting with assertion failure" << endl;
02412     }
02413     assert(myfile.is_open());
02414 
02415     while (myfile.good()) {
02416         getline(myfile, line);
02417         //        cout << line << endl;
02418         if (line.length() > 0) {
02419             char_separator<char> sep(",");
02420             tokenizer<char_separator<char> > tokens(line, sep);
02421             
02422 
02423             BOOST_FOREACH(string t, tokens) {
02424                 labelsToFind.push_back(lexical_cast<int>(t.data()));
02425                 labelsToFindBitset.set(lexical_cast<int>(t.data()));
02426             }
02427         }
02428 
02429     }
02430     myfile.close();
02431     //for ( vector<int>::iterator it=labelList.begin() ; it < labelList.end(); it++ )
02432     //  cout << " " << *it;
02433     //cout << endl;
02434 
02435 }
02436 int step = 1;
02437 void processPointCloud(const sensor_msgs::PointCloud2ConstPtr& point_cloud) {
02438 
02439     static int callback_counter_ = 0;
02440     callback_counter_++;
02441     ROS_INFO("Received frame from kinect");
02442     if (++callback_counter_ % step == 0) {
02443         ROS_INFO("accepted it");
02444 
02445         pcl::PointCloud<pcl::PointXYZRGB> cloud;
02446         pcl::PointCloud<pcl::PointXYZRGBCamSL>::Ptr cloud_seg_ptr(new pcl::PointCloud<pcl::PointXYZRGBCamSL > ());
02447         pcl::fromROSMsg(*point_cloud, cloud);
02448         convertType(cloud, *cloud_seg_ptr, VectorG(0,0,0), 0);
02449         assert(cloud_seg_ptr->size() == 640 * 480);
02450         segmentInPlace(*cloud_seg_ptr);
02451         globalTransform.transformPointCloudInPlaceAndSetOrigin(*cloud_seg_ptr);
02452         write_feats(globalTransform, cloud_seg_ptr, callback_counter_);
02453         sceneToAngleMap[callback_counter_] = currentAngle;
02454 
02455     } else
02456         ROS_INFO("rejected it");
02457     
02458 }
02459 
02460 void printLabelsToLookFor()
02461 {
02462   cout << "Labels to look for: " ;
02463   for (size_t i = 0; i < labelsToLookFor.size(); i++)
02464   {
02465      cout << labelsToLookFor.at(i) << ", ";
02466   }
02467   cout << "\n";
02468 }
02469 
02470 void printLabelsFound(int turnCount){
02471 
02472     labelsFoundFile << turnCount ; 
02473     // print out the list of labels found
02474     cout << "Labels Found:\n";
02475     for (boost::dynamic_bitset<>::size_type i = 0; i < labelsToFindBitset.size(); i++)
02476     {
02477         if(labelsToFindBitset.test(i) ){
02478             std::cout << i << ":" << labelsFound[i] << "," ;
02479             labelsFoundFile << "\t"<< i << ":" << labelsFound[i]    ;
02480         }
02481     }
02482     std::cout << std::endl;
02483     labelsFoundFile << endl;
02484 }
02485 
02486 void getMovement(bool lookFor){
02487     objCount = 0;
02488     labelsToLookFor.clear();
02489       // for all the classes not found run look for class in each of the predicted frames
02490     for(boost::dynamic_bitset<>::size_type k = 0; k < labelsFound.size(); k++){
02491         
02492         if(!labelsFound.test(k)){
02493                         labelsToLookFor.push_back(k);
02494         }
02495     }
02496     if (lookFor) {
02497         locations.clear();
02498         int cloudCount = 0;
02499         while (cloudVector.size() > 0) {
02500 
02501             vector<pcl::PointXYZI> frame_maximas;
02502             lookForClass(labelsToLookFor, cloudVector.at(0), spectralProfilesVector.at(0), segIndex2LabelVector.at(0), segment_cloudsVector.at(0), sceneNumVector.at(cloudCount), frame_maximas);
02503             locations.push_back(frame_maximas);
02504             // remove the point clouds in which maximas are found
02505             cloudVector.erase(cloudVector.begin());
02506             spectralProfilesVector.erase(spectralProfilesVector.begin());
02507             segIndex2LabelVector.erase(segIndex2LabelVector.begin());
02508             segment_cloudsVector.erase(segment_cloudsVector.begin());
02509 
02510             cloudCount++;
02511         }
02512 
02513         // find the maximum for each class and the corresponding frames     
02514 
02515 
02516         for (int lcount = 0; lcount < labelsToLookFor.size(); lcount++) {
02517 
02518             int label = labelsToLookFor.at(lcount);
02519             for (int i = 0; i < locations.size(); i++) {
02520                 if (locations.at(i).at(lcount).intensity > maximas.at(label).intensity) {
02521                     maximas.at(label).x = locations.at(i).at(lcount).x;
02522                     maximas.at(label).y = locations.at(i).at(lcount).y;
02523                     maximas.at(label).z = locations.at(i).at(lcount).z;
02524                     maximas.at(label).intensity = locations.at(i).at(lcount).intensity;
02525                     maximaFrames.at(label) = sceneNumVector.at(i);
02526                     maximaChanged.set(label, true);
02527                     cout << "Maxima for label: " << label << " changed to scene num: " << sceneNumVector.at(i) << endl;
02528                 }
02529             }
02530         }
02531         sceneNumVector.clear();
02532 
02533         // remove any classes already looked for and maxima location didnt change
02534         for (int lcount = 0; lcount < labelsToLookFor.size(); lcount++) {
02535             if (!maximaChanged.test(labelsToLookFor.at(lcount)) && labelsAlreadyLookedFor.test(labelsToLookFor.at(lcount))) {
02536                 labelsToLookFor.erase(labelsToLookFor.begin() + lcount);
02537                 lcount--;
02538             }
02539         }
02540     }
02541     maximaChanged.reset(); 
02542     rotations.clear();
02543     translations.clear(); 
02544     rotations.resize(labelsToLookFor.size(),0);
02545     translations.resize(labelsToLookFor.size(),0);
02546     
02547     for(int lcount =0; lcount< labelsToLookFor.size(); lcount++)
02548     {
02549         int label = labelsToLookFor.at(lcount);
02550         double angle =  sceneToAngleMap[maximaFrames.at(label)]; // this angle is wrt to the initial point
02551         double theta= (double)(atan(maximas.at(label).y/maximas.at(label).x)*180/PI);
02552         cout << "the angle within the frame is: " << theta << endl;
02553         angle = angle+theta;
02554         rotations.at(lcount) =  angle;
02555         
02556     }
02557     cout << "Rotations calculated:" << endl;
02558     // printing the labels to look for, frame numbers and rotation angles
02559     for(int lcount =0; lcount< labelsToLookFor.size(); lcount++)
02560     {
02561         cout << lcount << ". label: "  << labelsToLookFor.at(lcount) << " frame: " << maximaFrames.at(labelsToLookFor.at(lcount)) << " rotation: " << rotations[lcount] << endl;
02562     }
02563     
02564 }
02565 
02566 void robotMovementControl(const sensor_msgs::PointCloud2ConstPtr& point_cloud){
02567         double forwardDistance=0.5;
02568     if(all_done){ exit(0); }
02569     
02570     if(turnCount < MAX_TURNS && labelsFound.count() < NUM_CLASSES ) // if more labels are to be found and the turn count is less than the max
02571     {
02572         ROS_INFO("processing %d cloud.. \n",turnCount+1);
02573         processPointCloud (point_cloud);
02574          
02575         // turn robot and increase the count
02576         if(turnCount < MAX_TURNS-1){ 
02577         robot->turnLeft(40,2);
02578         currentAngle += 40;
02579         cout << "current Angle now is "  << currentAngle<< endl;
02580         }
02581         turnCount++;
02582         printLabelsFound(turnCount);
02583         // if all classes found then return
02584         if (labelsFound.count()== NUM_CLASSES) {
02585             all_done = true;
02586             return;
02587         }
02588         
02589         
02590         return;
02591     }
02592     // if all initial turns are done, and the there are some more labels to find
02593     if ( turnCount == MAX_TURNS && labelsFound.count() < NUM_CLASSES) {
02594         //look for the remaining labels and get the corresponding rotation and translation motions
02595        
02596         getMovement(true);
02597         printLabelsToLookFor();
02598      
02599         originalScan = false;
02600         // do not process the current cloud but move the robot to the correct position
02601         double angle = rotations[0] - currentAngle;
02602         robot->turnLeft(angle, 0);
02603         //robot->moveForward(1.0,2);
02604         currentAngle = rotations[0];
02605         cout << "current Angle now is "  << currentAngle<< endl;
02606         cout << "Looking for object " << labelsToLookFor.at(objCount)<< endl;
02607         labelsAlreadyLookedFor.set(labelsToLookFor.at(objCount),true);
02608         objCount++;
02609         //robot->moveForward(translations[0], 2);
02610         
02611         rotations.erase(rotations.begin());
02612         translations.erase(translations.begin());
02613         turnCount++;
02614         return;
02615     }
02616     
02617     if ( !translationState && labelsFound.count() < NUM_CLASSES   && objCount <= labelsToLookFor.size() ){
02618         ROS_INFO("processing %d cloud.. \n",turnCount+1);
02619         processPointCloud (point_cloud);
02620         printLabelsFound(turnCount);
02621         printLabelsToLookFor();
02622         cout << "foundAny : " << foundAny << " objCount: " << objCount << "size of labelsToLookFor: " << labelsToLookFor.size() << endl;
02623         // call get movement only if new labels are found 
02624         if(foundAny && objCount != labelsToLookFor.size() ){
02625                    cout << "calling getMovement  when found any "  <<  endl;
02626            getMovement(true);
02627            printLabelsToLookFor();
02628         }
02629         if(objCount == labelsToLookFor.size())
02630         {
02631             cout << "calling getMovement when objCount == labelsToLookFor.size()" << endl;
02632                     getMovement(false);
02633             printLabelsToLookFor();
02634             translationState = true;
02635             cout<< "switching to moving forward mode"<<endl;
02636         }
02637         
02638         // if there are still movements left, move the robot else all_done
02639         if(!rotations.empty()){
02640            double angle = rotations[0] - currentAngle;
02641         //robot->moveForward(-1.0,0);
02642            robot->turnLeft(angle,0);
02643 
02644            if(translationState ){
02645                robot->moveForward(forwardDistance,2);  
02646            }
02647            
02648         //robot->moveForward(1.0,2);
02649            currentAngle = rotations[0];
02650            cout << "current angle now is " << currentAngle << endl;
02651            cout << "Looking for object " << labelsToLookFor.at(objCount) << " at " << objCount << endl;
02652            labelsAlreadyLookedFor.set(labelsToLookFor.at(objCount),true);
02653            objCount++;
02654           // robot->moveForward(translations[0],2);
02655            rotations.erase(rotations.begin());
02656            translations.erase(translations.begin());
02657            turnCount++;
02658 
02659         }
02660         return;
02661                 
02662     }
02663     if (translationState && turnCount < MAX_TRYS && labelsFound.count() < NUM_CLASSES && objCount <= labelsToLookFor.size()){
02664         ROS_INFO("processing %d cloud.. \n",turnCount+1);
02665         processPointCloud (point_cloud);
02666         printLabelsToLookFor();
02667         // do not update the movement now
02668         //if(foundAny){
02669         //   getMovement();
02670         //}
02671 
02672         printLabelsFound(turnCount);
02673         // if there are still movements left, move the robot else all_done
02674         if(!rotations.empty()){
02675            double angle = rotations[0] - currentAngle;
02676         robot->moveForward(-forwardDistance,0);
02677            robot->turnLeft(angle,0);
02678         robot->moveForward(+forwardDistance,2);
02679            currentAngle = rotations[0];
02680            cout << "current angle now is " << currentAngle << endl;
02681            cout << "Looking for object " << labelsToLookFor.at(objCount)<< endl;
02682            labelsAlreadyLookedFor.set(labelsToLookFor.at(objCount),true);
02683            objCount++;
02684           // robot->moveForward(translations[0],2);
02685            rotations.erase(rotations.begin());
02686            translations.erase(translations.begin());
02687            turnCount++;
02688 
02689         }else{all_done = true;}
02690                 
02691     } else{ 
02692         all_done = true;
02693     }
02694     
02695     
02696 }
02697 
02698 void robotMovementControlSingleObject(const sensor_msgs::PointCloud2ConstPtr& point_cloud){
02699     double angle = 0;
02700     
02701     // first frame just pick a random direction and move to it
02702     if(turnCount== 0){
02703        srand ( time(NULL) );
02704 
02705         angle = rand() % SPAN - SPAN/2;
02706         robot->turnLeft(angle,2);
02707         currentAngle = angle;
02708         cout << "current Angle now is "  << currentAngle<< endl;
02709         turnCount ++;
02710         return;
02711     }
02712      // second frame onwards, 
02713     else if (turnCount < MAX_TRYS && labelsFound.count() < NUM_CLASSES){
02714         // process the cloud
02715         ROS_INFO("processing %d cloud.. \n",turnCount+1);
02716         processPointCloud (point_cloud);
02717         
02718         // look for the class
02719         getMovement(true);
02720         // if maxima changed the look-for/rotations list will be non-empty
02721         if(labelsToLookFor.size() != 0){
02722              printLabelsToLookFor();
02723              double angle = rotations[0] - currentAngle;
02724              robot->turnLeft(angle, 0);
02725              currentAngle = rotations[0];
02726              cout << "current Angle now is "  << currentAngle<< endl;
02727              cout << "Looking for object " << labelsToLookFor.at(objCount)<< endl;
02728              labelsAlreadyLookedFor.set(labelsToLookFor.at(objCount),true);
02729              objCount++;
02730              rotations.erase(rotations.begin());
02731              
02732 
02733         }else {// else pic a random angle and move
02734             angle = rand() % SPAN - SPAN/2;
02735             robot->turnLeft(angle-currentAngle,2);
02736             currentAngle = angle;
02737             cout << "current Angle now is "  << currentAngle<< endl;
02738         }  
02739         // increase the count
02740         turnCount++;
02741         return;
02742         
02743     }else {exit (0);}
02744     
02745       
02746 }
02747 
02748 void robotMovementControlRandom(const sensor_msgs::PointCloud2ConstPtr& point_cloud){
02749     double angle = 0;
02750     
02751     // first frame just pick a random direction and move to it
02752     if(turnCount== 0){
02753        srand ( time(NULL) );
02754 
02755         angle = rand() % SPAN - SPAN/2;
02756         robot->turnLeft(angle,2);
02757         currentAngle = angle;
02758         cout << "current Angle now is "  << currentAngle<< endl;
02759         turnCount ++;
02760         return;
02761     }
02762      // second frame onwards, 
02763     else if (turnCount < MAX_TRYS && labelsFound.count() < NUM_CLASSES){
02764         // process the cloud
02765         ROS_INFO("processing %d cloud.. \n",turnCount+1);
02766         processPointCloud (point_cloud);
02767         
02768             angle = rand() % SPAN - SPAN/2;
02769             robot->turnLeft(angle-currentAngle,2);
02770             currentAngle = angle;
02771             cout << "current Angle now is "  << currentAngle<< endl;
02772         turnCount++;
02773         return;
02774         
02775     }else {exit (0);}
02776     
02777       
02778 }
02779 
02780 Vector3d getCenter(pcl::PointCloud<PointT> & cloud)
02781 {
02782     Vector3d max;
02783     Vector3d min;
02784         for (size_t i = 0; i < cloud.size(); i++)
02785     {
02786         for (int j = 0; j < 3; j++)
02787         {
02788             if (max(j) < cloud.points[i].data[j])
02789                 max(j) = cloud.points[i].data[j];
02790 
02791             if (min(j) > cloud.points[i].data[j])
02792                 min(j) = cloud.points[i].data[j];
02793         }
02794     }
02795     return (max+min)/2;
02796 }
02797 
02798 void evaluate(string inp, string out, int oclass)
02799 {
02800         pcl::PointCloud<PointT> outc;
02801         pcl::io::loadPCDFile<PointT>(out, outc);
02802     std::vector<pcl::PointCloud<PointT> > segment_clouds;
02803         pcl::PointCloud<PointT> cloud;
02804         pcl::PointCloud<PointT>::Ptr cloud_seg(new pcl::PointCloud<PointT>());
02805         pcl::io::loadPCDFile<PointT>(inp, cloud);
02806     map<int, int> segIndex2Label;
02807     int max_segment_num;
02808     for (size_t i = 0; i < cloud.points.size(); i++) {
02809         counts[cloud.points[i].segment]++;
02810         if (max_segment_num < cloud.points[i].segment) {
02811             max_segment_num = (int) cloud.points[i].segment;
02812         }
02813     }
02814 
02815 
02816     int index_ = 0;
02817     vector<SpectralProfile> spectralProfiles;
02818     std::cerr << "max_seg num:" << max_segment_num << "," << cloud.points.size() << endl;
02819     for (int seg = 1; seg <= max_segment_num; seg++) {
02820          if(counts[seg]<=MIN_SEG_SIZE)
02821            continue;
02822         SpectralProfile temp;
02823         apply_segment_filter(cloud, *cloud_seg, seg, temp);
02824         getSpectralProfileCent(*cloud_seg,temp);
02825 
02826         //if (label!=0) cout << "segment: "<< seg << " label: " << label << " size: " << cloud_seg->points.size() << endl;
02827         if (!cloud_seg->points.empty() && cloud_seg->points.size() > MIN_SEG_SIZE) {
02828             segIndex2Label[index_]=labelMap[cloud_seg->points[1].label];
02829             //std::cout << seg << ". Cloud size after extracting : " << cloud_seg->points.size() << std::endl;
02830             segment_clouds.push_back(*cloud_seg);
02831             pcl::PointCloud<PointT>::Ptr tempPtr(new pcl::PointCloud<PointT > (segment_clouds[segment_clouds.size() - 1]));
02832             temp.cloudPtr = tempPtr;
02833 
02834             spectralProfiles.push_back(temp);
02835            // segment_num_index_map[cloud_seg->points[1].seugment] = index_;
02836             index_++;
02837         }
02838     }
02839     
02840     vector<int> classes;
02841     classes.push_back(oclass);
02842     vector<PointXYZI> maximas;
02843     lookForClass(classes, cloud, spectralProfiles, segIndex2Label, segment_clouds, 0, maximas);
02844     cout<<"heatMax"<<maximas.at(0)<<endl;
02845     
02846     Vector3d predL(maximas.at(0).x,maximas.at(0).y,maximas.at(0).z);
02847     Vector3d sump(0,0,0);
02848     //    Vector3d predL=getCenter(outc);
02849     int count=0;
02850     int targetLabel=invLabelMap[oclass+1];
02851     double minDist=DBL_MAX;
02852     cout<<"keyboard:"<<targetLabel<<endl;
02853     for (size_t i = 0; i < outc.points.size(); i++) {
02854         if(outc.points[i].label==targetLabel)
02855         {
02856                 Vector3d point(outc.points[i].x,outc.points[i].y,outc.points[i].z);
02857                 sump+=point;
02858                 count++;
02859                 double dist=(predL-point).norm();
02860                 if(minDist>dist)
02861                     minDist=dist;
02862         }
02863     }
02864     
02865     cout<<count<<" points had label keyboard"<<endl;
02866     Vector3d centroid=sump/count;
02867     cout<<"minDist"<<minDist<<endl;
02868     cout<<"centDist"<<(predL-centroid).norm()<<endl;
02869   
02870     
02871 }
02872 int main(int argc, char** argv) {
02873     readWeightVectors();
02874     ros::init(argc, argv, "hi");
02875     //  unsigned int step = 10;
02876     environment = "office";
02877     if (argc > 1) environment = argv[1];
02878     cout << "using evv= " << environment << endl;
02879     ros::NodeHandle n;
02880     robot = new MoveRobot(n);
02881 
02882 
02883     string labelsFoundFilename = environment+ "labels_found.txt";
02884     labelsFoundFile.open(labelsFoundFilename.data());
02885     // initialize the maximas
02886     for(size_t i = 0; i < maximas.size(); i++)
02887     {
02888         maximas.at(i).intensity = -FLT_MAX;
02889     }
02890     
02891 
02892     //Instantiate the kinect image listener
02893     if (BinFeatures) {
02894         readAllStumpValues();
02895     }
02896 
02897     readLabelList(environment + "_to_find.txt");
02898     labelsFound = labelsToFindBitset;
02899     labelsFound.flip();
02900     //for (boost::dynamic_bitset<>::size_type i = 0; i < labelsFound.size(); ++i)
02901       //  std::cout << labelsFound[i];
02902 
02903     readInvLabelMap(invLabelMap, "../svm-python-v204/" + environment + "_labelmap.txt");
02904     globalTransform = readTranform("globalTransform.bag");
02905     pub = n.advertise<sensor_msgs::PointCloud2 > ("/scene_labler/labeled_cloud", 10);
02906     //    std_msgs::String str;
02907     //    str.data = "hello world";
02908     ros::Subscriber cloud_sub_ = n.subscribe("/camera/rgb/points", 1, processPointCloud);
02909 
02910     ros::spin();
02911   
02912 
02913 }
02914 
02915 


depth_tracker_ros_vr8
Author(s): shusain
autogenerated on Fri Dec 6 2013 20:45:47