00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
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
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
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 }