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
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045 #ifndef SUPERPIXEL_SEGMENT_IMAGE
00046 #define SUPERPIXEL_SEGMENT_IMAGE
00047
00048 #include <cstdlib>
00049
00050 #include "Image/Image.H"
00051 #include "Image/Pixels.H"
00052 #include "Raster/Raster.H"
00053 #include "Image/MathOps.H"
00054 #include "Image/ColorOps.H"
00055
00056 #include "Gist/SuperPixel_filter.H"
00057 #include "Gist/SuperPixel_segment_graph.H"
00058
00059 #include "Util/Timer.H"
00060
00061
00062 PixRGB<byte> random_rgb(){
00063 PixRGB<byte> c((byte)random(),
00064 (byte)random(),
00065 (byte)random());
00066 return c;
00067 }
00068
00069
00070 static inline float
00071 diff(Image<float> r, Image<float> g, Image<float> b,
00072 int x1, int y1, int x2, int y2)
00073 {
00074 return sqrt(pow(r.getVal(x1, y1) - r.getVal(x2, y2), 2.0) +
00075 pow(g.getVal(x1, y1) - g.getVal(x2, y2), 2.0) +
00076 pow(b.getVal(x1, y1) - b.getVal(x2, y2), 2.0));
00077 }
00078
00079 static inline float
00080 diff(std::vector<Image<float> > channels,
00081 int x1, int y1, int x2, int y2)
00082 {
00083 float difference = 0.0;
00084 std::vector<Image<float> >::iterator
00085 it = channels.begin(),
00086 stop = channels.end();
00087 for (;it!=stop; ++it)
00088 {
00089 Image<float> ch = *it;
00090 difference+= pow(ch.getVal(x1, y1) - ch.getVal(x2, y2), 2.0) ;
00091 }
00092
00093 return sqrt(difference);
00094 }
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114 Image<int> SuperPixelSegment
00115 (Image<PixRGB<byte> > im,
00116 float sigma, float c, int min_size, int &num_ccs,
00117 std::vector<std::vector<Point2D<int> > > *groups ,
00118 std::vector<Image<float> > channels )
00119 {
00120
00121 std::vector<Image<float> > smooth_channels;
00122 std::vector<Image<float> >::iterator
00123 it = channels.begin(),
00124 stop = channels.end();
00125 for (;it!=stop; ++it) {
00126 Image<float> ch = *it;
00127 Image<float> smooth_temp = smooth(ch, sigma);
00128 smooth_channels.push_back(smooth_temp);
00129 }
00130
00131 int width = im.getWidth();
00132 int height = im.getHeight();
00133
00134
00135 edge *edges = new edge[width*height*4];
00136 int num = 0;
00137 for (int y = 0; y < height; y++) {
00138 for (int x = 0; x < width; x++) {
00139 if (x < width-1) {
00140 edges[num].a = y * width + x;
00141 edges[num].b = y * width + (x+1);
00142 edges[num].w = diff(smooth_channels, x, y, x+1, y);
00143 num++;
00144 }
00145
00146 if (y < height-1) {
00147 edges[num].a = y * width + x;
00148 edges[num].b = (y+1) * width + x;
00149 edges[num].w = diff(smooth_channels, x, y, x, y+1);
00150 num++;
00151 }
00152
00153 if ((x < width-1) && (y < height-1)) {
00154 edges[num].a = y * width + x;
00155 edges[num].b = (y+1) * width + (x+1);
00156 edges[num].w = diff(smooth_channels, x, y, x+1, y+1);
00157 num++;
00158 }
00159
00160 if ((x < width-1) && (y > 0)) {
00161 edges[num].a = y * width + x;
00162 edges[num].b = (y-1) * width + (x+1);
00163 edges[num].w = diff(smooth_channels, x, y, x+1, y-1);
00164 num++;
00165 }
00166 }
00167 }
00168
00169
00170 universe *u = segment_graph(width*height, num, edges, c);
00171
00172
00173 for (int i = 0; i < num; i++) {
00174 int a = u->find(edges[i].a);
00175 int b = u->find(edges[i].b);
00176 if ((a != b) && ((u->size(a) < min_size) || (u->size(b) < min_size)))
00177 u->join(a, b);
00178 }
00179 delete [] edges;
00180 num_ccs = u->num_sets();
00181
00182 Image<int> groupImage(width, height, NO_INIT);
00183
00184
00185
00186 groups->resize(u->num_sets());
00187
00188
00189
00190
00191 std::map<int, int> groupLabels;
00192 int labelCount = 0;
00193
00194 for (int y = 0; y < height; y++)
00195 for (int x = 0; x < width; x++)
00196 {
00197 int groupUnorderedId = u->find(y * width + x);
00198
00199
00200
00201 if(groupLabels.find(groupUnorderedId) == groupLabels.end())
00202 groupLabels[groupUnorderedId] = labelCount++;
00203
00204 int groupOrderedId = groupLabels[groupUnorderedId];
00205
00206 if(groups != NULL)
00207 (*groups)[groupOrderedId].push_back(Point2D<int>(x,y));
00208 groupImage.setVal(x, y, groupOrderedId);
00209 }
00210
00211 delete u;
00212
00213 return groupImage;
00214 }
00215
00216
00217 Image<int> SuperPixelSegment
00218 (Image<PixRGB<byte> > im,
00219 float sigma, float c, int min_size, int &num_ccs,
00220 std::vector<std::vector<Point2D<int> > > *groups)
00221 {
00222 Image<byte> r, g, b; getComponents(im, r, g, b);
00223
00224 std::vector<Image<float> > channels;
00225 channels.push_back(r);
00226 channels.push_back(g);
00227 channels.push_back(b);
00228
00229 return SuperPixelSegment
00230 (im,sigma,c,min_size,num_ccs,groups,channels);
00231 }
00232
00233
00234 namespace
00235 { std::vector<PixRGB<byte> > groupColors; }
00236
00237
00238 Image<int> SuperPixelRegionSizeImage
00239 (std::vector<std::vector<Point2D<int> > > const& groups, Image<int> groupImage)
00240 {
00241 Image<int> debugSizeImage(groupImage.getDims(), NO_INIT);
00242
00243 for(size_t grpIdx=0; grpIdx < groups.size(); grpIdx++)
00244 {
00245 int regionSize = (int) groups[grpIdx].size();
00246 for(size_t pntIdx=0; pntIdx<groups[grpIdx].size(); pntIdx++)
00247 debugSizeImage.setVal(groups[grpIdx][pntIdx], regionSize);
00248 }
00249
00250 return debugSizeImage;
00251 }
00252
00253
00254 Image<PixRGB<byte> > SuperPixelDebugImage(Image<int> groupImage)
00255 {
00256
00257 if(groupColors.size() == 0)
00258 {
00259 groupColors.resize(255);
00260 std::vector<PixRGB<byte> >::iterator
00261 it = groupColors.begin(),
00262 stop = groupColors.end();
00263 for (;it!=stop; ++it) *it = random_rgb();
00264 }
00265
00266 Image<PixRGB<byte> > debugImage(groupImage.getDims(), NO_INIT);
00267
00268 for(size_t i=0; i<groupImage.size(); ++i)
00269 debugImage.setVal
00270 (i,groupColors[groupImage.getVal(i)%groupColors.size()]);
00271
00272 return debugImage;
00273 }
00274
00275
00276 Image<PixRGB<byte> > SuperPixelDebugImage
00277 (std::vector<std::vector<Point2D<int> > > const& groups,
00278 Image<PixRGB<byte> > originalImage)
00279 {
00280 Image<PixRGB<byte> > debugImage(originalImage.getDims(), NO_INIT);
00281
00282 for(size_t grpIdx=0; grpIdx < groups.size(); grpIdx++)
00283 {
00284 PixRGB<long> avgColor(0,0,0);
00285 for(size_t pntIdx=0; pntIdx<groups[grpIdx].size(); pntIdx++)
00286 avgColor += originalImage.getVal(groups[grpIdx][pntIdx]);
00287 avgColor /= groups[grpIdx].size();
00288 for(size_t pntIdx=0; pntIdx<groups[grpIdx].size(); pntIdx++)
00289 debugImage.setVal(groups[grpIdx][pntIdx], avgColor);
00290 }
00291
00292 return debugImage;
00293 }
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312 Image<PixRGB<byte> > segment_image
00313 (Image<PixRGB<byte> > im, float sigma, float c, int min_size,
00314 int &num_ccs)
00315 {
00316 LINFO("This method is now deprecated. "
00317 "Please use SuperPixelSegment "
00318 "and SuperPixelDebugImage instead.");
00319 std::vector<std::vector<Point2D<int> > > groups;
00320 Image<int> groupImage =
00321 SuperPixelSegment
00322 (im, sigma, c, min_size, num_ccs, &groups);
00323 return SuperPixelDebugImage(groups,im);
00324 }
00325
00326 #endif
00327
00328
00329
00330
00331
00332