00001 #ifndef SEGMENT_IMAGE
00002 #define SEGMENT_IMAGE
00003
00004 #include <cstdlib>
00005 #include <image.h>
00006 #include <misc.h>
00007 #include <filter.h>
00008 #include "segment-graph.h"
00009
00010
00011 rgb random_rgb(){
00012 rgb c;
00013 double r;
00014
00015 c.r = (uchar)random();
00016 c.g = (uchar)random();
00017 c.b = (uchar)random();
00018
00019 return c;
00020 }
00021
00022
00023 static inline float diff(image<float> *r, image<float> *g, image<float> *b,
00024 int x1, int y1, int x2, int y2) {
00025 return sqrt(square(imRef(r, x1, y1)-imRef(r, x2, y2)) +
00026 square(imRef(g, x1, y1)-imRef(g, x2, y2)) +
00027 square(imRef(b, x1, y1)-imRef(b, x2, y2)));
00028 }
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041 image<rgb> *segment_image(image<rgb> *im, float sigma, float c, int min_size,
00042 int *num_ccs) {
00043 int width = im->width();
00044 int height = im->height();
00045
00046 image<float> *r = new image<float>(width, height);
00047 image<float> *g = new image<float>(width, height);
00048 image<float> *b = new image<float>(width, height);
00049
00050
00051 for (int y = 0; y < height; y++) {
00052 for (int x = 0; x < width; x++) {
00053 imRef(r, x, y) = imRef(im, x, y).r;
00054 imRef(g, x, y) = imRef(im, x, y).g;
00055 imRef(b, x, y) = imRef(im, x, y).b;
00056 }
00057 }
00058 image<float> *smooth_r = smooth(r, sigma);
00059 image<float> *smooth_g = smooth(g, sigma);
00060 image<float> *smooth_b = smooth(b, sigma);
00061 delete r;
00062 delete g;
00063 delete b;
00064
00065
00066 edge *edges = new edge[width*height*4];
00067 int num = 0;
00068 for (int y = 0; y < height; y++) {
00069 for (int x = 0; x < width; x++) {
00070 if (x < width-1) {
00071 edges[num].a = y * width + x;
00072 edges[num].b = y * width + (x+1);
00073 edges[num].w = diff(smooth_r, smooth_g, smooth_b, x, y, x+1, y);
00074 num++;
00075 }
00076
00077 if (y < height-1) {
00078 edges[num].a = y * width + x;
00079 edges[num].b = (y+1) * width + x;
00080 edges[num].w = diff(smooth_r, smooth_g, smooth_b, x, y, x, y+1);
00081 num++;
00082 }
00083
00084 if ((x < width-1) && (y < height-1)) {
00085 edges[num].a = y * width + x;
00086 edges[num].b = (y+1) * width + (x+1);
00087 edges[num].w = diff(smooth_r, smooth_g, smooth_b, x, y, x+1, y+1);
00088 num++;
00089 }
00090
00091 if ((x < width-1) && (y > 0)) {
00092 edges[num].a = y * width + x;
00093 edges[num].b = (y-1) * width + (x+1);
00094 edges[num].w = diff(smooth_r, smooth_g, smooth_b, x, y, x+1, y-1);
00095 num++;
00096 }
00097 }
00098 }
00099 delete smooth_r;
00100 delete smooth_g;
00101 delete smooth_b;
00102
00103
00104 universe *u = segment_graph(width*height, num, edges, c);
00105
00106
00107 for (int i = 0; i < num; i++) {
00108 int a = u->find(edges[i].a);
00109 int b = u->find(edges[i].b);
00110 if ((a != b) && ((u->size(a) < min_size) || (u->size(b) < min_size)))
00111 u->join(a, b);
00112 }
00113 delete [] edges;
00114 *num_ccs = u->num_sets();
00115
00116 image<rgb> *output = new image<rgb>(width, height);
00117
00118
00119 rgb *colors = new rgb[width*height];
00120 for (int i = 0; i < width*height; i++)
00121 colors[i] = random_rgb();
00122
00123 for (int y = 0; y < height-1; y++) {
00124 for (int x = 0; x < width-1; x++) {
00125 int comp = u->find(y * width + x);
00126 imRef(output, x, y) = colors[comp];
00127 }
00128 }
00129
00130 delete [] colors;
00131 delete u;
00132
00133 return output;
00134 }
00135
00136 #endif