[GRASS-SVN] r52318 - grass-addons/grass7/imagery/i.segment
svn_grass at osgeo.org
svn_grass at osgeo.org
Thu Jul 5 22:20:52 PDT 2012
Author: momsen
Date: 2012-07-05 22:20:52 -0700 (Thu, 05 Jul 2012)
New Revision: 52318
Modified:
grass-addons/grass7/imagery/i.segment/Makefile
grass-addons/grass7/imagery/i.segment/create_isegs.c
grass-addons/grass7/imagery/i.segment/iseg.h
grass-addons/grass7/imagery/i.segment/open_files.c
grass-addons/grass7/imagery/i.segment/parse_args.c
grass-addons/grass7/imagery/i.segment/times.txt
grass-addons/grass7/imagery/i.segment/write_output.c
Log:
BROKEN - added seg_time method to check timings of various structures.
Modified: grass-addons/grass7/imagery/i.segment/Makefile
===================================================================
--- grass-addons/grass7/imagery/i.segment/Makefile 2012-07-06 00:47:48 UTC (rev 52317)
+++ grass-addons/grass7/imagery/i.segment/Makefile 2012-07-06 05:20:52 UTC (rev 52318)
@@ -2,7 +2,7 @@
PGM = i.segment
-LIBES = $(IMAGERYLIB) $(RASTERLIB) $(SEGMENTLIB) $(GISLIB) $(LINKMLIB)
+LIBES = $(IMAGERYLIB) $(RASTERLIB) $(SEGMENTLIB) $(GISLIB) $(LINKMLIB) $(BTREE2LIB)
DEPENDENCIES = $(IMAGERYDEP) $(RASTERDEP) $(SEGMENTDEP) $(GISDEP) $(LINKMDEP)
include $(MODULE_TOPDIR)/include/Make/Module.make
Modified: grass-addons/grass7/imagery/i.segment/create_isegs.c
===================================================================
--- grass-addons/grass7/imagery/i.segment/create_isegs.c 2012-07-06 00:47:48 UTC (rev 52317)
+++ grass-addons/grass7/imagery/i.segment/create_isegs.c 2012-07-06 05:20:52 UTC (rev 52318)
@@ -10,8 +10,14 @@
#include <grass/raster.h>
#include <grass/segment.h> /* segmentation library */
#include <grass/linkm.h> /* memory manager for linked lists */
+#include <grass/rbtree.h> /* Red Black Tree library functions */
#include "iseg.h"
+#ifdef DEBUG
+ #include <time.h>
+ #include <stdbool.h> /* TODO decide if _bool is needed for FLAGs */
+#endif
+
#define LINKM
/* #define REVERSE */
@@ -50,6 +56,9 @@
}
else if (functions->method == 2)
successflag = ll_test(files, functions);
+
+ else if (functions->method == 3)
+ successflag = seg_speed_test(files, functions);
} /* end outer loop for processing polygons */
@@ -59,6 +68,7 @@
return successflag;
}
+#ifdef DEBUG
/* writes row+col to the output raster. Also using for the linkm speed test. */
int io_debug(struct files *files, struct functions *functions)
{
@@ -282,6 +292,188 @@
}
+int seg_speed_test(struct files *files, struct functions *functions)
+{
+ int i, j, n, max;
+ clock_t start, end;
+ double temp, cpu_time_used;
+ int (*get) (struct files *, int, int); /* files, row, col */
+ struct RB_TREE *no_check_tree;
+ struct RB_TRAV trav;
+ struct pixels *to_check, *newpixel, *current;
+ G_message("checking speed of RAM vs SEG vs get function performance");
+
+ G_message("Access in the same region, so shouldn't have any disk I/O");
+
+ max = 100000000;
+ G_message("repeating everything %d times.", max);
+
+ { /* Array vs. SEG ... when working in local area */
+ start = clock();
+ for (i=0; i<max; i++){
+ segment_get(&files->bands_seg, (void *)files->bands_val, 12, 12);
+ temp = files->bands_val[0];
+ }
+ end = clock();
+ cpu_time_used = ((double) (end - start)) / CLOCKS_PER_SEC;
+ G_message("Using SEG: %g", cpu_time_used);
+
+ start = clock();
+ for (i=0; i<max; i++){
+ temp = files->iseg[12][12];
+ }
+ end = clock();
+ cpu_time_used = ((double) (end - start)) / CLOCKS_PER_SEC;
+ G_message("Using array in RAM: %g", cpu_time_used);
+
+ get = &get_segID_SEG;
+
+ start = clock();
+ for (i=0; i<max; i++){
+ temp = get(files, 12, 12);
+ }
+ end = clock();
+ cpu_time_used = ((double) (end - start)) / CLOCKS_PER_SEC;
+ G_message("Using SEG w/ get(): %g", cpu_time_used);
+
+ get = &get_segID_RAM;
+
+ start = clock();
+ for (i=0; i<max; i++){
+ temp = get(files, 12, 12);
+ }
+ end = clock();
+ cpu_time_used = ((double) (end - start)) / CLOCKS_PER_SEC;
+ G_message("Using RAM w/ get(): %g", cpu_time_used);
+ }
+
+ G_message("to check storage requirements... system dependent... :");
+ G_message("unsigned char: %lu", sizeof(unsigned char));
+ G_message("unsigned char pointer: %lu", sizeof(unsigned char *));
+ G_message("_Bool: %lu", sizeof(_Bool));
+ G_message("int: %lu", sizeof(int));
+ G_message("unsigned int: %lu", sizeof(unsigned int));
+ G_message("double: %lu", sizeof(double));
+
+
+ max = 100000;
+ G_message("repeating everything %d times.", max);
+
+ { /* compare rbtree with linked list */
+ //~ no_check_tree = rbtree_create(compare_ids, sizeof(int));
+ //~ rbtree_init_trav(&trav, no_check_tree);
+ n = 100;
+ start = clock();
+ for (i=0; i<max; i++){
+ no_check_tree = rbtree_create(compare_ids, sizeof(int));
+ rbtree_init_trav(&trav, no_check_tree);
+
+ /*build*/
+ for(j=0; j<n; j++){
+ rbtree_insert(no_check_tree, &j);
+ }
+ //~ /*access*/
+ //~ while ((data = rbtree_traverse(&trav)) != NULL) {
+ //~ if (my_compare_fn(data, threshold_data) == 0) break;
+ //~ G_message("%d", data);
+ //~ }
+ /*free memory*/
+ rbtree_destroy(no_check_tree);
+ }
+ end = clock();
+ cpu_time_used = ((double) (end - start)) / CLOCKS_PER_SEC;
+ G_message("Using rbtree (just build/destroy), %d elements, time: %g", n, cpu_time_used);
+
+ to_check = NULL;
+
+ start = clock();
+ for (i=0; i<max; i++){
+ /*build*/
+ for(j=0; j<n; j++){
+ newpixel = (struct pixels *)link_new(files->token);
+ newpixel->next = to_check; /*point the new pixel to the current first pixel */
+ newpixel->row = j;
+ newpixel->col = i;
+ to_check = newpixel; /*change the first pixel to be the new pixel. */
+ }
+ /*access*/
+ for (current = to_check; current != NULL; current = current->next) { /* for each of Ri's neighbors */
+ temp = current->row;
+ }
+ /*free memory*/
+ my_dispose_list(files->token, &to_check);
+
+ }
+ end = clock();
+ cpu_time_used = ((double) (end - start)) / CLOCKS_PER_SEC;
+ G_message("Using linked list and linkm (build/access/free), %d elements, time: %g", n, cpu_time_used);
+
+
+ n=1000;
+ //repeat for both with larger membership
+
+ start = clock();
+ for (i=0; i<max; i++){
+ no_check_tree = rbtree_create(compare_ids, sizeof(int));
+ rbtree_init_trav(&trav, no_check_tree);
+
+ /*build*/
+ for(j=0; j<n; j++){
+ rbtree_insert(no_check_tree, &j);
+ }
+ //~ /*access*/
+ //~ while ((data = rbtree_traverse(&trav)) != NULL) {
+ //~ if (my_compare_fn(data, threshold_data) == 0) break;
+ //~ G_message("%d", data);
+ //~ }
+ /*free memory*/
+ rbtree_destroy(no_check_tree);
+ }
+ end = clock();
+ cpu_time_used = ((double) (end - start)) / CLOCKS_PER_SEC;
+ G_message("Using rbtree, %d elements, time: %g", n, cpu_time_used);
+
+ to_check = NULL;
+
+ start = clock();
+ for (i=0; i<max; i++){
+ /*build*/
+ for(j=0; j<n; j++){
+ newpixel = (struct pixels *)link_new(files->token);
+ newpixel->next = to_check; /*point the new pixel to the current first pixel */
+ newpixel->row = j;
+ newpixel->col = i;
+ to_check = newpixel; /*change the first pixel to be the new pixel. */
+ }
+ /*access*/
+ for (current = to_check; current != NULL; current = current->next) { /* for each of Ri's neighbors */
+ temp = current->row;
+ }
+ /*free memory*/
+ my_dispose_list(files->token, &to_check);
+
+ }
+ end = clock();
+ cpu_time_used = ((double) (end - start)) / CLOCKS_PER_SEC;
+ G_message("Using linked list and linkm, %d elements, time: %g", n, cpu_time_used);
+
+}
+
+ return TRUE;
+}
+
+int get_segID_SEG(struct files *files, int row, int col)
+{
+ segment_get(&files->bands_seg, (void *)files->bands_val, row, col);
+ return files->bands_val[0]; /*todo for accurate comparison, is converting double to int a time penalty? */
+}
+
+int get_segID_RAM(struct files *files, int row, int col)
+{
+ return files->iseg[row][col];
+}
+#endif
+
int region_growing(struct files *files, struct functions *functions)
{
int row, col, t;
@@ -423,6 +615,7 @@
current->col);
G_debug(4, "also passing Ri_count: %d", Ri_count);
*/
+
/* find segment neighbors */
if (find_segment_neighbors
(&Ri_head, &Rin_head, &Ri_count, files,
@@ -442,19 +635,21 @@
else { /*found neighbors, go ahead until find mutually agreeing neighbors */
G_debug(4, "2b, Found Ri's pixels");
+ #ifdef DEBUG
/*print out neighbors */
-
for (current = Ri_head; current != NULL;
current = current->next)
G_debug(4, "Ri: row: %d, col: %d", current->row,
current->col);
-
+ #endif
G_debug(4, "2b, Found Ri's neighbors");
+ #ifdef DEBUG
/*print out neighbors */
for (current = Rin_head; current != NULL;
current = current->next)
G_debug(4, "Rin: row: %d, col: %d", current->row,
current->col);
+ #endif
/* find Ri's most similar neighbor */
Ri_bestn = NULL;
@@ -518,19 +713,22 @@
find_segment_neighbors(&Rk_head, &Rkn_head, &Rk_count, files, functions); /* data structure for Rk's neighbors, and pixels in Rk if we don't already have it */
G_debug(4, "Found Rk's pixels");
+ #ifdef DEBUG
/*print out neighbors */
for (current = Rk_head; current != NULL;
current = current->next)
G_debug(4, "Rk: row: %d, col: %d",
current->row, current->col);
-
+ #endif
G_debug(4, "Found Rk's neighbors");
+ #ifdef DEBUG
/*print out neighbors */
for (current = Rkn_head; current != NULL;
current = current->next)
G_debug(4, "Rkn: row: %d, col: %d",
current->row, current->col);
-
+ #endif
+
/*find Rk's most similar neighbor */
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_head->row, Rk_head->col); /* current segment values */
@@ -608,11 +806,14 @@
}
while (t <= functions->end_t && endflag == FALSE) ;
/*end t loop *//*TODO, should there be a max t that it can iterate for? Include t in G_message? */
- if(endflag == FALSE) G_warning(_("Merging processes stopped due to reaching max iteration limit, more merges may be possible"));
+ if(endflag == FALSE) G_message(_("Merging processes stopped due to reaching max iteration limit, more merges may be possible"));
+
/* ****************************************************************************************** */
/* final pass, ignore threshold and force a merge for small segments with their best neighbor */
+ /* ****************************************************************************************** */
+
if (functions->min_segment_size > 1) {
G_verbose_message("Final iteration, force merges for small segments.");
@@ -703,21 +904,22 @@
else /* Merge with most similar neighbor */
{
- G_debug(4, "2b, Found Ri's pixels");
-
- /*print out neighbors */
- for (current = Ri_head; current != NULL;
- current = current->next)
- G_debug(4, "Ri: row: %d, col: %d", current->row,
- current->col);
+ //~ TODO DELETE?
+ //~ G_debug(4, "2b, Found Ri's pixels");
+ //~
+ //~ /*print out neighbors */
+ //~ for (current = Ri_head; current != NULL;
+ //~ current = current->next)
+ //~ G_debug(4, "Ri: row: %d, col: %d", current->row,
+ //~ current->col);
+//~
+ //~ G_debug(4, "2b, Found Ri's neighbors");
+ //~ /*print out neighbors */
+ //~ for (current = Rin_head; current != NULL;
+ //~ current = current->next)
+ //~ G_debug(4, "Rin: row: %d, col: %d", current->row,
+ //~ current->col);
- G_debug(4, "2b, Found Ri's neighbors");
- /*print out neighbors */
- for (current = Rin_head; current != NULL;
- current = current->next)
- G_debug(4, "Rin: row: %d, col: %d", current->row,
- current->col);
-
/* find Ri's most similar neighbor */
Ri_bestn = NULL;
Ri_similarity = LDBL_MAX; /* set current similarity to max value */
@@ -765,20 +967,21 @@
/* using this just to get the full pixel/cell membership list for Rk */
find_segment_neighbors(&Rk_head, &Rkn_head, &Rk_count, files, functions); /* data structure for Rk's neighbors, and pixels in Rk if we don't already have it */
- G_debug(4, "Found Rk's pixels");
- /*print out neighbors */
- for (current = Rk_head; current != NULL;
- current = current->next)
- G_debug(4, "Rk: row: %d, col: %d",
- current->row, current->col);
+//~ TODO DELETE?
+ //~ G_debug(4, "Found Rk's pixels");
+ //~ /*print out neighbors */
+ //~ for (current = Rk_head; current != NULL;
+ //~ current = current->next)
+ //~ G_debug(4, "Rk: row: %d, col: %d",
+ //~ current->row, current->col);
+//~
+ //~ G_debug(4, "Found Rk's neighbors");
+ //~ /*print out neighbors */
+ //~ for (current = Rkn_head; current != NULL;
+ //~ current = current->next)
+ //~ G_debug(4, "Rkn: row: %d, col: %d",
+ //~ current->row, current->col);
- G_debug(4, "Found Rk's neighbors");
- /*print out neighbors */
- for (current = Rkn_head; current != NULL;
- current = current->next)
- G_debug(4, "Rkn: row: %d, col: %d",
- current->row, current->col);
-
merge_values(Ri_head, Rk_head, Ri_count, Rk_count, files); /* TODO error trap */
/* merge_values sets Ri and Rk candidate flag to FALSE. Put Rk back to TRUE if the size is too small. */
@@ -791,16 +994,17 @@
} /* end else - pixel count was below minimum allowed */
} /* end if neighbors found */
- else
- G_warning("no neighbors found, this should NOT happen on merge step.");
-
+ else{ /* no neighbors were found */
+ G_warning("no neighbors found, this means only one segment was created.");
+ set_candidate_flag(Ri_head, FALSE, files);
+ }
} /*end if pixel is candidate pixel */
} /*next column */
- G_percent(row, files->nrows, 1);
+ G_percent(row, files->nrows-1, 1);
} /*next row */
} /* end if for force merge */
else
- G_verbose_message(_("Minimum pixels for group was set to 1, no final forced merge iteration for small segments."));
+ G_message(_("Input for minimum pixels in a segment was 1, skipping final iteration for joining small segments."));
/* free memory *//*TODO: anything ? */
@@ -813,11 +1017,18 @@
struct files *files,
struct functions *functions)
{
- int n, Ri_seg_ID = -1;
+ int n, current_seg_ID, Ri_seg_ID = -1;
struct pixels *newpixel, *current, *to_check; /* need to check the pixel neighbors of to_check */
int pixel_neighbors[8][2]; /* TODO: data type? put in files to allocate memory once? */
+
+//TODO remove... /* files->no_check is a FLAG structure, only used here but allocating memory in open_files */
+ struct RB_TREE *no_check_tree; /* SEGMENT ID that should no longer be checked on this current find_neighbors() run */
- /* files->no_check is a FLAG structure, only used here but allocating memory in open_files */
+#ifdef DEBUG
+ struct RB_TRAV trav;
+#endif
+
+ /* TODO, any time savings to move any variables to files (mem allocation in open_files) */
/* 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?
@@ -827,7 +1038,6 @@
/* parameter: R, current segment membership, could be single pixel or list of pixels.
* parameter: neighbors/Rin/Rik, neighbor pixels, could have a list already, or could be empty ?
* files->out_seg is currently an array [0] for seg ID and [1] for "candidate pixel"
- * files->no_check is a segmentation data structure, if the pixel should no longer be checked on this current find_neighbors() run
* functions->num_pn int, 4 or 8, for number of pixel neighbors
* */
@@ -839,17 +1049,19 @@
G_debug(5, "neig: row: %d, col: %d", current->row, current->col);
G_debug(5, "also passing Ri_count: %d", *seg_count); */
- /*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 */
- /*todo, dlete this loop for (n = 0; n < files->nrows; n++) {
- for (m = 0; m < files->ncols; m++) {
- val_no_check = FALSE;
- segment_put(&files->no_check, &val_no_check, n, m);
- }
- } */
- flag_clear_all(files->no_check);
-
+ /* *** initialize data *** */
+
+ /* get Ri's segment ID */
+ Ri_seg_ID = files->iseg[(*R_head)->row][(*R_head)->col]; /* old data structure needed, this... keep for readability? */
+
+// flag_clear_all(files->no_check);
+ no_check_tree = rbtree_create(compare_ids, sizeof(int));
to_check = NULL;
+#ifdef DEBUG
+ rbtree_init_trav(&trav, no_check_tree);
+#endif
+
/* Copy R in to_check and no_check data structures (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 */
@@ -860,15 +1072,22 @@
newpixel->row = current->row;
newpixel->col = current->col;
to_check = newpixel; /*change the first pixel to be the new pixel. */
-
- flag_set(files->no_check, current->row, current->col);
+//todo delete flag_set(files->no_check, current->row, current->col);
}
+//~ G_message("starting to insert dummy no_check values");
+//~ current_seg_ID = -5;
+//~ rbtree_insert(no_check_tree, ¤t_seg_ID);
+//~ G_message("inserted -5");
+//~ current_seg_ID = -10;
+//~ rbtree_insert(no_check_tree, ¤t_seg_ID);
+//~ G_message("inserted -10");
+
+ rbtree_insert(no_check_tree, &Ri_seg_ID);
+ G_debug(5, "inserted Ri_seg_ID number %d into RBtree.", Ri_seg_ID);
+
/* empty "neighbor" list Note: this step is in pseudo code, but think we just pass in Rin - it was already initialized, and later could have Ri data available to start from */
- /* get Ri's segment ID */
- Ri_seg_ID = files->iseg[(*R_head)->row][(*R_head)->col]; /* old data structure needed, this... keep for readability? */
-
while (to_check != NULL) { /* removing from to_check list as we go, NOT iterating over the list. */
G_debug(5,
"\tfind_pixel_neighbors for row: %d , col %d",
@@ -885,6 +1104,7 @@
link_dispose(files->token, (VOID_T *) current);
/*print out to_check */
+ #ifdef DEBUG
G_debug(5, "remaining pixel's in to_check, after popping:");
for (current = to_check; current != NULL; current = current->next)
G_debug(5, "to_check... row: %d, col: %d", current->row,
@@ -893,7 +1113,8 @@
current = current->next)
G_debug(5, "Rn... row: %d, col: %d", current->row,
current->col);
-
+ #endif
+
/*now check the pixel neighbors and add to the lists */
/*debug what neighbors were found: */
@@ -903,14 +1124,40 @@
for (n = 0; n < functions->num_pn; n++) { /* with pixel neighbors */
- G_debug(5,
- "\twith pixel neigh %d, row: %d col: %d, val_no_check = %d",
- n, pixel_neighbors[n][0], pixel_neighbors[n][1],
- flag_get(files->no_check, pixel_neighbors[n][0],
- pixel_neighbors[n][1]));
- if (flag_get(files->no_check, pixel_neighbors[n][0], pixel_neighbors[n][1]) == FALSE) { /* want to check this neighbor */
- flag_set(files->no_check, pixel_neighbors[n][0], pixel_neighbors[n][1]); /* don't check it again */
+ //~TODO delete G_debug(5,
+ //~ "\twith pixel neigh %d, row: %d col: %d, val_no_check = %d",
+ //~ n, pixel_neighbors[n][0], pixel_neighbors[n][1],
+ //~ flag_get(files->no_check, pixel_neighbors[n][0],
+ //~ pixel_neighbors[n][1]));
+ // TODO delete if (flag_get(files->no_check, pixel_neighbors[n][0], pixel_neighbors[n][1]) == FALSE)
+ current_seg_ID = files->iseg[pixel_neighbors[n][0]][pixel_neighbors[n][1]];
+ G_debug(5, "\tcurrent_seg_ID = %d", current_seg_ID);
+ G_debug(5, "********* rbtree_find(no_check_tree, ¤t_seg_ID) = %p", rbtree_find(no_check_tree, ¤t_seg_ID));
+ G_debug(5, "if evaluation: %d", rbtree_find(no_check_tree, ¤t_seg_ID) == FALSE);
+/* ######################
+ * bad logic... previously, was tracking no_check pixels
+ * want to get both neighbors AND membership of R
+ * Changing to no_check saving the segment ID's - need someway to find membership!
+ *
+ * do speed check on Rbtree vs. linked list membership list???
+ *
+ * A. revert to saving no_check pixels. could still use tree for no_check pixels,
+ * compare function could use row then col.
+ * Could have RBtree to save unique segment id's as well, so neighbor list could be reduced as well.
+ * return membership and neighbors would still be lists.
+ *
+ * B. save membership pixels in a tree. So with each new pixel to check:
+ * if current seg ID equals R_segID && can't find it in the tree, then add it to membership tree
+ * else if current seg ID is not in neighbor tree, then add it to neighbor list
+ * with B, would it be worth changing the neighbor list to a tree?
+ * */
+
+
+ if(rbtree_find(no_check_tree, ¤t_seg_ID) == FALSE) { /* want to check this neighbor */
+ if(rbtree_insert(no_check_tree, ¤t_seg_ID)==0) /* don't check it again */
+ G_warning("could not insert data!?");
+
if (!(FLAG_GET(files->null_flag, pixel_neighbors[n][0], pixel_neighbors[n][1]))) { /* all pixels, not just valid pixels */
G_debug(5, "\tfiles->iseg[][] = %d Ri_seg_ID = %d",
@@ -960,19 +1207,31 @@
} /*end if for pixel_neighbor was in "don't check" list */
} /* end for loop - next pixel neighbor */
+ #ifdef DEBUG
G_debug(5,
"remaining pixel's in to_check, after processing the last pixel's neighbors:");
for (current = to_check; current != NULL; current = current->next)
- G_debug(5, "to_check... row: %d, col: %d", current->row,
- current->col);
+ G_debug(5, "to_check... row: %d, col: %d", current->row,
+ current->col);
+
+ /* todo? just to see if it worked? G_message("no_check segment ID's: hmm, how implement?"); */
+/*
+ while ((data = rbtree_traverse(&trav)) != NULL) {
+ if (my_compare_fn(data, threshold_data) == 0) break;
+ G_message("%d", data);
+ }
+*/
G_debug(5, "\t### end of pixel neighors");
+ #endif
} /* while to_check has more elements */
+ /* TODO - anything to free??? */
+ /* clean up */
+ rbtree_destroy(no_check_tree);
+
return TRUE;
}
-
-
int find_four_pixel_neighbors(int p_row, int p_col,
int pixel_neighbors[8][2],
struct files *files)
@@ -1146,3 +1405,26 @@
return TRUE;
}
+
+/* function used by binary tree to compare items */
+/* TODO, I don't understand the purpose of all this C syntax...will this give me just a simple numeric comparison??? */
+
+/* TODO
+ * "static" was used in break_polygons.c extern was suggested in docs. */
+
+int compare_ids(const void *first, const void *second)
+{
+ int *a = (int *)first, *b = (int *)second;
+
+ if (*a < *b)
+ return -1;
+ else if (*a > *b)
+ return 1;
+ else if (*a == *b)
+ return 0;
+
+
+ G_warning(_("find neighbors: Bug in binary tree!"));
+ return 1;
+
+}
Modified: grass-addons/grass7/imagery/i.segment/iseg.h
===================================================================
--- grass-addons/grass7/imagery/i.segment/iseg.h 2012-07-06 00:47:48 UTC (rev 52317)
+++ grass-addons/grass7/imagery/i.segment/iseg.h 2012-07-06 05:20:52 UTC (rev 52318)
@@ -16,6 +16,8 @@
#include <grass/linkm.h>
#include "flag.h"
+#define DEBUG
+
/* pixel stack */
struct pixels
{
@@ -52,7 +54,7 @@
/* processing flags */
FLAG *candidate_flag, *null_flag; /*TODO, need some way to remember MASK/NULL values. Was using -1, 0, 1 in int array. Better to use 2 FLAG structures, better readibility? */
- FLAG *no_check; /* pixels that have already been checked during this neighbor finding routine */
+// FLAG *no_check; /* pixels that have already been checked during this neighbor finding routine */
/* memory management, linked lists */
struct link_head *token; /* for linkm linked list memory management. */
@@ -109,6 +111,9 @@
int io_debug(struct files *, struct functions *);
int ll_test(struct files *, struct functions *);
int test_pass_token(struct pixels **, struct files *);
+int seg_speed_test(struct files *, struct functions *);
+int get_segID_SEG(struct files *, int, int);
+int get_segID_RAM(struct files *, int, int);
int region_growing(struct files *, struct functions *);
int find_segment_neighbors(struct pixels **, struct pixels **, int *,
struct files *, struct functions *);
@@ -119,6 +124,7 @@
double calculate_euclidean_similarity(struct pixels *, struct pixels *,
struct files *, struct functions *);
int my_dispose_list(struct link_head *, struct pixels **);
+int compare_ids(const void *, const void *);
/* write_output.c */
int write_output(struct files *);
Modified: grass-addons/grass7/imagery/i.segment/open_files.c
===================================================================
--- grass-addons/grass7/imagery/i.segment/open_files.c 2012-07-06 00:47:48 UTC (rev 52317)
+++ grass-addons/grass7/imagery/i.segment/open_files.c 2012-07-06 05:20:52 UTC (rev 52318)
@@ -20,7 +20,7 @@
/*allocate memory for flags */
files->null_flag = flag_create(files->nrows, files->ncols);
files->candidate_flag = flag_create(files->nrows, files->ncols);
- files->no_check = flag_create(files->nrows, files->ncols);
+// files->no_check = flag_create(files->nrows, files->ncols);
G_debug(1, "Checking image group...");
/* references: i.cost r.watershed/seg and http://grass.osgeo.org/programming7/segmentlib.html */
Modified: grass-addons/grass7/imagery/i.segment/parse_args.c
===================================================================
--- grass-addons/grass7/imagery/i.segment/parse_args.c 2012-07-06 00:47:48 UTC (rev 52317)
+++ grass-addons/grass7/imagery/i.segment/parse_args.c 2012-07-06 05:20:52 UTC (rev 52318)
@@ -33,14 +33,18 @@
method->type = TYPE_STRING;
method->required = YES;
method->answer = "region_growing";
- method->options = "region_growing, io_debug, ll_test"; /* TODO at end, remove these from list: io_debug just writes row+col to each output pixel, ll_test for testing linked list data structure */
+ #ifdef DEBUG
+ method->options = "region_growing, io_debug, ll_test, seg_time";
+ #else
+ method->options = "region_growing";
+ #endif
method->description = _("Segmentation method.");
min_segment_size = G_define_option();
min_segment_size->key = "min"; /*TODO is there a preference for long or short key names? min is pretty generic...but short... */
min_segment_size->type = TYPE_INTEGER;
min_segment_size->required = YES;
- min_segment_size->answer = "10"; /* TODO, should a "typical" default be provided? */
+ min_segment_size->answer = "1"; /* TODO, should a "typical" default be provided? */
min_segment_size->options = "1-100000"; /*must be positive number, is >0 allowed in "options" or is 100,000 suitably large? */
min_segment_size->description = _("Minimum number of pixels (cells) in a segment. The final merge step will ignore the threshold for any segments with fewer pixels.");
@@ -126,6 +130,8 @@
functions->method = 1;
else if (strncmp(method->answer, "ll_test", 5) == 0)
functions->method = 2;
+ else if (strncmp(method->answer, "seg_time", 5) == 0)
+ functions->method = 3;
else
G_fatal_error("Couldn't assign segmentation method."); /*shouldn't be able to get here */
Modified: grass-addons/grass7/imagery/i.segment/times.txt
===================================================================
--- grass-addons/grass7/imagery/i.segment/times.txt 2012-07-06 00:47:48 UTC (rev 52317)
+++ grass-addons/grass7/imagery/i.segment/times.txt 2012-07-06 05:20:52 UTC (rev 52318)
@@ -1,3 +1,34 @@
+Segment ID storage - RAM vs SEG and speed access.
+
+i.segment -w --overwrite --verbose group=landsat_1band at samples output=temp threshold=5 method=seg_time min=1
+
+checking speed of RAM vs SEG vs get function performance
+Access in the same region, so shouldn't have any disk I/O
+repeating everything 100000000 times.
+Using SEG: 2.63
+Using array in RAM: 0.25
+Using SEG w/ get(): 3.27
+Using RAM w/ get(): 0.68
+to check storage requirements... system dependent... :
+unsigned char: 1
+unsigned char pointer: 8
+_Bool: 1
+int: 4
+unsigned int: 4
+double: 8
+repeating everything 100000 times.
+Using rbtree (just build/destroy), 100 elements, time: 3.94
+Using linked list and linkm (build/access/free), 100 elements, time: 0.3
+Using rbtree, 1000 elements, time: 51.03
+Using linked list and linkm, 1000 elements, time: 3.21
+
+
+Storage requirement:
+
+100,000,000 pixels
+
+
+#######################################################################################
NC sample landsat images, lsat7_2000_10
g.region rast=lsat7_2000_10 at landsat
Modified: grass-addons/grass7/imagery/i.segment/write_output.c
===================================================================
--- grass-addons/grass7/imagery/i.segment/write_output.c 2012-07-06 00:47:48 UTC (rev 52317)
+++ grass-addons/grass7/imagery/i.segment/write_output.c 2012-07-06 05:20:52 UTC (rev 52318)
@@ -97,7 +97,7 @@
flag_destroy(files->null_flag);
flag_destroy(files->candidate_flag);
- flag_destroy(files->no_check);
+// flag_destroy(files->no_check);
G_debug(1, "close_files() before link_cleanup()");
link_cleanup(files->token);
G_debug(1, "close_files() after link_cleanup()");
More information about the grass-commit
mailing list