[GRASS-SVN] r55022 - grass/trunk/imagery/i.segment
svn_grass at osgeo.org
svn_grass at osgeo.org
Tue Feb 12 15:43:04 PST 2013
Author: mmetz
Date: 2013-02-12 15:43:04 -0800 (Tue, 12 Feb 2013)
New Revision: 55022
Modified:
grass/trunk/imagery/i.segment/create_isegs.c
grass/trunk/imagery/i.segment/main.c
grass/trunk/imagery/i.segment/ngbrtree.c
grass/trunk/imagery/i.segment/parse_args.c
grass/trunk/imagery/i.segment/rclist.c
grass/trunk/imagery/i.segment/regtree.c
grass/trunk/imagery/i.segment/write_output.c
Log:
i.segment update
Modified: grass/trunk/imagery/i.segment/create_isegs.c
===================================================================
--- grass/trunk/imagery/i.segment/create_isegs.c 2013-02-12 20:52:30 UTC (rev 55021)
+++ grass/trunk/imagery/i.segment/create_isegs.c 2013-02-12 23:43:04 UTC (rev 55022)
@@ -14,7 +14,7 @@
#include <grass/rbtree.h> /* Red Black Tree library functions */
#include "iseg.h"
-#define EPSILON 1.0e-12
+#define EPSILON 1.0e-8
#define MAX(a,b) ( ((a)>(b)) ? (a) : (b) )
#define MIN(a,b) ( ((a)<(b)) ? (a) : (b) )
@@ -218,9 +218,9 @@
/* 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 > 0) {
- G_message(_("Pass %d:"), t);
+ G_message(_("Pass %d:"), ++t);
n_merges = 0;
globals->candidate_count = 0;
@@ -540,7 +540,7 @@
/* get segment id */
segment_get(&globals->rid_seg, (void *) &Ri.id, row, col);
- if (Ri.id < 0)
+ if (Ri.id < 0)
continue;
Ri_rs.id = Ri.id;
@@ -564,9 +564,6 @@
if (do_merge) {
- segment_get(&globals->bands_seg, (void *)Ri.mean,
- Ri.row, Ri.col);
-
/* find Ri's best neighbor, clear candidate flag */
Ri_nn = find_best_neighbor(&Ri, &Ri_rs, Ri_ngbrs,
&Rk, &Rk_rs,
@@ -648,6 +645,14 @@
n_ngbrs = 0;
/* TODO: add size of largest region to reg_tree, use this as min */
Rk->count = globals->ncells;
+ Rk->id = Rk_rs->id = 0;
+
+ if (Ri->id != Ri_rs->id)
+ G_fatal_error("Ri = %d but Ri_rs = %d", Ri->id, Ri_rs->id);
+ if (Ri->id <= 0)
+ G_fatal_error("Ri is %d", Ri->id);
+ if (Ri_rs->id <= 0)
+ G_fatal_error("Ri_rs is %d", Ri_rs->id);
/* go through segment, spreading outwards from head */
rclist_init(&rilist);
@@ -1039,10 +1044,10 @@
/* Ri ID must always be positive */
if (Ri_rs->id < 1)
- G_fatal_error("Ri id is negative: %d", Ri_rs->id);
+ G_fatal_error("Ri id is not positive: %d", Ri_rs->id);
/* if Rk ID is negative (no seed), Rk count must be 1 */
if (Rk_rs->id < 1 && Rk_rs->count > 1)
- G_fatal_error("Rk id is negative: %d, but count is > 1: %d",
+ G_fatal_error("Rk id is not positive: %d, but count is > 1: %d",
Rk_rs->id, Rk_rs->count);
/* update segment id and clear candidate flag */
@@ -1156,6 +1161,7 @@
}
} while (n--);
}
+ rclist_destroy(&rlist);
}
else {
/* Rk was larger than Ri */
@@ -1204,6 +1210,8 @@
}
} while (n--);
}
+ rclist_destroy(&rlist);
+
Ri->id = Ri_rs->id; /* == Rk->id */
if (Ri->id != Rk->id)
G_fatal_error("Ri ID should be set to Rk ID");
@@ -1215,7 +1223,79 @@
/* disable Rk */
Rk->id = Rk_rs->id = 0;
Rk->count = Rk_rs->count = 0;
+
+ /* update Ri */
+ 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);
+ }
+
return TRUE;
}
@@ -1294,6 +1374,9 @@
struct globals *globals)
{
struct reg_stats *rs_found;
+
+ if (rs->id <= 0)
+ G_fatal_error("Invalid region id %d", rs->id);
if ((rs_found = rgtree_find(globals->reg_tree, rs)) != NULL) {
@@ -1312,31 +1395,35 @@
static int calculate_reg_stats(int row, int col, struct reg_stats *rs,
struct globals *globals)
{
+ int ret = 0;
+
G_debug(4, "calculate_reg_stats()");
+ if (rs->id <= 0)
+ G_fatal_error("Invalid region id %d", rs->id);
+
segment_get(&globals->bands_seg, (void *)globals->bands_val,
row, col);
rs->count = 1;
- memcpy(rs->mean, globals->bands_val, globals->datasize);
memcpy(rs->sum, globals->bands_val, globals->datasize);
if (globals->min_reg_size < 3)
- return 1;
-
- if (globals->min_reg_size == 3) {
- int n, i, rid;
+ ret = 1;
+ else if (globals->min_reg_size == 3) {
+ int n, rid;
struct rc ngbr_rc;
int neighbors[8][2];
globals->find_neighbors(row, col, neighbors);
- for (n = 0; n < globals->nn; n++) {
+ n = globals->nn - 1;
+ do {
ngbr_rc.row = neighbors[n][0];
ngbr_rc.col = neighbors[n][1];
- if (ngbr_rc.row < 0 || ngbr_rc.row >= globals->nrows ||
- ngbr_rc.col < 0 || ngbr_rc.col >= globals->ncols) {
+ if (ngbr_rc.row < globals->row_min || ngbr_rc.row >= globals->row_max ||
+ ngbr_rc.col < globals->col_min || ngbr_rc.col >= globals->col_max) {
continue;
}
@@ -1348,34 +1435,22 @@
if (rid == rs->id) {
/* update region stats */
- segment_get(&globals->bands_seg, (void *)globals->bands_val,
- ngbr_rc.row, ngbr_rc.col);
-
- i = globals->nbands - 1;
- do {
- rs->sum[i] += globals->bands_val[i];
- } while (i--);
rs->count++;
/* only one other neighbor can have the same ID */
- break;
+ /* break; */
}
}
- }
+ } while (n--);
+ if (rs->count > 2)
+ G_fatal_error(_("Region size is larger than 2: %d"), rs->count);
- /* band mean */
- i = globals->nbands - 1;
- do {
- rs->mean[i] = rs->sum[i] / rs->count;
- } while (i--);
-
- return 2;
+ ret = 2;
}
-
- if (globals->min_reg_size > 3) {
+ else if (globals->min_reg_size > 3) {
/* rs->id must be set */
struct RB_TREE *rc_check_tree; /* cells already checked */
- int n, i, rid;
+ int n, rid;
struct rc ngbr_rc, next;
struct rclist rilist;
int neighbors[8][2];
@@ -1398,14 +1473,15 @@
globals->find_neighbors(next.row, next.col, neighbors);
n = globals->nn - 1;
- n = 0;
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);
+ no_check = (ngbr_rc.row < globals->row_min ||
+ ngbr_rc.row >= globals->row_max ||
+ ngbr_rc.col < globals->col_min ||
+ ngbr_rc.col >= globals->col_max);
if (!no_check) {
if ((FLAG_GET(globals->null_flag, ngbr_rc.row, ngbr_rc.col)) == 0) {
@@ -1425,32 +1501,31 @@
rclist_add(&rilist, ngbr_rc.row, ngbr_rc.col);
/* update region stats */
- segment_get(&globals->bands_seg,
- (void *)globals->bands_val,
- ngbr_rc.row, ngbr_rc.col);
-
- i = globals->nbands - 1;
- do {
- rs->sum[i] += globals->bands_val[i];
- } while (i--);
rs->count++;
}
}
}
}
- } while (n++ < globals->nn - 1); /* (n--); */
+ } while (n--);
} while (rclist_drop(&rilist, &next));
- /* band mean */
- i = globals->nbands - 1;
- do {
- rs->mean[i] = rs->sum[i] / rs->count;
- } while (i--);
/* clean up */
rbtree_destroy(rc_check_tree);
-
- return 3;
+ rclist_destroy(&rilist);
+
+ ret = 3;
}
+
+ /* band mean */
+ if (rs->count == 1)
+ memcpy(rs->mean, rs->sum, globals->datasize);
+ else {
+ int i = globals->nbands - 1;
+
+ do {
+ rs->mean[i] = rs->sum[i] / rs->count;
+ } while (i--);
+ }
- return 0;
+ return ret;
}
Modified: grass/trunk/imagery/i.segment/main.c
===================================================================
--- grass/trunk/imagery/i.segment/main.c 2013-02-12 20:52:30 UTC (rev 55021)
+++ grass/trunk/imagery/i.segment/main.c 2013-02-12 23:43:04 UTC (rev 55022)
@@ -2,9 +2,9 @@
/****************************************************************************
*
* MODULE: i.segment
- * AUTHOR(S): Eric Momsen <eric.momsen at gmail com> (Google Summer of Code 2012)
- * Optimized by Markus Metz
- * PURPOSE: Segments an image group.
+ * AUTHOR(S): Markus Metz
+ * based on the the GSoC project by Eric Momsen <eric.momsen at gmail com>
+ * PURPOSE: Object recognition, segments an image group.
* COPYRIGHT: (C) 2012 by Eric Momsen, and the GRASS Development Team
*
* This program is free software under the GNU General
@@ -34,8 +34,13 @@
module = G_define_module();
G_add_keyword(_("imagery"));
G_add_keyword(_("segmentation"));
+ G_add_keyword(_("object recognition"));
module->description =
+<<<<<<< .mine
+ _("Identify segments (objects) from imagery.");
+=======
_("Outputs a single segmented raster map based on input values in an image group.");
+>>>>>>> .r55021
parse_args(argc, argv, &globals);
Modified: grass/trunk/imagery/i.segment/ngbrtree.c
===================================================================
--- grass/trunk/imagery/i.segment/ngbrtree.c 2013-02-12 20:52:30 UTC (rev 55021)
+++ grass/trunk/imagery/i.segment/ngbrtree.c 2013-02-12 23:43:04 UTC (rev 55022)
@@ -44,7 +44,7 @@
int cmp_ngbr(struct ngbr_stats *a, struct ngbr_stats *b)
{
- return (a->id < b->id ? -1 : (a->id > b->id));
+ return (a->id - b->id);
}
@@ -220,11 +220,13 @@
/* Replace and remove if found */
if (f != NULL) {
- f->data.id = q->data.id;
- f->data.row = q->data.row;
- f->data.col = q->data.col;
- f->data.count = q->data.count;
- memcpy(f->data.mean, q->data.mean, tree->datasize);
+ if (f != q) {
+ f->data.id = q->data.id;
+ f->data.row = q->data.row;
+ f->data.col = q->data.col;
+ f->data.count = q->data.count;
+ memcpy(f->data.mean, q->data.mean, tree->datasize);
+ }
p->link[p->link[1] == q] = q->link[q->link[0] == NULL];
free(q->data.mean);
Modified: grass/trunk/imagery/i.segment/parse_args.c
===================================================================
--- grass/trunk/imagery/i.segment/parse_args.c 2013-02-12 20:52:30 UTC (rev 55021)
+++ grass/trunk/imagery/i.segment/parse_args.c 2013-02-12 23:43:04 UTC (rev 55022)
@@ -97,7 +97,7 @@
endt->key = "iterations";
endt->type = TYPE_INTEGER;
endt->required = NO;
- endt->answer = "100";
+ endt->answer = "20";
endt->description = _("Maximum number of iterations");
endt->guisection = _("Settings");
Modified: grass/trunk/imagery/i.segment/rclist.c
===================================================================
--- grass/trunk/imagery/i.segment/rclist.c 2013-02-12 20:52:30 UTC (rev 55021)
+++ grass/trunk/imagery/i.segment/rclist.c 2013-02-12 23:43:04 UTC (rev 55022)
@@ -22,7 +22,7 @@
if (list->head) {
list->head->next = new;
- list->head = list->head->next;
+ list->head = new;
}
else {
list->head = list->tail = new;
Modified: grass/trunk/imagery/i.segment/regtree.c
===================================================================
--- grass/trunk/imagery/i.segment/regtree.c 2013-02-12 20:52:30 UTC (rev 55021)
+++ grass/trunk/imagery/i.segment/regtree.c 2013-02-12 23:43:04 UTC (rev 55022)
@@ -44,7 +44,7 @@
int compare_regstat(struct reg_stats *a, struct reg_stats *b)
{
- return (a->id < b->id ? -1 : (a->id > b->id));
+ return (a->id - b->id);
}
@@ -221,14 +221,16 @@
/* Replace and remove if found */
if (f != NULL) {
- f->data.id = q->data.id;
- f->data.count = q->data.count;
- memcpy(f->data.sum, q->data.sum, tree->datasize);
- memcpy(f->data.mean, q->data.mean, tree->datasize);
- /* unused:
- memcpy(f->data.min, q->data.min, tree->datasize);
- memcpy(f->data.max, q->data.max, tree->datasize);
- */
+ if (f != q) {
+ f->data.id = q->data.id;
+ f->data.count = q->data.count;
+ memcpy(f->data.sum, q->data.sum, tree->datasize);
+ memcpy(f->data.mean, q->data.mean, tree->datasize);
+ /* unused:
+ memcpy(f->data.min, q->data.min, tree->datasize);
+ memcpy(f->data.max, q->data.max, tree->datasize);
+ */
+ }
p->link[p->link[1] == q] = q->link[q->link[0] == NULL];
free(q->data.sum);
Modified: grass/trunk/imagery/i.segment/write_output.c
===================================================================
--- grass/trunk/imagery/i.segment/write_output.c 2013-02-12 20:52:30 UTC (rev 55021)
+++ grass/trunk/imagery/i.segment/write_output.c 2013-02-12 23:43:04 UTC (rev 55022)
@@ -172,6 +172,8 @@
flag_destroy(globals->null_flag);
flag_destroy(globals->candidate_flag);
+
+ rgtree_destroy(globals->reg_tree);
/* anything else left to clean up? */
More information about the grass-commit
mailing list