$search
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