[GRASS-SVN] r55033 - grass/trunk/imagery/i.segment
svn_grass at osgeo.org
svn_grass at osgeo.org
Wed Feb 13 02:57:30 PST 2013
Author: mmetz
Date: 2013-02-13 02:57:30 -0800 (Wed, 13 Feb 2013)
New Revision: 55033
Modified:
grass/trunk/imagery/i.segment/create_isegs.c
grass/trunk/imagery/i.segment/i.segment.html
grass/trunk/imagery/i.segment/iseg.h
grass/trunk/imagery/i.segment/main.c
grass/trunk/imagery/i.segment/open_files.c
grass/trunk/imagery/i.segment/parse_args.c
Log:
i.segment update, fix mess by two people working at the module at the same time
Modified: grass/trunk/imagery/i.segment/create_isegs.c
===================================================================
--- grass/trunk/imagery/i.segment/create_isegs.c 2013-02-13 10:13:04 UTC (rev 55032)
+++ grass/trunk/imagery/i.segment/create_isegs.c 2013-02-13 10:57:30 UTC (rev 55033)
@@ -208,7 +208,7 @@
Rk_bestn_rs.sum = G_malloc(globals->datasize);
t = 0;
- n_merges = 1;
+ n_merges = 2;
/* threshold calculation */
alpha2 = globals->alpha * globals->alpha;
@@ -218,7 +218,7 @@
/* make the divisor a constant ? */
divisor = globals->nrows + globals->ncols;
- while (t < globals->end_t && n_merges > 0) {
+ while (t < globals->end_t && n_merges > 1) {
G_message(_("Pass %d:"), ++t);
@@ -489,7 +489,7 @@
}
/*end t loop *//*TODO, should there be a max t that it can iterate for? Include t in G_message? */
- if (n_merges > 0)
+ if (n_merges > 1)
G_message(_("Segmentation processes stopped at %d due to reaching max iteration limit, more merges may be possible"), t);
else
G_message(_("Segmentation converged after %d iterations."), t);
@@ -571,7 +571,7 @@
globals);
}
- if (do_merge) {
+ if (Ri_nn > 0) {
nbtree_clear(Ri_ngbrs);
@@ -1029,6 +1029,102 @@
return 1;
}
+int update_band_vals(int row, int col, struct reg_stats *rs,
+ struct globals *globals) {
+ /* update band values with sum */
+ /* rs->id must be set */
+ struct RB_TREE *rc_check_tree; /* cells already checked */
+ struct rclist rlist;
+ struct rc next, ngbr_rc;
+ int neighbors[8][2];
+ int rid, count, n;
+ int no_check;
+
+ G_debug(4, "update_band_vals()");
+
+ if (rs->count >= globals->min_reg_size) {
+ G_fatal_error(_("Region stats should go in tree, %d >= %d"),
+ rs->count, globals->min_reg_size);
+ }
+
+ segment_get(&globals->rid_seg, (void *) &rid, row, col);
+
+ if (rid != rs->id) {
+ G_fatal_error(_("Region ids are different"));
+ }
+
+ /* go through region, spreading outwards from head */
+ rclist_init(&rlist);
+
+ rc_check_tree = rbtree_create(compare_rc, sizeof(struct rc));
+ ngbr_rc.row = row;
+ ngbr_rc.col = col;
+ rbtree_insert(rc_check_tree, &ngbr_rc);
+ count = 1;
+
+ /* update region stats */
+ segment_put(&globals->bands_seg, (void *)rs->sum,
+ ngbr_rc.row, ngbr_rc.col);
+
+ next.row = row;
+ next.col = col;
+ do {
+ G_debug(5, "find_pixel_neighbors for row: %d , col %d",
+ next.row, next.col);
+
+ globals->find_neighbors(next.row, next.col, neighbors);
+
+ n = globals->nn - 1;
+ do {
+
+ ngbr_rc.row = neighbors[n][0];
+ ngbr_rc.col = neighbors[n][1];
+
+ no_check = (ngbr_rc.row < 0 || ngbr_rc.row >= globals->nrows ||
+ ngbr_rc.col < 0 || ngbr_rc.col >= globals->ncols);
+
+ if (!no_check) {
+ if ((FLAG_GET(globals->null_flag, ngbr_rc.row, ngbr_rc.col)) == 0) {
+
+ /* already checked ? */
+ if (!rbtree_find(rc_check_tree, &ngbr_rc)) {
+
+ /* not yet checked, don't check it again */
+ rbtree_insert(rc_check_tree, &ngbr_rc);
+
+ segment_get(&globals->rid_seg, (void *) &rid,
+ ngbr_rc.row, ngbr_rc.col);
+
+ if (rid == rs->id) {
+
+ /* want to check this neighbor's neighbors */
+ rclist_add(&rlist, ngbr_rc.row, ngbr_rc.col);
+
+ /* update region stats */
+ segment_put(&globals->bands_seg,
+ (void *)rs->sum,
+ ngbr_rc.row, ngbr_rc.col);
+ count++;
+ }
+ }
+ }
+ }
+ } while (n--);
+ } while (rclist_drop(&rlist, &next));
+
+ /* clean up */
+ rbtree_destroy(rc_check_tree);
+ rclist_destroy(&rlist);
+
+ if (count != rs->count) {
+ G_fatal_error(_("Region size is %d, should be %d"),
+ count, rs->count);
+ }
+
+ return count;
+}
+
+
static int merge_regions(struct ngbr_stats *Ri, struct reg_stats *Ri_rs,
struct ngbr_stats *Rk, struct reg_stats *Rk_rs,
int do_cand, struct globals *globals)
@@ -1228,72 +1324,7 @@
Ri->id = Ri_rs->id;
if (Ri_rs->count < globals->min_reg_size) {
- /* update band values with sum */
- /* rs->id must be set */
- struct RB_TREE *rc_check_tree; /* cells already checked */
- int rid;
- int no_check;
-
- /* go through region, spreading outwards from head */
- rclist_init(&rlist);
-
- rc_check_tree = rbtree_create(compare_rc, sizeof(struct rc));
- ngbr_rc.row = Ri->row;
- ngbr_rc.col = Ri->col;
- rbtree_insert(rc_check_tree, &ngbr_rc);
-
- /* update region stats */
- segment_put(&globals->bands_seg, (void *)Ri_rs->sum,
- ngbr_rc.row, ngbr_rc.col);
-
- next.row = Ri->row;
- next.col = Ri->col;
- do {
- G_debug(5, "find_pixel_neighbors for row: %d , col %d",
- next.row, next.col);
-
- globals->find_neighbors(next.row, next.col, neighbors);
-
- n = globals->nn - 1;
- do {
-
- ngbr_rc.row = neighbors[n][0];
- ngbr_rc.col = neighbors[n][1];
-
- no_check = (ngbr_rc.row < 0 || ngbr_rc.row >= globals->nrows ||
- ngbr_rc.col < 0 || ngbr_rc.col >= globals->ncols);
-
- if (!no_check) {
- if ((FLAG_GET(globals->null_flag, ngbr_rc.row, ngbr_rc.col)) == 0) {
-
- /* already checked ? */
- if (!rbtree_find(rc_check_tree, &ngbr_rc)) {
-
- /* not yet checked, don't check it again */
- rbtree_insert(rc_check_tree, &ngbr_rc);
-
- segment_get(&globals->rid_seg, (void *) &rid,
- ngbr_rc.row, ngbr_rc.col);
-
- if (rid == Ri_rs->id) {
-
- /* want to check this neighbor's neighbors */
- rclist_add(&rlist, ngbr_rc.row, ngbr_rc.col);
-
- /* update region stats */
- segment_put(&globals->bands_seg,
- (void *)Ri_rs->sum,
- ngbr_rc.row, ngbr_rc.col);
- }
- }
- }
- }
- } while (n--);
- } while (rclist_drop(&rlist, &next));
-
- /* clean up */
- rbtree_destroy(rc_check_tree);
- rclist_destroy(&rlist);
+ update_band_vals(Ri->row, Ri->col, Ri_rs, globals);
}
return TRUE;
@@ -1527,5 +1558,9 @@
} while (i--);
}
+ if (rs->count >= globals->min_reg_size)
+ G_fatal_error(_("Region of size %d should be in search tree"),
+ rs->count);
+
return ret;
}
Modified: grass/trunk/imagery/i.segment/i.segment.html
===================================================================
--- grass/trunk/imagery/i.segment/i.segment.html 2013-02-13 10:13:04 UTC (rev 55032)
+++ grass/trunk/imagery/i.segment/i.segment.html 2013-02-13 10:57:30 UTC (rev 55033)
@@ -60,10 +60,11 @@
<h3>Seeds</h3>
The seeds map can be used to provide either seed pixels (random or
selected points from which to start the segmentation process) or
-seed segments (results of previous segmentations or
-classifications). The different approaches are automatically
-detected by the program: any pixels that have identical seed values
-and are contiguous will be assigned a unique segment ID.
+seed segments. If the seeds are the results of a previous segmentation
+with lower threshold, hierarchical segmentation can be performed. The
+different approaches are automatically detected by the program: any
+pixels that have identical seed values and are contiguous will be
+assigned a unique segment ID.
<p>
It is expected that the <em>minsize</em> will be set to 1 if a seed
map is used, but the program will allow other values to be used. If
@@ -131,10 +132,12 @@
seeds=ortho_segs_l4
</pre></div>
<p>
-The output ortho_segs_l4 with threshold=0.2 looks best. There is some
-noise in the image, lets next force all segments smaller than 5 pixels
-to be merged into their most similar neighbor (even if they are less
-similar then required by our threshold):<br>
+The output ortho_segs_l4 with threshold=0.2 still has too many segments,
+but the output with threshold=0.3 has too few segments. A threshold
+value of 0.25 seems to be a good choice. There is also some noise in
+the image, lets next force all segments smaller than 10 pixels to be
+merged into their most similar neighbor (even if they are less similar
+than required by our threshold):<br>
<p>Set the region to match the entire map(s) in the group. <br>
<div class="code"><pre>
@@ -145,11 +148,11 @@
<div class="code"><pre>
i.segment group=ortho_group output=ortho_segs_final \
- threshold=0.2 min=5
+ threshold=0.25 min=10
</pre></div>
<p></p>
-Processing the entire ortho image with nearly 10 million pixels took about
-15 minutes for the first run.
+Processing the entire ortho image with nearly 10 million pixels took
+about 20 minutes for the final run.
<h2>TODO</h2>
<h3>Functionality</h3>
Modified: grass/trunk/imagery/i.segment/iseg.h
===================================================================
--- grass/trunk/imagery/i.segment/iseg.h 2013-02-13 10:13:04 UTC (rev 55032)
+++ grass/trunk/imagery/i.segment/iseg.h 2013-02-13 10:57:30 UTC (rev 55033)
@@ -117,6 +117,7 @@
int, struct globals *);
int fetch_reg_stats(int , int , struct reg_stats *,
struct globals *);
+int update_band_vals(int, int, struct reg_stats *, struct globals *);
/* void calculate_reg_stats(int, int, struct reg_stats *,
struct globals *); */
Modified: grass/trunk/imagery/i.segment/main.c
===================================================================
--- grass/trunk/imagery/i.segment/main.c 2013-02-13 10:13:04 UTC (rev 55032)
+++ grass/trunk/imagery/i.segment/main.c 2013-02-13 10:57:30 UTC (rev 55033)
@@ -36,7 +36,7 @@
G_add_keyword(_("segmentation"));
G_add_keyword(_("object recognition"));
module->description =
- _("Identifies segments (objects) from imagery data.");
+ _("Identify segments (objects) from imagery.");
parse_args(argc, argv, &globals);
Modified: grass/trunk/imagery/i.segment/open_files.c
===================================================================
--- grass/trunk/imagery/i.segment/open_files.c 2013-02-13 10:13:04 UTC (rev 55032)
+++ grass/trunk/imagery/i.segment/open_files.c 2013-02-13 10:57:30 UTC (rev 55033)
@@ -458,6 +458,9 @@
rgtree_insert(globals->reg_tree, &(globals->rs));
}
+ else {
+ update_band_vals(Ri->row, Ri->col, &(globals->rs), globals);
+ }
return 1;
}
Modified: grass/trunk/imagery/i.segment/parse_args.c
===================================================================
--- grass/trunk/imagery/i.segment/parse_args.c 2013-02-13 10:13:04 UTC (rev 55032)
+++ grass/trunk/imagery/i.segment/parse_args.c 2013-02-13 10:57:30 UTC (rev 55033)
@@ -44,7 +44,7 @@
similarity = G_define_option();
similarity->key = "similarity";
similarity->type = TYPE_STRING;
- similarity->required = YES;
+ similarity->required = NO;
similarity->answer = "euclidean";
similarity->options = "euclidean,manhattan";
similarity->description = _("Similarity calculation method");
@@ -65,7 +65,7 @@
radio_weight = G_define_option();
radio_weight->key = "radio_weight";
radio_weight->type = TYPE_DOUBLE;
- radio_weight->required = YES;
+ radio_weight->required = NO;
radio_weight->answer = "1";
radio_weight->options = "0-1";
radio_weight->label =
@@ -75,7 +75,7 @@
smooth_weight = G_define_option();
smooth_weight->key = "smooth_weight";
smooth_weight->type = TYPE_DOUBLE;
- smooth_weight->required = YES;
+ smooth_weight->required = NO;
smooth_weight->answer = "0.5";
smooth_weight->options = "0-1";
smooth_weight->label =
@@ -106,24 +106,21 @@
seeds = G_define_standard_option(G_OPT_R_INPUT);
seeds->key = "seeds";
seeds->required = NO;
- seeds->description = _("Name for output raster map with starting seeds");
- seeds->guisection = _("Optional outputs");
+ seeds->description = _("Name for input raster map with starting seeds");
/* Polygon constraints. */
bounds = G_define_standard_option(G_OPT_R_INPUT);
bounds->key = "bounds";
bounds->required = NO;
- bounds->label = _("Name for output bounding/constraining raster map");
+ bounds->label = _("Name for input bounding/constraining raster map");
bounds->description =
_("Must be integer values, each area will be segmented independent of the others");
- bounds->guisection = _("Optional outputs");
outband = G_define_standard_option(G_OPT_R_OUTPUT);
outband->key = "goodness";
outband->required = NO;
outband->description =
_("Name for output goodness of fit estimate");
- outband->guisection = _("Optional outputs");
diagonal = G_define_flag();
diagonal->key = 'd';
More information about the grass-commit
mailing list