[GRASS-SVN] r52019 - grass-addons/grass7/imagery/i.segment
svn_grass at osgeo.org
svn_grass at osgeo.org
Sat Jun 9 22:04:17 PDT 2012
Author: momsen
Date: 2012-06-09 22:04:16 -0700 (Sat, 09 Jun 2012)
New Revision: 52019
Modified:
grass-addons/grass7/imagery/i.segment/create_isegs.c
grass-addons/grass7/imagery/i.segment/iseg.h
grass-addons/grass7/imagery/i.segment/outline
grass-addons/grass7/imagery/i.segment/parse_args.c
grass-addons/grass7/imagery/i.segment/write_output.c
Log:
work in progress... hangs up... Using arrays - dumb/quick data structure, just to implement and see if logic works.
Modified: grass-addons/grass7/imagery/i.segment/create_isegs.c
===================================================================
--- grass-addons/grass7/imagery/i.segment/create_isegs.c 2012-06-09 17:42:15 UTC (rev 52018)
+++ grass-addons/grass7/imagery/i.segment/create_isegs.c 2012-06-10 05:04:16 UTC (rev 52019)
@@ -4,11 +4,13 @@
#include <stdlib.h>
#include <float.h> /* to get value of LDBL_MAX -> change this if there is a more usual grass way */
+#include <math.h> /* for sqrt() and pow() */
#include <grass/gis.h>
#include <grass/raster.h>
#include <grass/segment.h> /* segmentation library */
#include "iseg.h"
+
int create_isegs(struct files *files, struct functions *functions)
{
@@ -29,10 +31,11 @@
if (functions->method == 0)
- successflag = io_debug(files, functions);
- else if (functions->method == 1)
+ successflag = io_debug(files, functions); /* TODO: why does it want &files in main, but files here ??? */
+ else if (functions->method == 1) {
+ G_debug(1, "starting region_growing()");
successflag = region_growing(files, functions);
-
+ }
if (successflag != 0)
G_fatal_error("Error creating segments");
@@ -70,18 +73,25 @@
int region_growing(struct files *files, struct functions *functions)
{
- int row, col, n, t, pixel_neighbors[8][2]; /* could dynamically declare to be only 4 or 8 elements, but this is shorter for now */
- double threshold, Ri_simularity, Rk_simularity, tempsim;
+ int row, col, n, m, t;
+ double threshold, Ri_similarity, Rk_similarity, tempsim;
int endflag; /* =1 if there were no merges on that processing iteration */
int pathflag; /* =1 if we didn't find mutual neighbors, and should continue with Rk */
- int mergeflag; /* =1 if we have mutually agreeing best neighbors */
+ /*int mergeflag; just did it based on if statment... *//* =1 if we have mutually agreeing best neighbors */
+
/* Ri = current focus segment
* Rk = Ri's most similar neighbor
* Rkn = Rk's neighbors
* Rin = Ri's neigbors (as pixels or segments ?!?
*/
+ /* lets get this running, and just use fixed dimension arrays for now. t is limited to 90, segments will be small. */
+
+ int Ri[100][2], Rk[100][2], Rin[100][2], Rkn[100][2]; /* 100 or so maximum members, second dimension is for: 0: row 1: col */
+ int Ri_count, Rk_count, Rin_count, Rkn_count; /*crutch for now, probably won't need later. */
+ int Rk_id;
+
G_verbose_message("Running region growing algorithm");
t = 0;
@@ -96,8 +106,10 @@
/* Set candidate flag to true/1 for all pixels TODO: for polygon group, need to just set to true for those being processed */
- for (row = 0; row < files->nrows; row++) {
- for (col = 0; col < files->ncols; col++) {
+ /* for (row = 0; row < files->nrows; row++) {
+ for (col = 0; col < files->ncols; col++) { -----need to deal with edges.... */
+ for (row = 1; row < files->nrows - 1; row++) {
+ for (col = 1; col < files->ncols - 1; col++) {
segment_get(&files->out_seg, (void *)files->out_val, row, col); /*need to get, since we only want to change the flag, and not overwrite the segment value. */
/* TODO: if we are starting from seeds...and only allow merges between unassigned pixels
* and seeds/existing segments, then this needs an if (and will be very inefficient)
@@ -107,7 +119,7 @@
col);
}
}
-
+ G_debug(1, "Starting to process candidate pixels");
/*process candidate pixels */
/*check each pixel, start the processing only if it is a candidate pixel */
@@ -117,64 +129,93 @@
col);
if (files->out_val[1] == 1) { /* out_val[1] is the candidate pixel flag */
- /*TODO: need to empty/reset Ri, Rn, and Rk */
- Ri = Rin = Rk = Rkn = NULL;
+ /*need to empty/reset Ri, Rn, and Rk */
+ /* TODO: this will be different when Ri is different data structure. */
+ for (n = 0; n < 100; n++) {
+ for (m = 0; m < 2; m++) {
+ Ri[n][m] = Rk[n][m] = Rin[n][m] = Rkn[n][m] = 0;
+ }
+ }
+ Rin_count = Rkn_count = Rk_count = 0;
+ Ri_count = 1; /*we'll have the focus pixel to start with. */
+ /* First pixel in Ri is current pixel. We may add more later if it is part of a segment */
+ Ri[0][0] = row;
+ Ri[0][1] = col;
+ /* Ri_seg = files->out_val[0]; don't need this here -have it in merge_segments() *//* out_val[0] is segment ID, we still have data from call to check the flag. *//* TODO: if seperate segment ID from flag, need to get this value. */
+
pathflag = 1;
while (pathflag == 1) { /*if don't find mutual neighbors on first try, will use Rk as next Ri. */
-
- if (find_segment_neighbors(Ri, Rin) != 0) {
+ G_debug(1, "just before find_segment_neighbors(Ri)");
+ if (find_segment_neighbors
+ (Ri, Rin, Ri_count, Rin_count, files,
+ functions) != 0) {
G_debug(1, "Couldn't find neighbors"); /*this could happen if there is a pixel surrounded by pixels that have already been processed */
pathflag = 0;
- set candidate flag to false for this pixel;
+ Ri_count = 0;
+ set_candidate_flag(Ri, 0, files); /* TODO: error trap? */
}
else { /*found neighbors, go ahead until find mutually agreeing neighbors */
-
+ G_debug(1, "Found neighbors");
/* find Ri's most similar neighbor */
- Ri_similarity
- = LDBL_MAX;
+ Rk_id = -1;
+ Ri_similarity = LDBL_MAX; /* set current similarity to max value */
+ segment_get(&files->bands_seg, (void *)files->bands_val, Ri[0][0], Ri[0][1]); /* current segment values */
- for (each Rin) {
- tempsim = calculate_simularity(Ri, one neighbor); /*set up as function pointer... */
- if tempsim
- <Ri_similarity {
+ for (n = 0; n < Rin_count; n++) { /* for each of Ri's neighbors */
+ tempsim = (*functions->calculate_similarity) (Ri[0], Rin[n], files, functions); /*TODO: does this pass just the single point, row/col ???? */
+ if (tempsim < Ri_similarity) {
Ri_similarity = tempsim;
- Rk = current neighbor;
- }
+ Rk_id = n;
+ }
}
- if (Rk != null(need correct null finding !) AND Ri_similarity < threshold) { /* small TODO: should this be < or <=? */
+ if (Rk_id >= 0 && Ri_similarity < threshold) { /* small TODO: should this be < or <= for threshold? */
+ /*we'll have the neighbor pixel to start with. */
+ Rk_count = 1;
+ Rk[0][0] = Rin[Rk_id][0];
+ Rk[0][1] = Rin[Rk_id][1];
- Rkn = Ri; /* we know Ri should be a neighbor of Rk *//*Todo: is there a way to skip similarity calculations on these? keep a count, and pop them before doing the similarity check? */
- find_segment_neighbors(Rk, Rkn); /* data structure for Rk's neighbors, and pixels in Rk if we don't already have it */
+ /* Rkn = Ri; *//* we know Ri should be a neighbor of Rk *//*Todo: is there a way to skip similarity calculations on these? keep a count, and pop them before doing the similarity check? */
+ find_segment_neighbors(Rk, Rkn, Rk_count, Rkn_count, files, functions); /* data structure for Rk's neighbors, and pixels in Rk if we don't already have it */
/*find Rk's most similar neighbor */
- Rk_similarity = Ri_simularity; /*Ri gets first priority - ties won't change anything, so we'll accept Ri and Rk as mutually best neighbors */
+ Rk_similarity = Ri_similarity; /*Ri gets first priority - ties won't change anything, so we'll accept Ri and Rk as mutually best neighbors */
+ segment_get(&files->bands_seg, (void *)files->bands_val, Rk[0][0], Rk[0][1]); /* current segment values */
- for (each Rkn) {
+ for (n = 0; n < Rkn_count; n++) { /* for each of Rk's neighbors */
tempsim =
- calculate_similarity(Rk,
- one neighbor);
+ functions->calculate_similarity(Rk[0],
+ Rkn
+ [n],
+ files,
+ functions);
if (tempsim < Rk_similarity) {
Rk_similarity = tempsim;
- break; /* exit loop here, we know that Ri and Rk aren't mutually best neighbors */
+ break; /* exit for Rk's neighbors loop here, we know that Ri and Rk aren't mutually best neighbors */
}
}
- if (Rk_similarity == Ri_simularity) { /* so they agree, both are mutually most similar neighbors */
- /* put these steps in merge_segments(Ri, Rk) function? */
- update segment values for all pixels in Ri + Rk(mean) /* I assume this is a weighted mean? */
- set candidate flag to false for all pixels in Ri + Rk /* do this at the same time, so there is only one segment_put statement */
- endflag = 0; /* we've made at least one merge, so need another iteration */
-
- pathflag = 0; /* go to next row,column pixel - end of Rk -> Ri chain since we found neighbors */
+ if (Rk_similarity == Ri_similarity) { /* so they agree, both are mutually most similar neighbors */
+ /* TODO: put these steps in merge_segments(Ri, Rk) function? */
+ merge_values(Ri, Rk, Ri_count, Rk_count, files); /* TODO error trap */
+ endflag = 0; /* we've made at least one merge, so need another t iteration */
+ pathflag = 0; /* go to next row,column pixel - end of Rk -> Ri chain since we found mutual best neighbors */
}
else { /* they weren't mutually best neighbors */
- set candidate flag to false for all pixels in Ri; /* TODO !!!!!!!!!!!! hmm, maybe this raster should be its own data structure */
+ set_candidate_flag(Ri, 0, files); /* remove Ri from candidate pixels (set flag) */
- Rk
- = Ri; /* note, this is the eCognition technique. Seems this is a bit faster, we already have segment membership pixels */
+ /* Use Rk as next Ri: this is the eCognition technique. Seems this is a bit faster, we already have segment membership pixels */
+ Ri_count = Rk_count;
+ /* Ri = &Rk; *//* TODO fast/correct way to use arrays and pointers? Ri now will just point to Rk? */
+ /* at beginning, when initialize Rk ` Rk[n][m] = 0 ` ?? with that just remove the Rk pointer, and leave Ri pointing to the original Rk data? */
+ for (n = 0; n < 100; n++) { /*TODO shortcut code...get rid of this... */
+ for (m = 0; m < 2; m++) {
+ Ri[n][m] = Rk[n][m];
+ }
+ }
+
}
} /*end if Rk exists and < threshold */
} /* end else - Ri did have neighbors */
@@ -186,7 +227,7 @@
/* finished one pass for processing candidate pixels */
t++;
- } while (endflag == 0);
+ } while (t < 90 && endflag == 0);
/*end t loop */
/* TODO: free memory */
@@ -194,8 +235,12 @@
return 0;
}
-int find_segment_neighbors(Ri, Rin)
+int find_segment_neighbors(int Ri[][2], int Rin[][2], int seg_count,
+ int segn_count, struct files *files,
+ struct functions *functions)
{
+ G_debug(1, "in find_segment_neighbors()");
+ int n, m, Ri_seg_ID = -1;
/* neighbor list will be a listing of pixels that are neighbors? Include segment numbers? Only include unique segments?
* Maybe the most complete return would be a structure array, structure to include the segment ID and a list of points in it?
@@ -209,33 +254,86 @@
/*local data structures... but maybe they should be allocated out in the main function, is it really slow to create/free on each pass? */
/* Ri : input parameter, list of pixels in the current segment */
- to_check; /* queue or stack - need to check the neighbors of these pixels */
- no_check; /* sorted array or btree: list of pixels (by row / column ?) that have been put into the to_check queue, been processed, or are not candidate pixels */
+ int to_check[100][2]; /* queue or stack - need to check the neighbors of these pixels */
- current_pixel; /*what data type? This will be the popped pixel in each loop. */
+ /* int[100][2] no_check; *//* sorted array or btree: list of pixels (by row / column ?) that have been put into the to_check queue, been processed, or are not candidate pixels */
+ /* or use flag for no_check? ... need a better name for this variable??? */
+
+ int pixel_neighbors[8][2]; /* data type? put in files to allocate memory once? */
+
+ int current_pixel = 0; /*what data type? This will be the popped pixel in each loop. */
+
/* functions->pixel_neighbors ...array, 4 or 8 long. (Can be 4 or 8 neighbors to each pixel)
- * functions->num_pn int, 4 or 8.
+ * functions->num_pn int, 4 or 8. */
- to_check = Ri; /*need to copy data, not just pointer... */
- /* Put input in "current segment" list NOTE: in pseudo code, but think we should just pass Ri and use it directly */
- no_check = Ri; /*need to copy data, not just pointer... */
+ /*initialize data.... TODO: maybe remember min max row/col that was looked at each time, initialize in open_files, and reset smaller region at end of this functions */
+ G_debug(1, "setting files->no_check to 0...");
+ for (n = 0; n < files->nrows; n++)
+ for (m = 0; n < files->ncols; n++)
+ files->no_check[n][m] = 0; /* 0 means should be checked/expanded, 1 means it has already been checked/expanded. */
+
+ G_debug(1, "setting to_check to 0");
+
+ for (n = 0; n < 100; n++) {
+ for (m = 0; m < 2; m++) {
+ to_check[n][m] = files->no_check[n][m] = 0;
+ }
+ }
+
+ /* Put Ri in to be checked and no check lists (don't expand them if we find them again) */
+ /* NOTE: in pseudo code also have a "current segment" list, but think we can just pass Ri and use it directly */
+ G_debug(1, "Setting up Ri... ");
+ for (n = 0; n < seg_count; n++) {
+ to_check[n][0] = Ri[n][0];
+ to_check[n][1] = Ri[n][1];
+
+ files->no_check[Ri[n][0]][Ri[n][1]] = 1;
+ }
+
/* empty "neighbor" list Note: in pseudo code, but think we just pass in Rin - it was already initialized, and later could have Ri data available to start from */
- While(!empty(to_check)) {
- current_pixel = pop next to_check element;
- functions->(*find_pixel_neighbors) (current_pixel, pixel_neighbors);
+ /* get Ri's segment ID */
+ segment_get(&files->out_seg, (void *)files->out_val, Ri[0][0], Ri[0][1]);
+ Ri_seg_ID = files->out_val[1];
+ G_debug(1, "initializing is done, start processing");
+ while (current_pixel >= 0) { /* change to not empty once there is a stack... */
+ G_debug(1, "current_pixel: %d", current_pixel);
+ /* current_pixel = pop next to_check element; */
+ /*syntax for function pointer? functions->(*find_pixel_neighbors) (to_check[current_pixel], pixel_neighbors, files); */
+ functions->find_pixel_neighbors(to_check[current_pixel],
+ pixel_neighbors, files);
+ current_pixel--; /* Done using this pixels coords, now check neighbors and add to the lists */
+ G_debug(1, "found pixel neighbors");
+ for (n = 0; n < functions->num_pn; n++) { /*with pixel neighbors */
+ if (files->no_check[pixel_neighbors[n][0]][pixel_neighbors[n][1]] == 0) { /* want to check this neighbor */
+ files->no_check[pixel_neighbors[n][0]][pixel_neighbors[n][1]] = 1; /* OK, check it, but don't check it again! */
- for (n = 0; n < functions->num_pn; n++) {
- if (!pixel_neighbor[n] in "don't check" list) {
- put pixel_neighbor[n] in "don't check" list segment_get(&files->out_seg, (void *)files->out_val, pixel_neighbor[n][0], pixel_neighbor[n][1]); /*TODO : do I need a second "out_val" data structure? */
+ segment_get(&files->out_seg, (void *)files->out_val, pixel_neighbors[n][0], pixel_neighbors[n][1]); /*TODO : do I need a second "out_val" data structure? */
if (files->out_val[1] == 1) { /* valid candidate pixel */
- put pixel_neighbor[n] in to_check; /*want to check this pixels neighbors */
- if (files->out_val[0] = current segment ID)
- put pixel_neighbor[n] in Ri
- else
- put pixel_neighbor[n] in Rin}
+ G_debug(1, "files->out_val[0] = %d Ri_seg_ID = %d",
+ files->out_val[0], Ri_seg_ID);
+ if (files->out_val[0] == Ri_seg_ID) {
+ G_debug(1, "puting pixel_neighbor in Ri");
+ /* put pixel_neighbor[n] in Ri */
+ Ri[seg_count][0] = pixel_neighbors[n][0];
+ Ri[seg_count][1] = pixel_neighbors[n][1];
+ seg_count++; /* zero index... so increment after save data. */
+
+ /* put pixel_neighbor[n] in to_check -- want to check this pixels neighbors */
+ current_pixel++;
+ to_check[current_pixel][0] = pixel_neighbors[n][0];
+ to_check[current_pixel][1] = pixel_neighbors[n][1];
+
+ }
+ else {
+ /* put pixel_neighbor[n] in Rin */
+ Rin[segn_count][0] = pixel_neighbors[n][0];
+ Rin[segn_count][1] = pixel_neighbors[n][1];
+ segn_count++;
+ }
+ } /*end if valid candidate pixel */
} /*end if for pixel_neighbor was in "don't check" list */
} /* end for loop - next neighbor */
} /* while to_check has more elements */
@@ -243,35 +341,133 @@
return 0;
}
-find_four_pixel_neighbors(pixel, pixel_neighbors)
+int find_four_pixel_neighbors(int pixel[2], int pixel_neighbors[][2],
+ struct files *files)
{
+ /*
+ G_debug(1,"in find 4 pixel neighbors () ");
+ G_debug(1,"pixel row: %d pixel col: %d", pixel[0], pixel[1]);
+ G_debug(1, "Total rows: %d, total cols: %d", files->nrows, files->ncols); /*check that we have files... */
+
/* north */
- pixel_neighbors[0][1] = pixel column;
- if (pixel row > 0)
- pixel_neighbors[0][0] = pixel row + 1;
+ pixel_neighbors[0][1] = pixel[1];
+ if (pixel[0] > 0)
+ pixel_neighbors[0][0] = pixel[0] + 1;
else
- pixel_neighbors[0][0] = pixel row; /*This is itself, which will be in "already checked" list. TODO: use null or -1 as flag to skip? What is fastest to process? */
+ pixel_neighbors[0][0] = pixel[0]; /*This is itself, which will be in "already checked" list. TODO: use null or -1 as flag to skip? What is fastest to process? */
/* east */
- pixel_neighbors[1][0] = pixel row;
- if (pixel column < files->ncols)
- pixel_neighbors[1][1] = pixel column + 1;
+ pixel_neighbors[1][0] = pixel[0];
+ if (pixel[1] < files->ncols)
+ pixel_neighbors[1][1] = pixel[1] + 1;
else
- pixel_neighbors[1][1] = pixel column; /* ditto... */
+ pixel_neighbors[1][1] = pixel[1];
- /*TODO: continue for south and north */
+ /* south */
+ pixel_neighbors[2][1] = pixel[1];
+ if (pixel[0] < files->nrows)
+ pixel_neighbors[2][0] = pixel[0] - 1;
+ else
+ pixel_neighbors[2][0] = pixel[0];
+ /* west */
+ pixel_neighbors[3][0] = pixel[0];
+ if (pixel[1] < 0)
+ pixel_neighbors[3][1] = pixel[1] - 1;
+ else
+ pixel_neighbors[3][1] = pixel[1];
+
/*TODO: seems there should be a more elegent way to do this... */
return 0;
}
-find_eight_pixel_neighbors(pixel, neighbors)
+int find_eight_pixel_neighbors(int pixel[2], int pixel_neighbors[8][2],
+ struct files *files)
{
/* get the 4 orthogonal neighbors */
- find_four_pixel_neighbors(pixel, neighbors);
+ find_four_pixel_neighbors(pixel, pixel_neighbors, files);
/* get the 4 diagonal neighbors */
/*TODO... continue as above */
return 0;
}
+
+/* similarity / distance between two points based on their input raster values */
+/* TODO: I pulled getting the a values into the main function, they are stored in files. Remove a from these parameters */
+double calculate_euclidean_similarity(int a[2], int b[2], struct files *files,
+ struct functions *functions)
+{
+ double val = 0;
+ int n;
+
+ /* get comparison values for point b (got values for a before loop on all neighbors... */
+ segment_get(&files->bands_seg, (void *)files->second_val, b[0], b[1]);
+
+ /* euclidean distance, sum the square differences for each dimension */
+ for (n = 0; n < files->nbands; n++) {
+ val = val + pow(files->bands_val[n] - files->second_val[n], 2);
+ }
+
+ val = sqrt(val);
+
+ return val;
+
+}
+
+int merge_values(int Ri[100][2], int Rk[100][2], int Ri_count, int Rk_count,
+ struct files *files)
+{ /* I assume this is a weighted mean? */
+ int n;
+
+ /*get input values, maybe if handle earlier gets correctly this can be avoided. */
+ segment_get(&files->bands_seg, (void *)files->bands_val, Ri[0][0],
+ Ri[0][1]);
+ segment_get(&files->bands_seg, (void *)files->second_val, Rk[0][0],
+ Rk[0][1]);
+
+ for (n = 0; n < files->nbands; n++) {
+ files->bands_val[n] =
+ (files->bands_val[n] * Ri_count +
+ files->second_val[n] * Rk_count) / (Ri_count + Rk_count);
+ }
+
+ /* update segment number and process flag ==0 */
+
+ segment_get(&files->out_seg, (void *)files->out_val, Ri[0][0], Ri[0][1]);
+ files->out_val[1] = 0; /*candidate pixel flag, only one merge allowed per t iteration */
+
+
+ /* for each member of Ri and Rk, write new average bands values and segment values */
+ for (n = 0; n < Ri_count; n++) {
+ segment_put(&files->bands_seg, (void *)files->bands_val, Ri[n][0],
+ Ri[n][1]);
+ segment_put(&files->out_seg, (void *)files->out_val, Ri[n][0],
+ Ri[n][1]);
+ }
+ for (n = 0; n < Rk_count; n++) {
+ segment_put(&files->bands_seg, (void *)files->bands_val, Rk[n][0],
+ Rk[n][1]);
+ segment_put(&files->out_seg, (void *)files->out_val, Rk[n][0],
+ Rk[n][1]);
+ }
+
+ return 0;
+}
+
+/* TODO.. helper function, maybe make more general? */
+int set_candidate_flag(int Ri[100][2], int value, struct files *files)
+{
+ /* Ri is list of pixels, value is new value of flag */
+ int n;
+
+ /* TODO: Ri data structure... eventually just need to process all pixels in Ri. */
+ for (n = 0; n < 100; n++) {
+ segment_get(&files->out_seg, (void *)files->out_val, Ri[n][0], Ri[n][1]); /* this may change... */
+ files->out_val[1] = value; /*candidate pixel flag */
+ segment_put(&files->out_seg, (void *)files->out_val, Ri[n][0],
+ Ri[n][1]);
+
+ }
+ return 0;
+}
Modified: grass-addons/grass7/imagery/i.segment/iseg.h
===================================================================
--- grass-addons/grass7/imagery/i.segment/iseg.h 2012-06-09 17:42:15 UTC (rev 52018)
+++ grass-addons/grass7/imagery/i.segment/iseg.h 2012-06-10 05:04:16 UTC (rev 52019)
@@ -26,9 +26,13 @@
int nbands;
SEGMENT bands_seg, out_seg; /* bands is for input, normal application is landsat bands, but other input can be included in the group. */
double *bands_val; /* array, to hold all input values at one pixel */
+ double *second_val; /* to hold values at second point for similarity comparison */
int *out_val; /* array, to hold the segment ID and processing flag(s) */
char *out_name; /* name of output raster map */
+ /*int **no_check; *//* TODO maybe as SEGMENT. Also can this be smaller then an int? Just need to save 0 and 1. */
+ int no_check[100][2];
+
/* RASTER_MAP_TYPE data_type; Removed: input is always DCELL, output is CELL.
* TODO: if input might be smaller then DCELL, we could detect size and allocate accordingly. */
/*
@@ -61,12 +65,10 @@
struct functions
{
int method; /* Segmentation method */
- int (*find_pixel_neighbors) (int *[], int *[][]); /*pixel, pixel_neighbors *//*TODO need to define data types for these! */
+ int (*find_pixel_neighbors) (int[2], int[8][2], struct files *); /*pixel, pixel_neighbors */
+ double (*calculate_similarity) (int[2], int[2], struct files *,
+ struct functions *);
- /*based on options, such as diagonal neighbors, etc, some function pointers:
- * calc_simularity
- */
-
int num_pn; /* number of pixel neighbors int, 4 or 8. */
float threshold; /* similarity threshold */
@@ -84,8 +86,15 @@
int create_isegs(struct files *, struct functions *);
int io_debug(struct files *, struct functions *);
int region_growing(struct files *, struct functions *);
-int find_segment_neighbors(Ri, Rin); /* TODO: need data structure for Ri, Rin */
+int find_segment_neighbors(int[][2], int[][2], int, int, struct files *, struct functions *); /* TODO: need data structure for Ri, Rin */
+int set_candidate_flag(int[100][2], int, struct files *);
+int merge_values(int[100][2], int[100][2], int, int, struct files *); /* I assume this is a weighted mean? */
+int find_four_pixel_neighbors(int[2], int[][2], struct files *);
+int find_eight_pixel_neighbors(int[2], int[8][2], struct files *);
+double calculate_euclidean_similarity(int[2], int[2], struct files *,
+ struct functions *);
+
/* write_output.c */
/* also currently closes files */
int write_output(struct files *);
Modified: grass-addons/grass7/imagery/i.segment/outline
===================================================================
--- grass-addons/grass7/imagery/i.segment/outline 2012-06-09 17:42:15 UTC (rev 52018)
+++ grass-addons/grass7/imagery/i.segment/outline 2012-06-10 05:04:16 UTC (rev 52019)
@@ -209,16 +209,17 @@
While "to be checked" stack isn't empty:
pop
find pixel neighbors
- with neighbors
+ with pixel neighbors
if in "don't check" list
do nothing
else
put in "don't check" list
- add to "to be checked" stack
- if segment ID = current segment ID
- add to "current segment" list
- else
- add to "neighbor" list
+ if candidate pixel
+ if segment ID = current segment ID
+ add to "current segment" list
+ add to "to be checked" stack
+ else
+ add to "neighbor" list
next neighbor
loop...
Modified: grass-addons/grass7/imagery/i.segment/parse_args.c
===================================================================
--- grass-addons/grass7/imagery/i.segment/parse_args.c 2012-06-09 17:42:15 UTC (rev 52018)
+++ grass-addons/grass7/imagery/i.segment/parse_args.c 2012-06-10 05:04:16 UTC (rev 52019)
@@ -48,6 +48,8 @@
_("Use 8 neighbors (3x3 neighborhood) instead of the default 4 neighbors for each pixel.");
+ /* input for distance function */
+
if (G_parser(argc, argv))
exit(EXIT_FAILURE);
@@ -120,6 +122,9 @@
/* note from tutorial: You may have got to use the complete name of the member function
* including class-name and scope-operator (::).) */
+ /* TODO add user input for this */
+ functions->calculate_similarity = &calculate_euclidean_similarity;
+
/* other data */
files->nrows = Rast_window_rows();
files->ncols = Rast_window_cols();
Modified: grass-addons/grass7/imagery/i.segment/write_output.c
===================================================================
--- grass-addons/grass7/imagery/i.segment/write_output.c 2012-06-09 17:42:15 UTC (rev 52018)
+++ grass-addons/grass7/imagery/i.segment/write_output.c 2012-06-10 05:04:16 UTC (rev 52019)
@@ -9,7 +9,7 @@
int write_output(struct files *files)
{
- int out_fd, row, col;
+ int out_fd, row, col, n;
CELL *outbuf;
outbuf = Rast_allocate_c_buf(); /*hold one row of data to put into raster */
@@ -43,6 +43,10 @@
segment_close(&files->out_seg);
Rast_close(out_fd);
+ for (n = 0; n < files->nrows; n++)
+ G_free(files->no_check[n]);
+ G_free(files->no_check);
+
/* anything else left to clean up? */
return 0;
More information about the grass-commit
mailing list