blob_properties.cc
Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 2008, Willow Garage, Inc.
00003  * All rights reserved.
00004  *
00005  * Redistribution and use in source and binary forms, with or without
00006  * modification, are permitted provided that the following conditions are met:
00007  *
00008  *     * Redistributions of source code must retain the above copyright
00009  *       notice, this list of conditions and the following disclaimer.
00010  *     * Redistributions in binary form must reproduce the above copyright
00011  *       notice, this list of conditions and the following disclaimer in the
00012  *       documentation and/or other materials provided with the distribution.
00013  *     * Neither the name of the Willow Garage, Inc. nor the names of its
00014  *       contributors may be used to endorse or promote products derived from
00015  *       this software without specific prior written permission.
00016  *
00017  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00018  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00019  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00020  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
00021  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00022  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
00023  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00024  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
00025  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00026  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00027  * POSSIBILITY OF SUCH DAMAGE.
00028  *
00029  */
00030 
00039 #include "blob_properties.h"
00040 #include "gcc_version.h"
00041 
00042 namespace semanticmodel
00043 {
00044 
00045 using std::vector;
00046 using std::map;
00047 using std::string;
00048 
00049 typedef vector<float> Color;
00050 typedef vector<string> Colors;
00051 
00052 
00053 GeometricInfo centroidAndDiameter (const PointCloud& cloud)
00054 {
00055   boost::optional<double> min_x, min_y, min_z, max_x, max_y, max_z;
00056   double sx=0, sy=0, sz=0;
00057   const size_t n=cloud.points.size();
00058   ROS_ASSERT (n>0);
00059   BOOST_FOREACH (const Point& p, cloud)
00060   {
00061     sx += p.x;
00062     sy += p.y;
00063     sz += p.z;
00064     if (!min_x)
00065     {
00066       min_x = p.x;
00067       min_y = p.y;
00068       min_z = p.z;
00069       max_x = p.x;
00070       max_y = p.y;
00071       max_z = p.z;
00072     }
00073     else
00074     {
00075       // Guaranteed that all min/max are initialized
00076       if (*min_x > p.x)
00077         min_x = p.x;
00078       if (*min_y > p.y)
00079         min_y = p.y;
00080       if (*min_z > p.z)
00081         min_z = p.z;
00082       if (*max_x < p.x)
00083         max_x = p.x;
00084       if (*max_y < p.y)
00085         max_y = p.y;
00086       if (*max_z < p.z)
00087         max_z = p.z;
00088     }
00089   }
00090 
00091 #ifdef SEMANTIC_MODEL_GCC_46
00092 #pragma GCC diagnostic push
00093 #pragma GCC diagnostic ignored "-Wuninitialized"
00094 #endif
00095 
00096   const double dx = *max_x - *min_x;
00097   const double dy = *max_y - *min_y;
00098   const double dz = *max_z - *min_z;
00099   
00100 #ifdef SEMANTIC_MODEL_GCC_46
00101 #pragma GCC diagnostic pop
00102 #endif
00103 
00104   return GeometricInfo(sx/n, sy/n, sz/n, std::max(dx, std::max(dy, dz)));
00105 }
00106 
00107 
00108 
00109 Color color (float r, float g, float b)
00110 {
00111   Color c(3);
00112   c[0] = r;
00113   c[1] = g;
00114   c[2] = b;
00115   return c;
00116 }
00117 
00118 void rgbToHsv(const float r, const float g, const float b,
00119               float& h, float& s, float& v)
00120 {
00121   const float max = std::max(r, std::max(g, b));
00122   const float min = std::min(r, std::min(g, b));
00123   const float d = max-min;
00124   s = max==0.0 ? 0.0 : d/max;
00125   if (max==min) {
00126     h = 0;
00127   }
00128   else {
00129     if (max==r)
00130       h = (g - b) / d + (g < b ? 6 : 0);
00131     else if (max==g)
00132       h = (b - r) / d + 2;
00133     else
00134       h = (r - g) / d + 4;
00135     h /= 6;
00136   }
00137   v = max;
00138 }
00139 
00140 
00141 enum { BLACK, GREY, WHITE, RED, YELLOW, GREEN, BLUE };
00142 
00143 Colors createColors ()
00144 {
00145   Colors c(7);
00146   c[BLACK] = string("black");
00147   c[GREY] = "grey";
00148   c[WHITE] = "white";
00149   c[RED] = "red";
00150   c[YELLOW] = "yellow";
00151   c[GREEN] = "green";
00152   c[BLUE] = "blue";
00153   return c;
00154 }
00155 
00156 int matchingColor(float r, float g, float b)
00157 {
00158   ROS_ASSERT(r>=0 && g>=0 && b>=0 && r<=1 && g<=1 && b<=1);
00159   float h=0, s=0, v=0;
00160   rgbToHsv (r, g, b, h, s, v);
00161   ROS_ASSERT (h>=0 && h<=1 && s>=0 && s<=1 && v>=0 && v<=1);
00162 
00163   if (v<0.3)
00164     return BLACK;
00165   else if (v>0.85 && s<0.15)
00166     return WHITE;
00167   else if (s<0.2)
00168     return GREY;
00169   if (h < 0.1 || h >= 0.75)
00170     return RED;
00171   else if (h >= 0.1 && h < 0.15)
00172     return YELLOW;
00173   else if (h >= 0.15 && h < 0.45)
00174     return GREEN;
00175   else // if (h >= 0.45 && h < 0.75)
00176     return BLUE;
00177 }
00178 
00179 
00180 string blobColorName(const Blob& blob)
00181 {
00182   static vector<string> colors = createColors();
00183 
00184   typedef map<int, int> Histogram;
00185   Histogram counts;
00186   BOOST_FOREACH (const Point& p, *blob.cloud)
00187   {
00188     float r, g, b;
00189     uint32_t rgb = *reinterpret_cast<const int*>(&p.rgb);
00190     uint8_t rb = (rgb >> 16) & 0x0000ff;
00191     uint8_t gb = (rgb >> 8)  & 0x0000ff;
00192     uint8_t bb = (rgb)       & 0x0000ff;
00193     r = rb/255.0;
00194     g = gb/255.0;
00195     b = bb/255.0;
00196     counts[matchingColor(r, g, b)] += 1;
00197   }
00198   
00199   int best_count=-1;
00200   int best=-42;
00201   BOOST_FOREACH (const Histogram::value_type& e, counts)
00202   {
00203     if (e.second>best_count)
00204     {
00205       best_count = e.second;
00206       best = e.first;
00207     }
00208   }
00209   ROS_ASSERT (best_count>0);
00210   return colors[best];
00211 }
00212 
00213 } // namespace


semanticmodel
Author(s): Julian ("Mac") Mason
autogenerated on Thu Dec 12 2013 12:39:10