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
00014 #include <opencv/cv.h>
00015 #include <opencv/highgui.h>
00016 #include "moveRobot.h"
00017
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
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;
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
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
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++;
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)
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
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))
00225 {
00226 return 1;
00227 }
00228
00229 return 0;
00230 }
00231
00232 };
00233
00234 MoveRobot * robot;
00235 #define MAX_TURNS 2
00236 #define MAX_TRYS 20
00237 int turnCount = 0;
00238 vector<int> labelsToFind;
00239 boost::dynamic_bitset<> labelsFound(NUM_CLASSES);
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
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>);
00316
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
00332
00333 tree->nearestKSearch(centroid, 2, nn_indices, nn_distances);
00334
00335 for (size_t j = 0; j < nn_indices.size(); ++j)
00336 {
00337 if (min_distance > nn_distances[j]) {
00338 min_distance = nn_distances[j];
00339 min_index = nn_indices[j];
00340
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
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
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
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
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
00403
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
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
00426
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;
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;
00493
00494 assert(RGBDSlamFrame->size() == size.width * size.height);
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
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
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
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
00638
00639 if (addNodeHeader) {
00640 for (size_t i = 0; i < numTimes; i++) {
00641
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
00648
00649 if (addEdgeHeader) {
00650 for (size_t i = 0; i < numTimes; i++) {
00651
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
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
00671 VectorG cam_coordinates = originalFrame->getCameraTrans().getOrigin();
00672 pcl::PointXYZ origin(cam_coordinates.v[0], cam_coordinates.v[1], cam_coordinates.v[2]);
00673
00674 tree.insertScan(xyzcloud, origin, -1, true);
00675 }
00676 void apply_segment_filter(pcl::PointCloud<PointT> &incloud, pcl::PointCloud<PointT> &outcloud, int segment) {
00677
00678
00679 outcloud.points.erase(outcloud.points.begin(), outcloud.points.end());
00680
00681 outcloud.header.frame_id = incloud.header.frame_id;
00682
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
00700 }
00701 }
00702
00703
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
00712
00713 outcloud.points.erase(outcloud.points.begin(), outcloud.points.end());
00714
00715 outcloud.header.frame_id = incloud.header.frame_id;
00716
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
00737 indices.push_back(i);
00738
00739
00740 }
00741 }
00742
00743
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
00755
00756 outcloud.points.erase(outcloud.points.begin(), outcloud.points.end());
00757
00758 outcloud.header.frame_id = incloud.header.frame_id;
00759
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
00780 indices.push_back(i);
00781
00782
00783 }
00784 }
00785
00786
00787 if (j >= MIN_SEG_SIZE) {
00788 outcloud.points.resize(j + 1);
00789
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
00798
00799 outcloud.points.erase(outcloud.points.begin(), outcloud.points.end());
00800
00801 outcloud.header.frame_id = incloud.header.frame_id;
00802
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
00820 }
00821 }
00822
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
00828
00829 outcloud.points.erase(outcloud.points.begin(), outcloud.points.end());
00830
00831 outcloud.header.frame_id = incloud.header.frame_id;
00832
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
00850 }
00851 }
00852
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
00866 }
00867
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>);
00889
00890 tree->setInputCloud(big_cloud);
00891 std::vector<int> nn_indices;
00892 nn_indices.resize(2);
00893 std::vector<float> nn_distances;
00894 nn_distances.resize(2);
00895
00896
00897 for (size_t i = 0; i < small_cloud->points.size(); ++i) {
00898
00899
00900 tree->nearestKSearch(small_cloud->points[i], 2, nn_indices, nn_distances);
00901
00902 for (size_t j = 0; j < nn_indices.size(); ++j)
00903 {
00904
00905
00906
00907
00908
00909 if (min_distance > nn_distances[j]) {
00910 min_distance = nn_distances[j];
00911 min_index = nn_indices[j];
00912
00913
00914 }
00915 }
00916 }
00917
00918
00919
00920
00921
00922
00923
00924
00925
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
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
00949 }
00950
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
00958 }
00959
00960
00961
00962
00963
00964
00965
00966
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
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
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
00989 map<int, int> segments;
00990 for (size_t i = 0; i < cloud_cam->points.size(); ++i) {
00991
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
01005
01006 }
01007
01008 }
01009
01010
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 ¢roid) {
01043 centroid[0] = 0;
01044 centroid[1] = 0;
01045 centroid[2] = 0;
01046 for (size_t i = 0; i < cloud.points.size(); ++i) {
01047
01048 centroid[0] += cloud.points[i].x;
01049 centroid[1] += cloud.points[i].y;
01050 centroid[2] += cloud.points[i].z;
01051
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
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
01085 if (minEigV > eigen_values(i)) {
01086 minEigV = eigen_values(i);
01087
01088 spectralProfile.normal = eigen_vectors.col(i);
01089
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
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);
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
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
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
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
01143 vector<vector<float> >::iterator it = descriptor_results.begin();
01144 int numFeats = it->size();
01145 result.resize(numFeats);
01146
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++) {
01153 vector<BinningInfo>::iterator binningInfo = binningInfos.begin();
01154
01155 vector<vector<float> >::iterator ires = result.begin();
01156
01157 assert(numFeats == it_point->size());
01158
01159 for (vector<float>::iterator it_feature = it_point->begin(); it_feature < it_point->end(); it_feature++, binningInfo++, ires++) {
01160
01161 int bin = binningInfo->getBinIndex(*it_feature);
01162
01163
01164
01165 (*ires)[bin] += 1;
01166 }
01167 }
01168
01169
01170
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
01178 for (vector<float>::iterator i2 = i->begin(); i2 < i->end(); i2++) {
01179 c2++;
01180 *i2 = *i2 / numPoints;
01181 assert(*i2 <= 1.0);
01182
01183 }
01184
01185 }
01186
01187
01188 }
01189
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
01194 for (vector<float>::iterator it2 = it->begin(); it2 < it->end(); it2++) {
01195 features.push_back(*it2);
01196 }
01197 }
01198 }
01199
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
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
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
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
01311 } else {
01312 unknownCount++;
01313
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
01326 } else {
01327 unknownCount++;
01328
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
01358
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
01378
01379
01380 edge_features[seg2_id].push_back(segment1Spectral.getHorzDistanceBwCentroids(segment2Spectral));
01381 addToEdgeHeader("centroid_horz_diff");
01382
01383 edge_features[seg2_id].push_back(segment1Spectral.getVertDispCentroids(segment2Spectral));
01384 addToEdgeHeader("centroid_z_diff");
01385
01386
01387
01388 edge_features[seg2_id].push_back(distance_matrix[make_pair(segment_id, seg2_id)]);
01389 addToEdgeHeader("dist_closest");
01390
01391
01392 edge_features[seg2_id].push_back(segment1Spectral.getAngleDiffInRadians(segment2Spectral));
01393 addToEdgeHeader("AngleDiff");
01394
01395
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
01404 if (UseVolFeats) {
01405 edge_features[seg2_id].push_back(get_occupancy_feature(*(segment1Spectral.cloudPtr), *(segment2Spectral.cloudPtr), tree));
01406 addToEdgeHeader("Occupancy");
01407 }
01408
01409
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
01488 if (indexMatrix[ybin][xbin] != -1) {
01489
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
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
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
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
01649
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)
01665 continue;
01666
01667
01668
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
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
01699 if (maxCost[oclass] < cost)
01700 {
01701 maxCost[oclass] = cost;
01702 maxS[oclass].setCentroid( target);
01703
01704
01705
01706
01707
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
01731
01732
01733
01734 }
01735
01736 for (size_t oclass = 0; oclass < classes.size(); oclass++)
01737 {
01738
01739
01740 maxS[oclass].setAvgCentroid();
01741 maxS[oclass].transformCentroid(invTrans);
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
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
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
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
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
01856
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)
01872 continue;
01873
01874
01875
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
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
01906 if (maxCost[oclass] < cost)
01907 {
01908 maxCost[oclass] = cost;
01909 maxS[oclass].setCentroid( target);
01910
01911
01912
01913
01914
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
01942
01943
01944
01945 }
01946
01947 for (size_t oclass = 0; oclass < classes.size(); oclass++)
01948 {
01949
01950
01951 maxS[oclass].setAvgCentroid();
01952 maxS[oclass].transformCentroid(invTrans);
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
01963
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
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
02055 nodeFeats.at(0) = z;
02056 nodeFeats.at(1) = dist;
02057
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)
02077 continue;
02078
02079
02080
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
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
02111 if (maxCost[oclass] < cost)
02112 {
02113 maxCost[oclass] = cost;
02114 maxS[oclass].setCentroid( target);
02115
02116
02117
02118
02119
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
02143
02144
02145
02146 }
02147
02148 for (size_t oclass = 0; oclass < classes.size(); oclass++)
02149 {
02150
02151
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
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
02174 string featfilename = "data_scene_labelling_full_" + lexical_cast<string > (scene_num);
02175 featfile.open(featfilename.data());
02176
02177
02178
02179
02180
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
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
02202
02203
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
02222
02223
02224
02225
02226
02227
02228
02229
02230
02231
02232
02233
02234
02235
02236
02237
02238 SpectralProfile temp;
02239 apply_segment_filter_and_compute_HOG(*cloud_ptr, *cloud_seg, seg, temp);
02240
02241
02242 if (!cloud_seg->points.empty() && cloud_seg->points.size() > MIN_SEG_SIZE) {
02243
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
02262
02263
02264
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
02270 int seg_id = segment_clouds[i].points[1].segment;
02271
02272
02273 get_color_features(segment_clouds[i], features[seg_id], spectralProfiles[i]);
02274
02275
02276
02277
02278
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
02293
02294
02295
02296
02297
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 << " " << 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
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
02317 featfile << "\n";
02318 }
02319 cerr << "\n";
02320 map < int, vector <float> > edge_features;
02321
02322
02323
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
02331
02332
02333
02334
02335
02336
02337 for (map< int, vector<float> >::iterator it2 = edge_features.begin(); it2 != edge_features.end(); it2++) {
02338
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
02345 if (BinFeatures) {
02346 edgeFeatStumps[featIndex].writeBinnedValues(*it3, featfile, featIndex);
02347 } else {
02348 featfile << " " << featIndex << ":" << *it3;
02349 }
02350 featIndex++;
02351
02352
02353 }
02354
02355 featfile << endl;
02356 }
02357
02358 }
02359
02360
02361
02362
02363
02364
02365
02366
02367
02368
02369 featfile.close();
02370
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());
02379 map<int, int> segIndex2Label;
02380
02381
02382
02383
02384
02385
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
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
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
02432
02433
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
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
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
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
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
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)];
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
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 )
02571 {
02572 ROS_INFO("processing %d cloud.. \n",turnCount+1);
02573 processPointCloud (point_cloud);
02574
02575
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
02584 if (labelsFound.count()== NUM_CLASSES) {
02585 all_done = true;
02586 return;
02587 }
02588
02589
02590 return;
02591 }
02592
02593 if ( turnCount == MAX_TURNS && labelsFound.count() < NUM_CLASSES) {
02594
02595
02596 getMovement(true);
02597 printLabelsToLookFor();
02598
02599 originalScan = false;
02600
02601 double angle = rotations[0] - currentAngle;
02602 robot->turnLeft(angle, 0);
02603
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
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
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
02639 if(!rotations.empty()){
02640 double angle = rotations[0] - currentAngle;
02641
02642 robot->turnLeft(angle,0);
02643
02644 if(translationState ){
02645 robot->moveForward(forwardDistance,2);
02646 }
02647
02648
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
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
02668
02669
02670
02671
02672 printLabelsFound(turnCount);
02673
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
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
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
02713 else if (turnCount < MAX_TRYS && labelsFound.count() < NUM_CLASSES){
02714
02715 ROS_INFO("processing %d cloud.. \n",turnCount+1);
02716 processPointCloud (point_cloud);
02717
02718
02719 getMovement(true);
02720
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 {
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
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
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
02763 else if (turnCount < MAX_TRYS && labelsFound.count() < NUM_CLASSES){
02764
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
02827 if (!cloud_seg->points.empty() && cloud_seg->points.size() > MIN_SEG_SIZE) {
02828 segIndex2Label[index_]=labelMap[cloud_seg->points[1].label];
02829
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
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
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
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
02886 for(size_t i = 0; i < maximas.size(); i++)
02887 {
02888 maximas.at(i).intensity = -FLT_MAX;
02889 }
02890
02891
02892
02893 if (BinFeatures) {
02894 readAllStumpValues();
02895 }
02896
02897 readLabelList(environment + "_to_find.txt");
02898 labelsFound = labelsToFindBitset;
02899 labelsFound.flip();
02900
02901
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
02907
02908 ros::Subscriber cloud_sub_ = n.subscribe("/camera/rgb/points", 1, processPointCloud);
02909
02910 ros::spin();
02911
02912
02913 }
02914
02915