[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