source: proiecte/pmake3d/segment/segment-image.h @ 77

Last change on this file since 77 was 77, checked in by (none), 14 years ago

Added parallelized code

File size: 4.8 KB
Line 
1/*
2Copyright (C) 2006 Pedro Felzenszwalb
3
4This program is free software; you can redistribute it and/or modify
5it under the terms of the GNU General Public License as published by
6the Free Software Foundation; either version 2 of the License, or
7(at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12GNU General Public License for more details.
13
14You should have received a copy of the GNU General Public License
15along with this program; if not, write to the Free Software
16Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
17*/
18
19#ifndef SEGMENT_IMAGE
20#define SEGMENT_IMAGE
21
22#include <cstdlib>
23#include <image.h>
24#include <misc.h>
25#include <filter.h>
26#include "segment-graph.h"
27
28// random color
29rgb random_rgb(){ 
30  rgb c;
31  //double r;
32 
33  c.r = (uchar)random();
34  c.g = (uchar)random();
35  c.b = (uchar)random();
36
37  return c;
38}
39
40// dissimilarity measure between pixels
41static inline float diff(imagef *r, imagef *g, imagef *b,
42                         int x1, int y1, int x2, int y2) {
43  return sqrt(square(imRef(r, x1, y1)-imRef(r, x2, y2)) +
44              square(imRef(g, x1, y1)-imRef(g, x2, y2)) +
45              square(imRef(b, x1, y1)-imRef(b, x2, y2)));
46}
47
48/*
49 * Segment an image
50 *
51 * Returns a color image representing the segmentation.
52 *
53 * im: image to segment.
54 * sigma: to smooth the image.
55 * c: constant for treshold function.
56 * min_size: minimum component size (enforced by post-processing stage).
57 * num_ccs: number of connected components in the segmentation.
58 */
59image *segment_image(image *im, float sigma, float c, int min_size,
60                          int *num_ccs) {
61  int width = im->w;
62  int height = im->h;
63
64  imagef *r = imagef_construct(width, height, false);//new image<float>(width, height);
65  imagef *g = imagef_construct(width, height, false);//new image<float>(width, height);
66  imagef *b = imagef_construct(width, height, false);//new image<float>(width, height);
67
68  // smooth each color channel 
69  for (int y = 0; y < height; y++) {
70    for (int x = 0; x < width; x++) {
71      imRef(r, x, y) = imRef(im, x, y).r;
72      imRef(g, x, y) = imRef(im, x, y).g;
73      imRef(b, x, y) = imRef(im, x, y).b;
74    }
75  }
76  imagef *smooth_r = smooth(r, sigma);
77  imagef *smooth_g = smooth(g, sigma);
78  imagef *smooth_b = smooth(b, sigma);
79 
80  imagef_destruct(r);//delete r;
81  imagef_destruct(g);//delete g;
82  imagef_destruct(b);//delete b;
83 
84  // build graph
85  edge *edges = new edge[width*height*4];
86  int num = 0;
87  for (int y = 0; y < height; y++) {
88    for (int x = 0; x < width; x++) {
89      if (x < width-1) {
90        edges[num].a = y * width + x;
91        edges[num].b = y * width + (x+1);
92        edges[num].w = diff(smooth_r, smooth_g, smooth_b, x, y, x+1, y);
93        num++;
94      }
95
96      if (y < height-1) {
97        edges[num].a = y * width + x;
98        edges[num].b = (y+1) * width + x;
99        edges[num].w = diff(smooth_r, smooth_g, smooth_b, x, y, x, y+1);
100        num++;
101      }
102
103      if ((x < width-1) && (y < height-1)) {
104        edges[num].a = y * width + x;
105        edges[num].b = (y+1) * width + (x+1);
106        edges[num].w = diff(smooth_r, smooth_g, smooth_b, x, y, x+1, y+1);
107        num++;
108      }
109
110      if ((x < width-1) && (y > 0)) {
111        edges[num].a = y * width + x;
112        edges[num].b = (y-1) * width + (x+1);
113        edges[num].w = diff(smooth_r, smooth_g, smooth_b, x, y, x+1, y-1);
114        num++;
115      }
116    }
117  }
118  imagef_destruct(smooth_r);//delete smooth_r;
119  imagef_destruct(smooth_g);//delete smooth_g;
120  imagef_destruct(smooth_b);//delete smooth_b;
121
122  // segment
123  universe *u = segment_graph(width*height, num, edges, c);
124 
125  // post process small components
126  for (int i = 0; i < num; i++) {
127    //int a = u->find(edges[i].a);
128    int a = universe_find(u,edges[i].a);
129    //int b = u->find(edges[i].b);
130    int b = universe_find(u,edges[i].b);
131    //if ((a != b) && ((u->size(a) < min_size) || (u->size(b) < min_size)))
132    if ((a != b) && ((universe_size(u,a) < min_size) || (universe_size(u,b) < min_size)))
133      universe_join(u,a,b);//u->join(a, b);
134  }
135  delete [] edges;
136  //*num_ccs = u->num_sets();
137  *num_ccs = universe_num_sets(u);//u->num_sets();
138
139  //image<rgb> *output = new image<rgb>(width, height);
140  image *output = image_construct(width, height, false);
141
142  // pick random colors for each component
143  rgb *colors = new rgb[width*height];
144  for (int i = 0; i < width*height; i++)
145    colors[i] = random_rgb();
146 
147  for (int y = 0; y < height; y++) {
148    for (int x = 0; x < width; x++) {
149      //int comp = u->find(y * width + x);
150      int comp = universe_find(u,y * width + x);
151      imRef(output, x, y) = colors[comp];
152    }
153  } 
154
155  delete [] colors; 
156  delete u;
157
158  return output;
159}
160
161#endif
Note: See TracBrowser for help on using the repository browser.