[GRASS-SVN] r52622 - grass-addons/grass7/imagery/i.segment
svn_grass at osgeo.org
svn_grass at osgeo.org
Fri Aug 10 09:12:42 PDT 2012
Author: momsen
Date: 2012-08-10 09:12:42 -0700 (Fri, 10 Aug 2012)
New Revision: 52622
Modified:
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
Log:
started adding calculations for the perimeter.
Modified: grass-addons/grass7/imagery/i.segment/create_isegs.c
===================================================================
--- grass-addons/grass7/imagery/i.segment/create_isegs.c 2012-08-10 14:48:01 UTC (rev 52621)
+++ grass-addons/grass7/imagery/i.segment/create_isegs.c 2012-08-10 16:12:42 UTC (rev 52622)
@@ -924,11 +924,14 @@
#ifdef PROFILE
fn_start = clock();
#endif
- if (find_segment_neighbors
+ //~ if (find_segment_neighbors
+ //~ (&Ri_head, &Rin_head, &Ri_count, files,
+ //~ functions) != TRUE) {
+ //~ G_fatal_error("find_segment_neighbors() failed");
+ //~ }
+ find_segment_neighbors
(&Ri_head, &Rin_head, &Ri_count, files,
- functions) != TRUE) {
- G_fatal_error("find_segment_neighbors() failed");
- }
+ functions);
#ifdef PROFILE
fn_end = clock();
fn_lap =
@@ -1235,12 +1238,15 @@
Ri_head->row, Ri_head->col);
/* find segment neighbors */
- if (find_segment_neighbors
+ //~ if (find_segment_neighbors
+ //~ (&Ri_head, &Rin_head, &Ri_count, files,
+ //~ functions) != TRUE) {
+ //~ G_fatal_error("find_segment_neighbors() failed");
+ //~ }
+find_segment_neighbors
(&Ri_head, &Rin_head, &Ri_count, files,
- functions) != TRUE) {
- G_fatal_error("find_segment_neighbors() failed");
- }
-
+ functions);
+
if (Rin_head != NULL) { /*found neighbors */
if (Ri_count >= functions->min_segment_size) /* don't force a merge */
set_candidate_flag(Ri_head, FALSE, files);
@@ -1329,12 +1335,14 @@
return TRUE;
}
+/* TODO, for now will return borderPixels instead of passing a pointer, I saw mentioned that each parameter slows down the function call? */
+/* TODO, My first impression is that the borderPixels count is ONLY needed for the case of initial seeds, and not used later on. Another reason to split the function... */
int find_segment_neighbors(struct pixels **R_head,
struct pixels **neighbors_head, int *seg_count,
struct files *files,
struct functions *functions)
{
- int n, current_seg_ID, R_iseg = -1;
+ int n, borderPixels, current_seg_ID, R_iseg = -1;
struct pixels *newpixel, *current, *to_check, tree_pix; /* need to check the pixel neighbors of to_check */
int pixel_neighbors[8][2];
struct RB_TREE *no_check_tree; /* pixels that should no longer be checked on this current find_neighbors() run */
@@ -1362,7 +1370,8 @@
/* *** initialize data *** */
-
+ borderPixels = 0;
+
segment_get(&files->iseg_seg, &R_iseg, (*R_head)->row,
(*R_head)->col);
@@ -1393,6 +1402,7 @@
*neighbors_head = newpixel; /*change the first pixel to be the new pixel. */
/* todo polish... could use a tree and only return pixels from unique segments. */
}
+ borderPixels++; /* increment for all non null pixels TODO perimeter: OK to ignore these cells? */
}
}
@@ -1506,7 +1516,9 @@
}
else { /* segment id's were different */
- if (!rbtree_find(known_iseg, ¤t_seg_ID)) { /* we don't have any neighbors yet from this segment */
+ borderPixels++; /* increment for all non null pixels that are non in no-check or R_iseg TODO perimeter: move this to include pixels in no-check ??? */
+
+ if (!rbtree_find(known_iseg, ¤t_seg_ID)) { /* we don't have any neighbors yet from this segment */
if (current_seg_ID != 0)
/* with seeds, non seed pixels are defaulted to zero. Should we use null instead?? then could skip this check? Or we couldn't insert it??? */
/* add to known neighbors list */
@@ -1523,6 +1535,11 @@
newpixel->col = pixel_neighbors[n][1];
*neighbors_head = newpixel; /*change the first pixel to be the new pixel. */
}
+ else { /* TODO we need to keep track of (and return!) a total count of neighbors pixels for each neighbor segment, to update the perimeter value in the similarity calculation. */
+ /* todo perimeter: need to initalize this somewhere!!! */
+ /* todo perimeter... need to find pixel with same segment ID.... countShared++;
+ * Oh! Should we change the tree to sort on segment ID...need to think of fast way to return this count? with pixel? or with something else? */
+ }
}
@@ -1545,7 +1562,7 @@
rbtree_destroy(no_check_tree);
rbtree_destroy(known_iseg);
}
- return TRUE;
+ return borderPixels;
}
int find_four_pixel_neighbors(int p_row, int p_col,
@@ -1656,7 +1673,8 @@
}
- /*
+ /* TODO: add shape parameter...
+ *
In the eCognition literature, we find that the key factor in the
multi-scale segmentation algorithm used by Definiens is the scale
factor f:
@@ -1731,7 +1749,7 @@
}
/* calculates and stores the mean value for all pixels in a list, assuming they are all in the same segment */
- int merge_pixels(struct pixels *R_head, struct files *files)
+ int merge_pixels(struct pixels *R_head, int borderPixels, struct files *files)
{
int n, count = 0;
struct pixels *current;
@@ -1759,6 +1777,10 @@
files->second_val[n] = files->second_val[n] / count;
}
+ /* add in the shape values */
+ files->bands_val[files->nbands] = count; /* area (Num Pixels) */
+ files->bands_val[files->nbands + 1] = borderPixels; /* Perimeter Length */ /* todo polish, not exact for edges...close enough for now? */
+
/* save the results */
for (current = R_head; current != NULL; current = current->next) {
segment_put(&files->bands_seg, (void *)files->second_val,
Modified: grass-addons/grass7/imagery/i.segment/iseg.h
===================================================================
--- grass-addons/grass7/imagery/i.segment/iseg.h 2012-08-10 14:48:01 UTC (rev 52621)
+++ grass-addons/grass7/imagery/i.segment/iseg.h 2012-08-10 16:12:42 UTC (rev 52622)
@@ -29,6 +29,7 @@
struct pixels *next;
int row;
int col;
+ int countShared; /* todo perimeter: will hold the count how many pixels are shared on the Border Between Ri and Rk. Not used for all pixels... see if this is an OK way to do this...*/
};
/* input and output files, as well as some other processing info */
@@ -116,7 +117,7 @@
struct files *, struct functions *);
int set_candidate_flag(struct pixels *, int, struct files *);
int merge_values(struct pixels *, struct pixels *, int, int, struct files *);
-int merge_pixels(struct pixels *, struct files *);
+int merge_pixels(struct pixels *, int, struct files *);
int find_four_pixel_neighbors(int, int, int[][2], struct files *);
int find_eight_pixel_neighbors(int, int, int[8][2], struct files *);
double calculate_euclidean_similarity(struct pixels *, struct pixels *,
Modified: grass-addons/grass7/imagery/i.segment/open_files.c
===================================================================
--- grass-addons/grass7/imagery/i.segment/open_files.c 2012-08-10 14:48:01 UTC (rev 52621)
+++ grass-addons/grass7/imagery/i.segment/open_files.c 2012-08-10 16:12:42 UTC (rev 52622)
@@ -11,7 +11,7 @@
{
struct Ref Ref; /* group reference list */
int *in_fd, seeds_fd, bounds_fd, null_check, out_fd, mean_fd;
- int n, s, row, col, srows, scols, inlen, nseg;
+ int n, s, row, col, srows, scols, inlen, nseg, borderPixels;
DCELL **inbuf; /* buffer array, to store lines from each of the imagery group rasters */
CELL *boundsbuf;
void *seedsbuf, *ptr; /* todo. correct data type when allowing any data type? hmm, since have changed logic, seeds must be CELL. Could update code. */
@@ -134,6 +134,10 @@
G_fatal_error("Unable to create input temporary files");
/* ******* remaining memory allocation ********* */
+
+ /* save the area and perimeter as well */
+ /* TODO: currently saving this with the input DCELL values. Better to have a second segment structure to save as integers ??? */
+ inlen = inlen + sizeof(double) * 2;
files->bands_val = (double *)G_malloc(inlen);
files->second_val = (double *)G_malloc(inlen);
@@ -196,6 +200,8 @@
else
files->bands_val[n] = (inbuf[n][col] - min[n]) / (max[n] - min[n]); /*scaled version */
}
+ files->bands_val[Ref.nfiles] = 1; /* area (Num Pixels) */
+ files->bands_val[Ref.nfiles + 1] = 4; /* Perimeter Length */ /* todo polish, not exact for edges...close enough for now? */
segment_put(&files->bands_seg, (void *)files->bands_val, row, col); /* store input bands */
if (null_check != -1) { /*good pixel */
@@ -273,8 +279,8 @@
newpixel->col = col;
R_head = newpixel;
- /*get pixel list, todo polish, could use custom (shorter) function, not using all of what fsn() does... */
- find_segment_neighbors(&R_head, &Rn_head, &R_count, files, functions); /* todo, I suppose there is a small chance that a renumbered segment matches and borders an original segment. This would be a good reason to write a custom fnp() function to chop out the neighbors and also check the candidate flag. */
+ /*get pixel list, todo polish, could use custom (shorter) function, not using all of what fsn() does... hmm, after adding perimeter, we do use most of it... */
+ borderPixels = find_segment_neighbors(&R_head, &Rn_head, &R_count, files, functions); /* todo, I suppose there is a small chance that a renumbered segment matches and borders an original segment. This would be a good reason to write a custom fnp() function to chop out the neighbors and also check the candidate flag. */
/* update the segment ID *//* TODO, Markus, this could also be done in merge_pixels to avoid iterating this list twice.
* for now I've put it here, to make merge_pixels() more general. Unless you think initialization speed is more important then future flexibility? */
@@ -289,7 +295,7 @@
}
/*merge pixels (updates the bands_seg) */
- merge_pixels(R_head, files);
+ merge_pixels(R_head, borderPixels, files);
/*todo calculate perimeter (?and area?) here? */
More information about the grass-commit
mailing list