SphereUniformSampling.cpp
Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 2013, Fraunhofer FKIE
00003  *
00004  * Authors: Bastian Gaspers
00005  *
00006  * Redistribution and use in source and binary forms, with or without
00007  * modification, are permitted provided that the following conditions are met:
00008  *
00009  * * Redistributions of source code must retain the above copyright
00010  *   notice, this list of conditions and the following disclaimer.
00011  * * Redistributions in binary form must reproduce the above copyright
00012  *   notice, this list of conditions and the following disclaimer in the
00013  *   documentation and/or other materials provided with the distribution.
00014  * * Neither the name of the Fraunhofer FKIE nor the names of its
00015  *   contributors may be used to endorse or promote products derived from
00016  *   this software without specific prior written permission.
00017  *
00018  * This file is part of the StructureColoring ROS package.
00019  *
00020  * The StructureColoring ROS package is free software:
00021  * you can redistribute it and/or modify it under the terms of the
00022  * GNU Lesser General Public License as published by the Free
00023  * Software Foundation, either version 3 of the License, or
00024  * (at your option) any later version.
00025  *
00026  * The StructureColoring ROS package is distributed in the hope that it will be useful,
00027  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00028  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00029  * GNU Lesser General Public License for more details.
00030  *
00031  * You should have received a copy of the GNU Lesser General Public License
00032  * along with The StructureColoring ROS package.
00033  * If not, see <http://www.gnu.org/licenses/>.
00034  */
00035 
00036 #include <structureColoring/histograms/SphereUniformSampling.h>
00037 
00038 SphereUniformSampling::SphereUniformSampling(unsigned int phi_resolution, bool halfSphereFlip)
00039         :mPhi_resolution(phi_resolution), mHalfSphereFlip(halfSphereFlip){
00040         mData.resize(mPhi_resolution);
00041         mRatioToNextData.resize(mPhi_resolution - 1);
00042         for(unsigned int i=0; i<mPhi_resolution; i++){
00043                 unsigned int uisize = 2 * mPhi_resolution * sin (M_PI * (float)i / (float)mPhi_resolution) + 1.5;
00044                 mData[i].reserve(uisize);
00045                 for(unsigned int j=0; j<uisize; j++){
00046                         mData[i].push_back(SphereUniformSampling::NormalEntry(i, j, mPhi_resolution));
00047                 }
00048                 if(i>0)mRatioToNextData[i-1] = uisize / mData[i-1].size();
00049         }
00050 }
00051 
00052 //void SphereUniformSampling::mergeVectors(std::vector<int>& out, const std::vector<int>& in1, const std::vector<int>& in2){
00053 //      if(in1.size() == 0) out = in2;
00054 //      else if(in2.size() == 0) out = in1;
00055 //      else{
00056 //              out.clear();
00057 //              out.reserve(in1.size() + in2.size());
00058 //              unsigned int j=0;
00059 //              for(unsigned int i=0;i<in1.size(); i++){
00060 //                      while ((j<in2.size())&&(in1[i] > in2[j])){
00061 //                              out.push_back(in2[j]);
00062 //                              j++;
00063 //                      }
00064 //                      if (in1[i] < in2[j])out.push_back(in1[i]);
00065 //              }
00066 //              for (;j<in2.size();j++){
00067 //                      out.push_back(in2[j]);
00068 //              }
00069 //      }
00070 //}
00071 
00072 void SphereUniformSampling::getHistogramIndicesFromAngles(unsigned int& i, unsigned int& j, const float phi, const float theta, const unsigned int phi_resolution){
00073         float phi_corrected = phi;
00074         if (phi_corrected > M_PI){
00075                 phi_corrected = M_PI;
00076                 ROS_ERROR("getHistogramIndicesFromAngles: phi (%f) > PI", phi);
00077         }
00078         i = ((phi_corrected/(M_PI)) * phi_resolution)+0.5;
00079 
00080         float theta_corrected = theta;
00081         if (theta_corrected >= 2.f * M_PI){
00082                 theta_corrected = 0;
00083                 ROS_ERROR("getHistogramIndicesFromAngles: theta (%f) > 2 * PI", theta);
00084         }
00085         unsigned int uisize = 2 * phi_resolution * sin (M_PI * (float)i / (float)phi_resolution) + 1.5;
00086         j = ((theta_corrected / (2.f * M_PI)) * uisize)+0.5;
00087 }
00088 
00089 void SphereUniformSampling::getAnglesFromHistogramIndices(float& phi, float& theta, const unsigned int i, const unsigned int j, const unsigned int phi_resolution){
00090         unsigned int uisize = 2 * phi_resolution * sin (M_PI * (float)i / (float)phi_resolution) + 1.5;
00091         if((i==(unsigned int)-1)||(j==(unsigned int)-1)){
00092                 phi = -M_PI;
00093                 theta = -M_PI;
00094         } else {
00095                 phi = (float)i * M_PI / (float)phi_resolution;
00096                 theta = 2.f * M_PI * ((float)(j) / ((float)uisize));
00097         }
00098         if (phi > M_PI){
00099                 if (phi < M_PI +0.01){
00100                         phi = M_PI - 0.0001;
00101                 } else {
00102                         ROS_ERROR("getAnglesFromHistogramIndices: phi (%f) > PI", phi);
00103                         phi = M_PI;
00104                 }
00105         }
00106         if (theta >= 2 * M_PI){
00107                 if (theta < 2 * M_PI +0.01){
00108                         theta = 2 * M_PI - 0.0001;
00109                 } else {
00110                         ROS_ERROR("getAnglesFromHistogramIndices: theta (%f) >= 2 * PI", theta);
00111                         theta = 0;
00112                 }
00113         }
00114 }
00115 
00116 void SphereUniformSampling::getPointsAngle(std::list<int>& points, const float phi, const float theta, const float max_angle) const{
00117         points.clear();
00118         std::list<int> nPoints;
00119         if((phi >= 0)&&(theta >= 0)){
00120                 std::vector<Pair2ui> neighbors;
00121                 getAllAngleNeighbors(neighbors, phi, theta, max_angle);
00122                 for(unsigned int n=0; n<neighbors.size(); n++){
00123                         nPoints = mData[neighbors[n].first][neighbors[n].second].getPoints();
00124                         points.merge(nPoints);
00125                 }
00126         }
00127 }
00128 
00129 void SphereUniformSampling::getPoints(std::vector<int>& points, const unsigned int i, const unsigned int j, std::vector<float>* weights) const{
00130         points.clear();
00131         if ((i < mData.size()) && (j < mData[i].size())){
00132                 const std::list<int>& points_list = mData[i][j].getPoints();
00133                 for(std::list<int>::const_reverse_iterator list_it=points_list.rbegin(); list_it != points_list.rend(); ++list_it){
00134                         points.push_back(*list_it);
00135                 }
00136                 if (weights != NULL){
00137                         const std::list<float>& weights_list = mData[i][j].getWeights();
00138                         for(std::list<float>::const_reverse_iterator list_it=weights_list.rbegin(); list_it != weights_list.rend(); ++list_it){
00139                                 weights->push_back(*list_it);
00140                         }
00141                 }
00142         }
00143 }
00144 
00145 float SphereUniformSampling::getMaximumAngle(float& phi, float& theta, const float max_angle) const{
00146         float max_weight=-1.f, phi_ij, theta_ij;
00147         unsigned int max_i=-1, max_j=-1;
00148         for(unsigned int i=0; i<mData.size(); i++){
00149                 for(unsigned int j=0; j<mData[i].size(); j++){
00150                         mData[i][j].getAngles(phi_ij, theta_ij);
00151                         float tmp_weight = getWeightAngle(phi_ij, theta_ij, max_angle);
00152                         if (tmp_weight > max_weight){
00153                                 max_weight = tmp_weight;
00154                                 max_i = i;
00155                                 max_j = j;
00156                         }
00157                 }
00158         }
00159         mData[max_i][max_j].getAngles(phi, theta);
00160         return max_weight;
00161 }
00162 
00163 float SphereUniformSampling::getMaximumIndices(unsigned int& idx_i, unsigned int& idx_j, const float max_angle) const{
00164         float max_weight=-1.f, phi_ij, theta_ij;
00165         unsigned int max_i=-1, max_j=-1;
00166         for(unsigned int i=0; i<mData.size(); i++){
00167                 for(unsigned int j=0; j<mData[i].size(); j++){
00168                         mData[i][j].getAngles(phi_ij, theta_ij);
00169                         float tmp_weight = getWeightAngle(phi_ij, theta_ij, max_angle);
00170                         if (tmp_weight > max_weight){
00171                                 max_weight = tmp_weight;
00172                                 max_i = i;
00173                                 max_j = j;
00174                         }
00175                 }
00176         }
00177         idx_i = max_i;
00178         idx_j = max_j;
00179         return max_weight;
00180 }
00181 
00182 float SphereUniformSampling::getMaximum(unsigned int& imax, unsigned int& jmax) const{
00183         imax = 0; jmax = 0;
00184         float wmax = 0.f;
00185         for (unsigned int i=0; i<mData.size(); i++){
00186                 for(unsigned int j=0; j<mData[i].size(); j++){
00187                         float w = mData[i][j].getWeight();
00188                         if(w > wmax){
00189                                 imax = i;
00190                                 jmax = j;
00191                                 wmax = w;
00192                         }
00193                 }
00194         }
00195         return wmax;
00196 }
00197 
00198 void SphereUniformSampling::getAllAngleNeighbors(std::vector<Pair2ui>& neighbors, const float phi, const float theta, const float max_angle) const{
00199         float dotProduct = 0.f, max_angle_cos = cos(max_angle);
00200         neighbors.clear();
00201         Eigen::Vector3f pointNormal(0, 0, 0);
00202         Eigen::Vector3f binNormal;
00203         pointNormal.z() = cos(phi);
00204         pointNormal.y() = sin(theta) * sin(phi);
00205         pointNormal.x() = cos(theta) * sin(phi);
00206         for(unsigned int i=0; i<mData.size(); i++){
00207                 for(unsigned int j=0; j<mData[i].size(); j++){
00208                         binNormal = mData[i][j].getNormal();
00209                         dotProduct = binNormal.dot(pointNormal);
00210                         if(mHalfSphereFlip) dotProduct = fabsf(dotProduct);
00211                         if (dotProduct >= max_angle_cos){
00212                                 neighbors.push_back(std::make_pair(i, j));
00213                         }
00214                 }
00215         }
00216 }
00217 
00218 void SphereUniformSampling::getAllAngleNeighbors(std::vector<Pair2ui>& neighbors, const Eigen::Vector3f& pointNormal, const float max_angle) const{
00219         float dotProduct = 0.f, max_angle_cos = cos(max_angle);
00220         neighbors.clear();
00221         Eigen::Vector3f binNormal;
00222         for(unsigned int i=0; i<mData.size(); i++){
00223                 for(unsigned int j=0; j<mData[i].size(); j++){
00224                         binNormal = mData[i][j].getNormal();
00225                         dotProduct = binNormal.dot(pointNormal);
00226                         if(mHalfSphereFlip) dotProduct = fabsf(dotProduct);
00227                         if (dotProduct >= max_angle_cos){
00228                                 neighbors.push_back(std::make_pair(i, j));
00229                         }
00230                 }
00231         }
00232 }
00233 
00234 void SphereUniformSampling::getHistogramAsPointCloud(pcl::PointCloud<pcl::PointXYZRGB>& histogramCloud, const float scale, const Eigen::Vector3f& translation) const{
00235         pcl::PointXYZRGB binNormal;
00236         unsigned int imax=0, jmax=0;
00237         getMaximum(imax, jmax);
00238         float maxWeight = mData[imax][jmax].getWeight();
00239         for (unsigned int i=0; i<mData.size(); i++){
00240                 for (unsigned int j=0; j<mData[i].size(); j++){
00241                         Eigen::Vector3f normal = mData[i][j].getNormal();
00242                         binNormal.x = normal.x() * scale + translation.x();
00243                         binNormal.y = normal.y() * scale + translation.y();
00244                         binNormal.z = normal.z() * scale + translation.z();
00245                         //unsigned int rgb = 0xffffff;
00246                         unsigned int rgb = 0x000000;
00247 //                      if ((i == imax) && (j == jmax)) rgb = 0x00ffff;
00248 //                      else {
00249                                 unsigned int w = (unsigned int)(255 * mData[i][j].getWeight() / maxWeight);//(getWeightAngle(phi, theta, max_angle)+0.5);
00250                                 if(w > 0xff) w = 0xff;
00251                                 unsigned int col = (w<<8) + (w<<16) + w;
00252                                 if(col > 0xffffff)col = 0xffffff;
00253                                 //rgb -= col;
00254                                 rgb += col;
00255 //                      }
00256                         binNormal.rgb = *(float*)&rgb;
00257                         histogramCloud.points.push_back(binNormal);
00258                 }
00259         }
00260 }
00261 
00262 void SphereUniformSampling::addPointNoNeighbors(std::list<int>::iterator& points_it, std::list<float>::iterator& weights_it, const unsigned int i, const unsigned int j, const int index, const float weight){
00263         if ((i<mData.size()) && (j<mData[i].size()))
00264                 mData[i][j].addIndex(points_it, weights_it, index, weight);
00265 }
00266 
00267 void SphereUniformSampling::deletePointsAtAngle(const float phi, const float theta, const float max_angle){
00268         std::vector<Pair2ui> neighbors;
00269         getAllAngleNeighbors(neighbors, phi, theta, max_angle);
00270         for(unsigned int n=0; n<neighbors.size(); n++){
00271                 deleteEntry(neighbors[n].first, neighbors[n].second);
00272         }
00273 }
00274 
00275 void SphereUniformSampling::deletePointNWeightAt(const std::list<int>::iterator points_it, const std::list<float>::iterator weights_it, const unsigned int i, const unsigned int j){
00276         if ((i<mData.size()) && (j<mData[i].size())){
00277                 mData[i][j].deletePointNWeight(points_it, weights_it);
00278         }
00279 }
00280 
00281 float SphereUniformSampling::getWeightAngle(const float phi, const float theta, const float max_angle) const{
00282         float ret_weight=0.f;
00283         std::vector<Pair2ui> neighbors;
00284         getAllAngleNeighbors(neighbors, phi, theta, max_angle);
00285         for(unsigned int n=0; n<neighbors.size(); n++){
00286                 ret_weight += mData[neighbors[n].first][neighbors[n].second].getWeight();
00287         }
00288         return ret_weight;
00289 }
00290 
00291 float SphereUniformSampling::getPlanarAngle(const float phi1, const float theta1, const float phi2, const float theta2) const{
00292         Eigen::Vector3f normal1(cos(phi1)*sin(theta1),sin(phi1)*sin(theta1),cos(theta1));
00293         Eigen::Vector3f normal2(cos(phi2)*sin(theta2),sin(phi2)*sin(theta2),cos(theta2));
00294         return acos(normal1.dot(normal2));
00295 }
00296 
00297 void SphereUniformSampling::deleteEntry(unsigned int i, unsigned int j){
00298         if ((i < mData.size()) && (j < mData[i].size())){
00299                 mData[i][j].deleteEntry();
00300         }
00301 }
00302 
00303 SphereUniformSampling::NormalEntry::NormalEntry(const unsigned int i, const unsigned int j, const unsigned int phi_resolution){
00304         SphereUniformSampling::getAnglesFromHistogramIndices(mPhi, mTheta, i, j, phi_resolution);
00305         getNormalFromAngles(mNormal, mPhi, mTheta);
00306         mWeight = 0;
00307 }
00308 
00309 void SphereUniformSampling::NormalEntry::addIndex(std::list<int>::iterator& points_it, std::list<float>::iterator& weights_it, const int idx, const float w){
00310         mWeight+=w;
00311         mPoints.push_back(idx);
00312         mWeights.push_back(w);
00313         points_it = mPoints.end();
00314         points_it--;
00315         weights_it = mWeights.end();
00316         weights_it--;
00317 }
00318 
00319 void SphereUniformSampling::NormalEntry::deletePointNWeight(const std::list<int>::iterator points_it, const std::list<float>::iterator weights_it){
00320         mPoints.erase(points_it);
00321         mWeight -= *weights_it;
00322         mWeights.erase(weights_it);
00323 }
00324 
00325 void SphereUniformSampling::NormalEntry::getNormalFromAngles(Eigen::Vector3f& normal, const float phi, const float theta){
00326         normal.z() = cos(phi);
00327         normal.y() = sin(theta) * sin(phi);
00328         normal.x() = cos(theta) * sin(phi);
00329 }


structure_coloring_fkie
Author(s): Bastian Gaspers
autogenerated on Sun Jan 5 2014 11:38:09