[GRASS-SVN] r49813 - in grass/trunk: include include/Make include/defs lib/imagery

svn_grass at osgeo.org svn_grass at osgeo.org
Sun Dec 18 14:05:04 EST 2011


Author: annakrat
Date: 2011-12-18 11:05:04 -0800 (Sun, 18 Dec 2011)
New Revision: 49813

Added:
   grass/trunk/lib/imagery/iclass.c
   grass/trunk/lib/imagery/iclass_bands.c
   grass/trunk/lib/imagery/iclass_local_proto.h
   grass/trunk/lib/imagery/iclass_perimeter.c
   grass/trunk/lib/imagery/iclass_signatures.c
   grass/trunk/lib/imagery/iclass_statistics.c
Modified:
   grass/trunk/include/Make/Grass.make
   grass/trunk/include/defs/imagery.h
   grass/trunk/include/imagery.h
   grass/trunk/lib/imagery/Makefile
Log:
imagerylib: functions used by wxIClass, based on i.class (co-author V. Petras)

Modified: grass/trunk/include/Make/Grass.make
===================================================================
--- grass/trunk/include/Make/Grass.make	2011-12-18 19:00:59 UTC (rev 49812)
+++ grass/trunk/include/Make/Grass.make	2011-12-18 19:05:04 UTC (rev 49813)
@@ -201,7 +201,7 @@
 GPDEDEPS         = $(RASTER3DLIB) $(RASTERLIB) $(GISLIB) $(GMATHLIB) $(OMPLIBPATH) $(OMPLIB) $(MATHLIB)
 GPROJDEPS        = $(GISLIB) $(GDALLIBS) $(PROJLIB) $(MATHLIB)
 HTMLDRIVERDEPS   = $(DRIVERLIB) $(GISLIB) $(MATHLIB)
-IMAGERYDEPS      = $(GISLIB) $(MATHLIB)
+IMAGERYDEPS      = $(GISLIB) $(MATHLIB) $(RASTERLIB) $(VECTORLIB)
 INTERPFLDEPS     = $(BITMAPLIB) $(DBMILIB) $(GMATHLIB) $(INTERPDATALIB) $(QTREELIB) $(VECTORLIB) $(RASTERLIB) $(GISLIB) $(MATHLIB)
 #IORTHODEPS       = $(IMAGERYLIB) $(GISLIB)
 LIDARDEPS        = $(VECTORLIB) $(DBMILIB) $(GMATHLIB) $(RASTERLIB) $(SEGMENTLIB) $(GISLIB) $(MATHLIB)

Modified: grass/trunk/include/defs/imagery.h
===================================================================
--- grass/trunk/include/defs/imagery.h	2011-12-18 19:00:59 UTC (rev 49812)
+++ grass/trunk/include/defs/imagery.h	2011-12-18 19:05:04 UTC (rev 49813)
@@ -50,6 +50,37 @@
 int I_init_group_ref(struct Ref *);
 int I_free_group_ref(struct Ref *);
 
+/* iclass.c */
+struct Map_info;
+int I_iclass_analysis(IClass_statistics *, struct Ref *, struct Map_info *, const char *, const char *, const char *);
+int I_iclass_init_group(const char *, struct Ref *);
+void I_iclass_create_raster(IClass_statistics *, struct Ref *, const char *);
+
+/* iclass_statistics.c */
+void I_iclass_statistics_get_nbands(IClass_statistics *, int *);
+void I_iclass_statistics_get_cat(IClass_statistics *, int *);
+void I_iclass_statistics_get_name(IClass_statistics *, const char **);
+void I_iclass_statistics_get_color(IClass_statistics *, const char **);
+void I_iclass_statistics_get_ncells(IClass_statistics *, int *);
+int I_iclass_statistics_get_max(IClass_statistics *, int, int *);
+int I_iclass_statistics_get_range_max(IClass_statistics *, int, int *);
+int I_iclass_statistics_get_min(IClass_statistics *, int, int *);
+int I_iclass_statistics_get_range_min(IClass_statistics *, int, int *);
+int I_iclass_statistics_get_sum(IClass_statistics *, int, float *);
+int I_iclass_statistics_get_mean(IClass_statistics *, int, float *);
+int I_iclass_statistics_get_stddev(IClass_statistics *, int, float *);
+void I_iclass_statistics_get_nstd(IClass_statistics *, float *);
+void I_iclass_statistics_set_nstd(IClass_statistics *, float);
+int I_iclass_statistics_get_histo(IClass_statistics *, int, int, int *);
+int I_iclass_statistics_get_product(IClass_statistics *, int, int, float *);
+void I_iclass_init_statistics(IClass_statistics *, int, const char *, const char *, float);
+void I_iclass_free_statistics(IClass_statistics *);
+
+/* iclass_signatures.c */
+int I_iclass_init_signatures(struct Signature *, struct Ref *);
+void I_iclass_add_signature(struct Signature *, IClass_statistics *);
+int I_iclass_write_signatures(struct Signature *, const char *, const char *, const char *);
+
 /* list_gp.c */
 int I_list_group(const char *, const struct Ref *, FILE *);
 int I_list_group_simple(const struct Ref *, FILE *);

Modified: grass/trunk/include/imagery.h
===================================================================
--- grass/trunk/include/imagery.h	2011-12-18 19:00:59 UTC (rev 49812)
+++ grass/trunk/include/imagery.h	2011-12-18 19:05:04 UTC (rev 49813)
@@ -3,6 +3,7 @@
 
 #include <grass/gis.h>
 #include <grass/raster.h>
+//#include <grass/vector.h>
 
 /* File/directory name lengths */
 #define INAME_LEN GNAME_MAX	/* coupled to raster map name length */
@@ -104,6 +105,37 @@
     struct ClassSig *ClassSig;
 };
 
+/* IClass */
+
+/*! Holds statistical values for creating histograms and raster maps for one class.
+
+  One class is represented by one category (cat).
+*/
+typedef struct
+{
+    int cat;                /*!< class */
+    const char *name;       /*!< signature description (class name) */
+    const char *color;      /*!< class color (RRR:GGG:BBB)*/
+    int nbands;             /*!< number of bands */
+    
+    int ncells;             /*!< number of cells in training areas */
+
+    int *band_min;          /*!< minimum value for each band */
+    int *band_max;          /*!< maximum value for each band */
+    float *band_sum;        /*!< sum of values for each band */
+    float *band_mean;       /*!< mean of values for each band */
+    float *band_stddev;     /*!< standard deviation for each band */
+
+    float **band_product;   /*!< sum of products of cell category values of 2 bands */
+    int **band_histo;       /*!< number of cells for cell category value (0-256) for each band */
+
+    int *band_range_min;    /*!< min range of values to create raster map */
+    int *band_range_max;    /*!< max range of values to create raster map */
+    float nstd;             /*!< multiplier of standard deviation */
+
+    
+} IClass_statistics;
+
 #define SIGNATURE_TYPE_MIXED 1
 
 #define GROUPFILE "CURGROUP"

Modified: grass/trunk/lib/imagery/Makefile
===================================================================
--- grass/trunk/lib/imagery/Makefile	2011-12-18 19:00:59 UTC (rev 49812)
+++ grass/trunk/lib/imagery/Makefile	2011-12-18 19:05:04 UTC (rev 49813)
@@ -2,6 +2,8 @@
 
 LIB = IMAGERY
 
+EXTRA_CFLAGS = $(VECT_CFLAGS)
+
 include $(MODULE_TOPDIR)/include/Make/Lib.make
 include $(MODULE_TOPDIR)/include/Make/Doxygen.make
 

Added: grass/trunk/lib/imagery/iclass.c
===================================================================
--- grass/trunk/lib/imagery/iclass.c	                        (rev 0)
+++ grass/trunk/lib/imagery/iclass.c	2011-12-18 19:05:04 UTC (rev 49813)
@@ -0,0 +1,153 @@
+/*!
+   \file lib/imagery/iclass.c
+
+   \brief Imagery library - functions for wx.iclass
+
+   Computation based on training areas for supervised classification.
+   Based on i.class module (GRASS 6).
+
+   Copyright (C) 1999-2007, 2011 by the GRASS Development Team
+
+   This program is free software under the GNU General Public License
+   (>=v2).  Read the file COPYING that comes with GRASS for details.
+
+   \author David Satnik, Central Washington University (original author)
+   \author Markus Neteler <neteler itc.it> (i.class module)
+   \author Bernhard Reiter <bernhard intevation.de> (i.class module)
+   \author Brad Douglas <rez touchofmadness.com>(i.class module)
+   \author Glynn Clements <glynn gclements.plus.com> (i.class module)
+   \author Hamish Bowman <hamish_b yahoo.com> (i.class module)
+   \author Jan-Oliver Wagner <jan intevation.de> (i.class module)
+   \author Anna Kratochvilova <kratochanna gmail.com> (rewriting for wx.iclass)
+   \author Vaclav Petras <wenzeslaus gmail.com> (rewriting for wx.iclass)
+ */
+
+#include <grass/imagery.h>
+#include <grass/glocale.h>
+#include <grass/vector.h>
+
+#include "iclass_local_proto.h"
+
+
+/*!
+   \brief Calculates statistical values for one class and multiple bands based on training areas.
+
+   Calculates values statistical based on the cells
+   that are within training areas. Creates raster map
+   to display the cells of the image bands which fall
+   within standard deviations from the means.
+
+   \param statistics pointer to bands statistics
+   \param refer pointer to band files structure
+   \param vector_map name of vector map with training areas
+   \param layer_name vector layer
+   \param group name of imagery group
+   \param raster_name name of temporary raster map (to be created)
+
+   \return 1 on success
+   \return 0 on failure
+ */
+int I_iclass_analysis(IClass_statistics * statistics, struct Ref *refer,
+		      struct Map_info *map_info, const char *layer_name,
+		      const char *group, const char *raster_name)
+{
+
+    int category;
+
+    struct Cell_head band_region;
+
+    CELL **band_buffer;
+
+    int *band_fd;
+
+    IClass_perimeter_list perimeters;
+
+
+
+    G_debug(1, "iclass_analysis(): group = %s", group);
+
+    category = statistics->cat;
+
+    /* region set to the first band */
+    Rast_get_cellhd(refer->file[0].name, refer->file[0].mapset, &band_region);
+
+    /* find perimeter points from vector map */
+    if (!vector2perimeters
+	(map_info, layer_name, category, &perimeters, &band_region)) {
+	return 0;
+    }
+
+    open_band_files(refer, &band_buffer, &band_fd);
+    alloc_statistics(statistics, refer->nfiles);
+    make_all_statistics(statistics, &perimeters, band_buffer, band_fd);
+    create_raster(statistics, band_buffer, band_fd, raster_name);
+    close_band_files(refer, band_buffer, band_fd);
+
+    free_perimeters(&perimeters);
+    return 1;
+}
+
+
+
+/*!
+   \brief Read files for the specified group into the Ref structure.
+
+   \param group_name name of imagery group
+   \param[out] refer pointer to band files structure
+
+   \return 1 on success
+   \return 0 on failure
+ */
+int I_iclass_init_group(const char *group_name, struct Ref *refer)
+{
+    int n;
+
+    G_debug(3, "init_group(): group = %s", group_name);
+    I_init_group_ref(refer);	/* called in I_get_group_ref */
+
+    I_get_group_ref(group_name, refer);
+
+    for (n = 0; n < refer->nfiles; n++) {
+	if (G_find_raster(refer->file[n].name, refer->file[n].mapset) == NULL) {
+	    G_warning(_("Raster map <%s@%s> in group "
+			"<%s> do not exist"), refer->file[n].name,
+		      refer->file[n].mapset, group_name);
+	    I_free_group_ref(refer);
+	    return 0;
+	}
+    }
+
+    if (refer->nfiles <= 1) {
+	G_warning(_("Group <%s> does not have enough files (it has %d files)"),
+		  group_name, refer->nfiles);
+	I_free_group_ref(refer);
+	return 0;
+    }
+
+    return 1;
+}
+
+/*!
+   \brief Create raster map based on statistics.
+
+   \param statistics pointer to bands statistics
+   \param refer pointer to band files structure
+   \param raster_name name of temporary raster map (to be created)
+ */
+void I_iclass_create_raster(IClass_statistics * statistics, struct Ref *refer,
+			    const char *raster_name)
+{
+    CELL **band_buffer;
+
+    int *band_fd;
+
+    int b;
+
+    for (b = 0; b < statistics->nbands; b++) {
+	band_range(statistics, b);
+    }
+
+    open_band_files(refer, &band_buffer, &band_fd);
+    create_raster(statistics, band_buffer, band_fd, raster_name);
+    close_band_files(refer, band_buffer, band_fd);
+}

Added: grass/trunk/lib/imagery/iclass_bands.c
===================================================================
--- grass/trunk/lib/imagery/iclass_bands.c	                        (rev 0)
+++ grass/trunk/lib/imagery/iclass_bands.c	2011-12-18 19:05:04 UTC (rev 49813)
@@ -0,0 +1,99 @@
+/*!
+   \file lib/imagery/iclass_bands.c
+
+   \brief Imagery library - functions for wx.iclass
+
+   Computation based on training areas for supervised classification.
+   Based on i.class module (GRASS 6).
+
+   Reading bands cell category values.
+
+   Copyright (C) 1999-2007, 2011 by the GRASS Development Team
+
+   This program is free software under the GNU General Public License
+   (>=v2).  Read the file COPYING that comes with GRASS for details.
+
+   \author David Satnik, Central Washington University (original author)
+   \author Markus Neteler <neteler itc.it> (i.class module)
+   \author Bernhard Reiter <bernhard intevation.de> (i.class module)
+   \author Brad Douglas <rez touchofmadness.com>(i.class module)
+   \author Glynn Clements <glynn gclements.plus.com> (i.class module)
+   \author Hamish Bowman <hamish_b yahoo.com> (i.class module)
+   \author Jan-Oliver Wagner <jan intevation.de> (i.class module)
+   \author Anna Kratochvilova <kratochanna gmail.com> (rewriting for wx.iclass)
+   \author Vaclav Petras <wenzeslaus gmail.com> (rewriting for wx.iclass)
+ */
+
+#include <grass/imagery.h>
+#include <grass/raster.h>
+
+#include "iclass_local_proto.h"
+
+/*!
+   \brief Open and allocate space for the group band files.
+
+   \param refer pointer to band files structure
+   \param[out] band_buffer buffer to read one row of each band
+   \param[out] band_fd band files descriptors
+ */
+void open_band_files(struct Ref *refer, CELL *** band_buffer, int **band_fd)
+{
+    int n, nbands;
+
+    char *name, *mapset;
+
+    G_debug(3, "open_band_files()");
+
+    /* allocate row buffers and open raster maps */
+    nbands = refer->nfiles;
+    *band_buffer = (CELL **) G_malloc(nbands * sizeof(CELL *));
+    *band_fd = (int *)G_malloc(nbands * sizeof(int));
+
+    for (n = 0; n < nbands; n++) {
+	(*band_buffer)[n] = Rast_allocate_c_buf();
+	name = refer->file[n].name;
+	mapset = refer->file[n].mapset;
+	(*band_fd)[n] = Rast_open_old(name, mapset);
+    }
+}
+
+/*!
+   \brief Close and free space for the group band files.
+
+   \param refer pointer to band files structure
+   \param band_buffer buffer to read one row of each band
+   \param band_fd band files descriptors
+ */
+void close_band_files(struct Ref *refer, CELL ** band_buffer, int *band_fd)
+{
+    int n, nbands;
+
+    G_debug(3, "close_band_files()");
+
+    nbands = refer->nfiles;
+    for (n = 0; n < nbands; n++) {
+	G_free(band_buffer[n]);
+	Rast_close(band_fd[n]);
+    }
+
+    G_free(band_buffer);
+    G_free(band_fd);
+}
+
+/*!
+   \brief Read one row of each band.
+
+   \param band_buffer buffer to read one row of each band
+   \param band_fd band files descriptors
+   \param nbands number of band files
+   \param row data row
+ */
+void read_band_row(CELL ** band_buffer, int *band_fd, int nbands, int row)
+{
+    int i;
+
+    G_debug(5, "read_band_row(): row = %d", row);
+
+    for (i = 0; i < nbands; i++)
+	Rast_get_c_row_nomask(band_fd[i], band_buffer[i], row);
+}

Added: grass/trunk/lib/imagery/iclass_local_proto.h
===================================================================
--- grass/trunk/lib/imagery/iclass_local_proto.h	                        (rev 0)
+++ grass/trunk/lib/imagery/iclass_local_proto.h	2011-12-18 19:05:04 UTC (rev 49813)
@@ -0,0 +1,107 @@
+/*!
+   \file lib/imagery/iclass_local_proto.h
+
+   \brief Imagery library - functions for wx.iclass
+
+   Computation based on training areas for supervised classification.
+   Based on i.class module (GRASS 6).
+
+   Copyright (C) 1999-2007, 2011 by the GRASS Development Team
+
+   This program is free software under the GNU General Public License
+   (>=v2).  Read the file COPYING that comes with GRASS for details.
+
+   \author David Satnik, Central Washington University (original author)
+   \author Markus Neteler <neteler itc.it> (i.class module)
+   \author Bernhard Reiter <bernhard intevation.de> (i.class module)
+   \author Brad Douglas <rez touchofmadness.com>(i.class module)
+   \author Glynn Clements <glynn gclements.plus.com> (i.class module)
+   \author Hamish Bowman <hamish_b yahoo.com> (i.class module)
+   \author Jan-Oliver Wagner <jan intevation.de> (i.class module)
+   \author Anna Kratochvilova <kratochanna gmail.com> (rewriting for wx.iclass)
+   \author Vaclav Petras <wenzeslaus gmail.com> (rewriting for wx.iclass)
+ */
+
+#ifndef ICLASS_LOCAL_PROTO_H
+#define ICLASS_LOCAL_PROTO_H
+
+#include <grass/imagery.h>
+#include <grass/raster.h>
+#include <grass/vector.h>
+
+#define MAX_CATS 256
+
+/*! Point of area perimeter */
+typedef struct
+{
+    int x;			/*!< column */
+    int y;			/*!< row */
+
+} IClass_point;
+
+/*! Holds perimeter points of one area.
+
+   Perimeter is represented by rasterized area outline
+   (not only vertices).
+ */
+typedef struct
+{
+    int npoints;
+    IClass_point *points;
+
+} IClass_perimeter;
+
+/*! Holds perimeters of training areas. */
+typedef struct
+{
+    int nperimeters;
+    IClass_perimeter *perimeters;
+
+} IClass_perimeter_list;
+
+/* iclass_statistics.c */
+void alloc_statistics(IClass_statistics * statistics, int nbands);
+
+int make_statistics(IClass_statistics * statistics,
+		    IClass_perimeter * perimeter, CELL ** band_buffer,
+		    int *band_fd);
+int make_all_statistics(IClass_statistics * statistics,
+			IClass_perimeter_list * perimeters,
+			CELL ** band_buffer, int *band_fd);
+void create_raster(IClass_statistics * statistics, CELL ** band_buffer,
+		   int *band_fd, const char *raster_name);
+void band_range(IClass_statistics *, int);
+
+float mean(IClass_statistics * statistics, int band);
+
+float stddev(IClass_statistics * statistics, int band);
+
+float var(IClass_statistics * statistics, int band1, int band2);
+
+float var_signature(IClass_statistics * statistics, int band1, int band2);
+
+/* iclass_bands.c */
+void open_band_files(struct Ref *refer, CELL *** band_buffer, int **band_fd);
+
+void close_band_files(struct Ref *refer, CELL ** band_buffer, int *band_fd);
+
+void read_band_row(CELL ** band_buffer, int *band_fd, int nbands, int row);
+
+/* iclass_perimeter.c */
+int vector2perimeters(struct Map_info *, const char *layer_name,
+		      int category, IClass_perimeter_list * perimeters,
+		      struct Cell_head *band_region);
+int make_perimeter(struct line_pnts *points, IClass_perimeter * perimeter,
+		   struct Cell_head *band_region);
+int edge2perimeter(IClass_perimeter * perimeter, int x0, int y0, int x1,
+		   int y1);
+void perimeter_add_point(IClass_perimeter * perimeter, int x, int y);
+
+int edge_order(const void *aa, const void *bb);
+
+void free_perimeters(IClass_perimeter_list * perimeters);
+
+/* iclass.c */
+int init_group(const char *group_name, struct Ref *refer);
+
+#endif // ICLASS_LOCAL_PROTO_H

Added: grass/trunk/lib/imagery/iclass_perimeter.c
===================================================================
--- grass/trunk/lib/imagery/iclass_perimeter.c	                        (rev 0)
+++ grass/trunk/lib/imagery/iclass_perimeter.c	2011-12-18 19:05:04 UTC (rev 49813)
@@ -0,0 +1,389 @@
+/*!
+   \file lib/imagery/iclass_perimeter.c
+
+   \brief Imagery library - functions for wx.iclass
+
+   Computation based on training areas for supervised classification.
+   Based on i.class module (GRASS 6).
+
+   Vector map with training areas is used to determine corresponding
+   cells by computing cells on area perimeter.
+
+   Copyright (C) 1999-2007, 2011 by the GRASS Development Team
+
+   This program is free software under the GNU General Public License
+   (>=v2).  Read the file COPYING that comes with GRASS for details.
+
+   \author David Satnik, Central Washington University (original author)
+   \author Markus Neteler <neteler itc.it> (i.class module)
+   \author Bernhard Reiter <bernhard intevation.de> (i.class module)
+   \author Brad Douglas <rez touchofmadness.com>(i.class module)
+   \author Glynn Clements <glynn gclements.plus.com> (i.class module)
+   \author Hamish Bowman <hamish_b yahoo.com> (i.class module)
+   \author Jan-Oliver Wagner <jan intevation.de> (i.class module)
+   \author Anna Kratochvilova <kratochanna gmail.com> (rewriting for wx.iclass)
+   \author Vaclav Petras <wenzeslaus gmail.com> (rewriting for wx.iclass)
+ */
+
+#include <grass/vector.h>
+#include <grass/raster.h>
+#include <grass/glocale.h>
+
+#include "iclass_local_proto.h"
+
+
+#define extrema(x,y,z) (((x<y)&&(z<y))||((x>y)&&(z>y)))
+#define non_extrema(x,y,z) (((x<y)&&(y<z))||((x>y)&&(y>z)))
+
+/*!
+   \brief Creates perimeters from vector areas of given category.
+
+   \param vector_map name of vector map
+   \param layer_name layer name (within vector map)
+   \param category vector category (cat column value)
+   \param[out] perimeters list of perimeters
+   \param band_region region which determines perimeter cells
+
+   \return 1 on success
+   \return 0 on error
+ */
+int vector2perimeters(struct Map_info *Map, const char *layer_name,
+		      int category, IClass_perimeter_list * perimeters,
+		      struct Cell_head *band_region)
+{
+    struct line_pnts *points;
+
+    int nareas, nareas_cat, layer;
+
+    int i, cat, ret;
+
+    int j;
+
+    G_debug(3, "iclass_vector2perimeters():layer = %s, category = %d",
+	    layer_name, category);
+
+    layer = Vect_get_field_number(Map, layer_name);
+    nareas = Vect_get_num_areas(Map);
+    if (nareas == 0)
+	return 0;
+
+    nareas_cat = 0;
+    /* find out, how many areas have given category */
+    for (i = 1; i <= nareas; i++) {
+	cat = Vect_get_area_cat(Map, i, layer);
+	if (cat < 0) {
+	    // no centroid, no category
+	}
+	else if (cat == category) {
+	    nareas_cat++;
+	}
+    }
+
+    if (nareas_cat == 0)
+	return 0;
+
+    perimeters->nperimeters = nareas_cat;
+    perimeters->perimeters =
+	(IClass_perimeter *) G_calloc(nareas_cat, sizeof(IClass_perimeter));
+
+    j = 0;			// area with cat
+    for (i = 1; i <= nareas; i++) {
+
+	cat = Vect_get_area_cat(Map, i, layer);
+	if (cat < 0) {
+	    // no centroid, no category
+	}
+	else if (cat == category) {
+	    j++;
+
+	    points = Vect_new_line_struct();	// Vect_destroy_line_struct
+	    ret = Vect_get_area_points(Map, i, points);
+
+	    if (ret <= 0) {
+		Vect_destroy_line_struct(points);
+		free_perimeters(perimeters);
+		G_warning(_("Get area %d failed"), i);
+		return 0;
+	    }
+	    if (make_perimeter
+		(points, &perimeters->perimeters[j - 1], band_region) <= 0) {
+		Vect_destroy_line_struct(points);
+		free_perimeters(perimeters);
+		G_warning(_("Perimeter computation failed"));
+		return 0;
+	    }
+	    Vect_destroy_line_struct(points);
+	}
+
+    }
+
+    //Vect_close(&Map);
+
+    return 1;
+}
+
+/*!
+   \brief Frees all perimeters in list of perimeters.
+
+   It also frees list of perimeters itself.
+
+   \param perimeters list of perimeters
+ */
+void free_perimeters(IClass_perimeter_list * perimeters)
+{
+    int i;
+
+    G_debug(5, "free_perimeters()");
+
+    for (i = 0; i < perimeters->nperimeters; i++) {
+	G_free(perimeters->perimeters[i].points);
+    }
+    G_free(perimeters->perimeters);
+}
+
+/*!
+   \brief Creates one perimeter from vector area.
+
+   \param points list of vertices represting area
+   \param[out] perimeter perimeter
+   \param band_region region which determines perimeter cells
+
+   \return 1 on success
+   \return 0 on error
+ */
+int make_perimeter(struct line_pnts *points, IClass_perimeter * perimeter,
+		   struct Cell_head *band_region)
+{
+    IClass_point *tmp_points;
+
+    IClass_point *vertex_points;
+
+    int i, first, prev, skip, next;
+
+    int count, vertex_count;
+
+    int np;			/* perimeter estimate */
+
+    G_debug(5, "iclass_make_perimeter()");
+    count = points->n_points;
+
+    tmp_points = (IClass_point *) G_calloc(count, sizeof(IClass_point));	/* TODO test */
+
+    for (i = 0; i < count; i++) {
+	G_debug(5, "iclass_make_perimeter(): points: x: %f y: %f",
+		points->x[i], points->y[i]);
+	tmp_points[i].y = Rast_northing_to_row(points->y[i], band_region);
+	tmp_points[i].x = Rast_easting_to_col(points->x[i], band_region);
+    }
+
+    /* find first edge which is not horizontal */
+
+    first = -1;
+    prev = count - 1;
+    for (i = 0; i < count; prev = i++) {
+	/* non absurd polygon has vertexes with different y coordinate */
+	if (tmp_points[i].y != tmp_points[prev].y) {
+	    first = i;
+	    break;
+	}
+    }
+    if (first < 0) {
+	G_free(tmp_points);
+	G_warning(_("Absurd polygon."));
+	return 0;
+    }
+
+    /* copy tmp to vertex list collapsing adjacent horizontal edges */
+
+    /* vertex_count <= count, size of vertex_points is count */
+    vertex_points = (IClass_point *) G_calloc(count, sizeof(IClass_point));	/* TODO test */
+    skip = 0;
+    vertex_count = 0;
+    i = first;			/* stmt not necssary */
+
+    do {
+	if (!skip) {
+	    vertex_points[vertex_count].x = tmp_points[i].x;
+	    vertex_points[vertex_count].y = tmp_points[i].y;
+	    vertex_count++;
+	}
+
+	prev = i++;
+	if (i >= count)
+	    i = 0;
+	if ((next = i + 1) >= count)
+	    next = 0;
+
+	skip = ((tmp_points[prev].y == tmp_points[i].y) &&
+		(tmp_points[next].y == tmp_points[i].y));
+    }
+    while (i != first);
+
+    G_free(tmp_points);
+
+    /* count points on the perimeter */
+
+    np = 0;
+    prev = vertex_count - 1;
+    for (i = 0; i < vertex_count; prev = i++) {
+	np += abs(vertex_points[prev].y - vertex_points[i].y);
+    }
+
+    /* allocate perimeter list */
+
+    perimeter->points = (IClass_point *) G_calloc(np, sizeof(IClass_point));
+    if (!perimeter->points) {
+	G_free(vertex_points);
+	G_warning(_("Outlined area is too large."));
+	return 0;
+    }
+
+    /* store the perimeter points */
+
+    perimeter->npoints = 0;
+    prev = vertex_count - 1;
+    for (i = 0; i < vertex_count; prev = i++) {
+	edge2perimeter(perimeter, vertex_points[prev].x,
+		       vertex_points[prev].y, vertex_points[i].x,
+		       vertex_points[i].y);
+    }
+
+    /*
+     * now decide which verticies should be included
+     *    local extrema are excluded
+     *    local non-extrema are included
+     *    verticies of horizontal edges which are pseudo-extrema
+     *      are excluded.
+     *    one vertex of horizontal edges which are pseudo-non-extrema
+     *      are included.
+     */
+
+    prev = vertex_count - 1;
+    i = 0;
+    do {
+	next = i + 1;
+	if (next >= vertex_count)
+	    next = 0;
+
+	if (extrema
+	    (vertex_points[prev].y, vertex_points[i].y,
+	     vertex_points[next].y))
+	    skip = 1;
+	else if (non_extrema
+		 (vertex_points[prev].y, vertex_points[i].y,
+		  vertex_points[next].y))
+	    skip = 0;
+	else {
+	    skip = 0;
+	    if (++next >= vertex_count)
+		next = 0;
+	    if (extrema
+		(vertex_points[prev].y, vertex_points[i].y,
+		 vertex_points[next].y))
+		skip = 1;
+	}
+
+	if (!skip)
+	    perimeter_add_point(perimeter, vertex_points[i].x,
+				vertex_points[i].y);
+
+	i = next;
+	prev = i - 1;
+    }
+    while (i != 0);
+
+    G_free(vertex_points);
+
+    /* sort the edge points by row and then by col */
+    qsort(perimeter->points, (size_t) perimeter->npoints,
+	  sizeof(IClass_point), edge_order);
+
+    return 1;
+
+}
+
+/*!
+   \brief Converts edge to cells.
+
+   It rasterizes edge given by two vertices.
+   Resterized points are added to perimeter.
+
+   \param perimeter perimeter
+   \param x0,y0 first edge point row and cell
+   \param x1,y1 second edge point row and cell
+
+   \return 1 on success
+   \return 0 on error
+ */
+int edge2perimeter(IClass_perimeter * perimeter, int x0, int y0, int x1,
+		   int y1)
+{
+    float m;
+
+    float x;
+
+    if (y0 == y1)
+	return 0;
+
+    x = x0;
+    m = (float)(x0 - x1) / (float)(y0 - y1);
+
+    if (y0 < y1) {
+	while (++y0 < y1) {
+	    x0 = (x += m) + .5;
+	    perimeter_add_point(perimeter, x0, y0);
+	}
+    }
+    else {
+	while (--y0 > y1) {
+	    x0 = (x -= m) + .5;
+	    perimeter_add_point(perimeter, x0, y0);
+	}
+    }
+
+    return 1;
+}
+
+/*!
+   \brief Adds point to perimeter.
+
+   \a perimeter has to have allocated space for \c points memeber.
+
+   \param perimeter perimeter
+   \param x,y point row and cell
+ */
+void perimeter_add_point(IClass_perimeter * perimeter, int x, int y)
+{
+    int n;
+
+    G_debug(5, "perimeter_add_point(): x: %d, y: %d", x, y);
+
+    n = perimeter->npoints++;
+    perimeter->points[n].x = x;
+    perimeter->points[n].y = y;
+}
+
+/*!
+   \brief Determines points order during sorting.
+
+   \param aa first IClass_point
+   \param bb second IClass_point
+ */
+int edge_order(const void *aa, const void *bb)
+{
+    const IClass_point *a = aa;
+
+    const IClass_point *b = bb;
+
+    if (a->y < b->y)
+	return -1;
+    if (a->y > b->y)
+	return 1;
+
+    if (a->x < b->x)
+	return -1;
+    if (a->x > b->x)
+	return 1;
+
+    return 0;
+}

Added: grass/trunk/lib/imagery/iclass_signatures.c
===================================================================
--- grass/trunk/lib/imagery/iclass_signatures.c	                        (rev 0)
+++ grass/trunk/lib/imagery/iclass_signatures.c	2011-12-18 19:05:04 UTC (rev 49813)
@@ -0,0 +1,128 @@
+/*!
+   \file lib/imagery/iclass_statistics.c
+
+   \brief Imagery library - functions for wx.iclass
+
+   Computation based on training areas for supervised classification.
+   Based on i.class module (GRASS 6).
+
+   Computation and writing signatures to file.
+
+   Copyright (C) 1999-2007, 2011 by the GRASS Development Team
+
+   This program is free software under the GNU General Public License
+   (>=v2).  Read the file COPYING that comes with GRASS for details.
+
+   \author David Satnik, Central Washington University (original author)
+   \author Markus Neteler <neteler itc.it> (i.class module)
+   \author Bernhard Reiter <bernhard intevation.de> (i.class module)
+   \author Brad Douglas <rez touchofmadness.com>(i.class module)
+   \author Glynn Clements <glynn gclements.plus.com> (i.class module)
+   \author Hamish Bowman <hamish_b yahoo.com> (i.class module)
+   \author Jan-Oliver Wagner <jan intevation.de> (i.class module)
+   \author Anna Kratochvilova <kratochanna gmail.com> (rewriting for wx.iclass)
+   \author Vaclav Petras <wenzeslaus gmail.com> (rewriting for wx.iclass)
+ */
+
+#include <string.h>
+#include <stdio.h>
+
+#include <grass/imagery.h>
+#include <grass/glocale.h>
+#include <grass/colors.h>
+
+#include "iclass_local_proto.h"
+
+
+
+/*!
+   \brief Initialize signatures.
+
+   \param[out] sigs pointer to signatures
+   \param refer pointer to band files structure
+
+   \return 1 on success
+   \return 0 on failure
+ */
+int I_iclass_init_signatures(struct Signature *sigs, struct Ref *refer)
+{
+    G_debug(3, "I_iclass_init_signatures()");
+
+    if (!I_init_signatures(sigs, refer->nfiles))
+	return 1;		// success
+
+    return 0;
+}
+
+/*!
+   \brief Add one signature.
+
+   \param[out] sigs pointer to signatures
+   \param statistics pointer to statistics structure
+ */
+void I_iclass_add_signature(struct Signature *sigs,
+			    IClass_statistics * statistics)
+{
+    int sn;
+
+    int b1, b2;
+
+    int r, g, b;
+
+    G_debug(3, "I_iclass_add_signature()");
+
+    G_str_to_color(statistics->color, &r, &g, &b);
+
+    /* get a new signature */
+    I_new_signature(sigs);
+
+    /* save the signature in a Sig structure */
+    sn = sigs->nsigs;
+    strcpy(sigs->sig[sn - 1].desc, statistics->name);
+    sigs->sig[sn - 1].npoints = statistics->ncells;
+    sigs->sig[sn - 1].status = 1;
+
+    sigs->sig[sn - 1].have_color = 1;
+    sigs->sig[sn - 1].r = r;
+    sigs->sig[sn - 1].g = g;
+    sigs->sig[sn - 1].b = b;
+
+    for (b1 = 0; b1 < sigs->nbands; b1++) {
+	sigs->sig[sn - 1].mean[b1] = statistics->band_mean[b1];
+	for (b2 = 0; b2 <= b1; b2++) {
+	    sigs->sig[sn - 1].var[b1][b2] = var_signature(statistics, b1, b2);
+	}
+    }
+}
+
+/*!
+   \brief Write signtures to signature file.
+
+   \param sigs pointer to signatures
+   \param group image group
+   \param sub_group image subgroup
+   \param file_name name of signature file
+
+   \return 1 on success
+   \return 0 on failure
+ */
+int I_iclass_write_signatures(struct Signature *sigs, const char *group,
+			      const char *sub_group, const char *file_name)
+{
+    FILE *outsig_fd;
+
+    G_debug(3, "I_write_signatures(): group=%s, file_name=%s", group,
+	    file_name);
+
+    if (!
+	(outsig_fd =
+	 I_fopen_signature_file_new(group, sub_group, file_name))) {
+	G_warning(_("Unable to open output signature file '%s'"), file_name);
+	return 0;
+    }
+
+    I_write_signatures(outsig_fd, sigs);
+    fclose(outsig_fd);
+
+    return 1;
+}

Added: grass/trunk/lib/imagery/iclass_statistics.c
===================================================================
--- grass/trunk/lib/imagery/iclass_statistics.c	                        (rev 0)
+++ grass/trunk/lib/imagery/iclass_statistics.c	2011-12-18 19:05:04 UTC (rev 49813)
@@ -0,0 +1,764 @@
+/*!
+   \file lib/imagery/iclass_statistics.c
+
+   \brief Imagery library - functions for wx.iclass
+
+   Computation based on training areas for supervised classification.
+   Based on i.class module (GRASS 6).
+
+   Computing statistical values (mean, min, max, ...) from given area
+   perimeters for each band.
+
+   Copyright (C) 1999-2007, 2011 by the GRASS Development Team
+
+   This program is free software under the GNU General Public License
+   (>=v2).  Read the file COPYING that comes with GRASS for details.
+
+   \author David Satnik, Central Washington University (original author)
+   \author Markus Neteler <neteler itc.it> (i.class module)
+   \author Bernhard Reiter <bernhard intevation.de> (i.class module)
+   \author Brad Douglas <rez touchofmadness.com>(i.class module)
+   \author Glynn Clements <glynn gclements.plus.com> (i.class module)
+   \author Hamish Bowman <hamish_b yahoo.com> (i.class module)
+   \author Jan-Oliver Wagner <jan intevation.de> (i.class module)
+   \author Anna Kratochvilova <kratochanna gmail.com> (rewriting for wx.iclass)
+   \author Vaclav Petras <wenzeslaus gmail.com> (rewriting for wx.iclass)
+ */
+
+#include <math.h>
+
+#include <grass/imagery.h>
+#include <grass/glocale.h>
+#include <grass/colors.h>
+
+#include "iclass_local_proto.h"
+
+/*!
+   \brief Initialize statistics.
+
+   \param[out] statistics pointer to statistics structure
+   \param category category (class)
+   \param name class name
+   \param color class color
+   \param nstd standard deviation
+ */
+void I_iclass_init_statistics(IClass_statistics * statistics, int category,
+			      const char *name, const char *color, float nstd)
+{
+    G_debug(4, "init_statistics() category=%d, name=%s, color=%s, nstd=%f",
+	    category, name, color, nstd);
+
+    statistics->cat = category;
+    statistics->name = G_store(name);
+    statistics->color = G_store(color);
+    statistics->nstd = nstd;
+
+    statistics->ncells = 0;
+    statistics->nbands = 0;
+
+    statistics->band_min = NULL;
+    statistics->band_max = NULL;
+    statistics->band_sum = NULL;
+    statistics->band_mean = NULL;
+    statistics->band_stddev = NULL;
+    statistics->band_product = NULL;
+    statistics->band_histo = NULL;
+    statistics->band_range_min = NULL;
+    statistics->band_range_max = NULL;
+}
+
+/*!
+   \brief Allocate space for statistics.
+
+   \param statistics pointer to statistics structure
+   \param nbands number of band files
+ */
+void alloc_statistics(IClass_statistics * statistics, int nbands)
+{
+    int i;
+
+    G_debug(4, "alloc_statistics()");
+
+    statistics->nbands = nbands;
+
+    statistics->band_min = (int *)G_calloc(nbands, sizeof(int));
+    statistics->band_max = (int *)G_calloc(nbands, sizeof(int));
+    statistics->band_sum = (float *)G_calloc(nbands, sizeof(float));
+    statistics->band_mean = (float *)G_calloc(nbands, sizeof(float));
+    statistics->band_stddev = (float *)G_calloc(nbands, sizeof(float));
+    statistics->band_product = (float **)G_calloc(nbands, sizeof(float *));
+    statistics->band_histo = (int **)G_calloc(nbands, sizeof(int *));
+    statistics->band_range_min = (int *)G_calloc(nbands, sizeof(int));
+    statistics->band_range_max = (int *)G_calloc(nbands, sizeof(int));
+
+    for (i = 0; i < nbands; i++) {
+	statistics->band_product[i] =
+	    (float *)G_calloc(nbands, sizeof(float));
+	statistics->band_histo[i] = (int *)G_calloc(MAX_CATS, sizeof(int));
+    }
+}
+
+/*!
+   \brief Free space allocated for statistics attributes.
+
+   Frees all allocated arrays in statistics structure.
+
+   \param statistics pointer to statistics structure
+   \param nbands number of band files
+ */
+void I_iclass_free_statistics(IClass_statistics * statistics)
+{
+    int i;
+
+    G_debug(4, "free_statistics()");
+
+    G_free(statistics->name);
+    G_free(statistics->color);
+    G_free(statistics->band_min);
+    G_free(statistics->band_max);
+    G_free(statistics->band_sum);
+    G_free(statistics->band_mean);
+    G_free(statistics->band_stddev);
+    G_free(statistics->band_range_max);
+    G_free(statistics->band_range_min);
+
+
+    for (i = 0; i < statistics->nbands; i++) {
+	G_free(statistics->band_histo[i]);
+	G_free(statistics->band_product[i]);
+    }
+    G_free(statistics->band_histo);
+    G_free(statistics->band_product);
+}
+
+/*!
+   \brief Calculate statistics for all training areas.
+
+   \param statistics pointer to statistics structure
+   \param perimeters list of all area perimeters
+   \param band_buffer buffer to read band rows into
+   \param band_fd band files descriptors
+
+   \return 1 on succes
+   \return 0 on failure
+ */
+int make_all_statistics(IClass_statistics * statistics,
+			IClass_perimeter_list * perimeters,
+			CELL ** band_buffer, int *band_fd)
+{
+    int i, b, b2, nbands;
+
+    float mean_value, stddev_value;
+
+    G_debug(5, "make_all_statistics()");
+
+    nbands = statistics->nbands;
+    for (b = 0; b < nbands; b++) {
+	statistics->band_sum[b] = 0.0;
+	statistics->band_min[b] = MAX_CATS;
+	statistics->band_max[b] = 0;
+	for (b2 = 0; b2 < nbands; b2++)
+	    statistics->band_product[b][b2] = 0.0;
+	for (b2 = 0; b2 < MAX_CATS; b2++)
+	    statistics->band_histo[b][b2] = 0;
+    }
+
+    for (i = 0; i < perimeters->nperimeters; i++) {
+	if (!make_statistics
+	    (statistics, &perimeters->perimeters[i], band_buffer, band_fd)) {
+	    return 0;
+	}
+    }
+    for (b = 0; b < statistics->nbands; b++) {
+	mean_value = mean(statistics, b);
+	stddev_value = stddev(statistics, b);
+
+	statistics->band_stddev[b] = stddev_value;
+	statistics->band_mean[b] = mean_value;
+
+	band_range(statistics, b);
+    }
+
+    return 1;
+}
+
+/*!
+   \brief Calculate statistics for one training area.
+
+   \param statistics[out] pointer to statistics structure
+   \param perimeter area perimeter
+   \param band_buffer buffer to read band rows into
+   \param band_fd band files descriptors
+
+   \return 1 on succes
+   \return 0 on failure
+ */
+int make_statistics(IClass_statistics * statistics,
+		    IClass_perimeter * perimeter, CELL ** band_buffer,
+		    int *band_fd)
+{
+    int b, b2;
+
+    int value;
+
+    int i;
+
+    int x0, x1;
+
+    int x, y;
+
+    int ncells;
+
+    int nbands;
+
+    G_debug(5, "make_statistics()");
+
+    nbands = statistics->nbands;
+
+    if (perimeter->npoints % 2) {
+	G_warning(_("prepare_signature: outline has odd number of points."));
+	return 0;
+    }
+
+    ncells = 0;
+
+    for (i = 1; i < perimeter->npoints; i += 2) {
+	y = perimeter->points[i].y;
+	if (y != perimeter->points[i - 1].y) {
+	    G_warning(_("prepare_signature: scan line %d has odd number of points."),
+		      (i + 1) / 2);
+	    return 0;
+	}
+	read_band_row(band_buffer, band_fd, nbands, y);
+
+	x0 = perimeter->points[i - 1].x - 1;
+	x1 = perimeter->points[i].x - 1;
+
+	if (x0 > x1) {
+	    G_warning(_("signature: perimeter points out of order."));
+	    return 0;
+	}
+
+	for (x = x0; x <= x1; x++) {
+	    ncells++;		/* count interior points */
+	    for (b = 0; b < nbands; b++) {
+		value = band_buffer[b][x];
+		G_debug(5, "make_statistics() read value: %d", value);
+		if (value < 0 || value > MAX_CATS - 1) {
+		    G_warning(_("prepare_signature: data error."));
+		    return 0;
+		}
+		statistics->band_sum[b] += value;	/* sum for means */
+		statistics->band_histo[b][value]++;	/* histogram */
+		if (statistics->band_min[b] > value)
+		    statistics->band_min[b] = value;	/* absolute min, max */
+		if (statistics->band_max[b] < value) {
+		    statistics->band_max[b] = value;
+		    G_debug(5,
+			    "make_statistics() statistics->band_max[%d]: %d",
+			    b, statistics->band_max[b]);
+		}
+
+		for (b2 = 0; b2 <= b; b2++)	/* products for variance */
+		    statistics->band_product[b][b2] +=
+			value * band_buffer[b2][x];
+	    }
+	}
+    }
+    statistics->ncells += ncells;
+
+    return 1;
+}
+
+/*!
+   \brief Create raster map based on statistics.
+
+   \param statistics pointer to statistics structure
+   \param band_buffer buffer to read band rows into
+   \param band_fd band files descriptors
+   \param raster_name name of new raster map
+ */
+void create_raster(IClass_statistics * statistics, CELL ** band_buffer,
+		   int *band_fd, const char *raster_name)
+{
+    int fd;
+
+    CELL *buffer;
+
+    int n;
+
+    int col;
+
+    int nbands;
+
+    int row, nrows, ncols;
+
+    struct Colors raster_colors;
+
+    int r, g, b;
+
+    int cell_in_ranges;
+
+    nbands = statistics->nbands;
+
+    /* build new raster based on current signature and Nstd */
+
+    fd = Rast_open_c_new(raster_name);
+    buffer = Rast_allocate_c_buf();
+    nrows = Rast_window_rows();
+    ncols = Rast_window_cols();
+
+    for (row = 0; row < nrows; row++) {
+	read_band_row(band_buffer, band_fd, nbands, row);
+	for (col = 0; col < ncols; col++) {
+	    buffer[col] = (CELL) 0;
+	    cell_in_ranges = 1;
+	    for (n = 0; n < nbands; n++) {
+		if (band_buffer[n][col] < statistics->band_range_min[n] ||
+		    band_buffer[n][col] > statistics->band_range_max[n]) {
+		    /* out of at least 1 range */
+		    cell_in_ranges = 0;
+		}
+	    }
+	    if (cell_in_ranges) {
+		/* if in range do the assignment */
+		buffer[col] = (CELL) 1;
+	    }
+	}
+	Rast_put_row(fd, buffer, CELL_TYPE);
+    }
+    Rast_close(fd);
+
+    /* generate and write the color table for the mask */
+    Rast_init_colors(&raster_colors);
+    G_str_to_color(statistics->color, &r, &g, &b);
+    Rast_set_c_color((CELL) 1, r, g, b, &raster_colors);
+    Rast_write_colors(raster_name, G_mapset(), &raster_colors);
+}
+
+/* helpers */
+/*!
+   \brief Helper function for computing min and max range in one band.
+
+   Computing min and max range value (distance from mean
+   dependent on number od std ddevs).
+
+   \param statistics pointer to statistics structure
+   \param band band index
+ */
+void band_range(IClass_statistics * statistics, int band)
+{
+    float dist;
+
+    dist = statistics->nstd * statistics->band_stddev[band];
+    statistics->band_range_min[band] =
+	statistics->band_mean[band] - dist + 0.5;
+    statistics->band_range_max[band] =
+	statistics->band_mean[band] + dist + 0.5;
+}
+
+/*!
+   \brief Helper function for computing mean.
+
+   Computing mean value of cell category values
+   in one band within training area.
+
+   \param statistics pointer to statistics structure
+   \param band band index
+
+   \return mean value
+ */
+float mean(IClass_statistics * statistics, int band)
+{
+    return statistics->band_sum[band] / statistics->ncells;
+}
+
+/*!
+   \brief Helper function for standard deviation.
+
+   Computing standard deviation of cell category values
+   in one band within training area.
+
+   \param statistics pointer to statistics structure
+   \param band band index
+
+   \return standard deviation
+ */
+float stddev(IClass_statistics * statistics, int band)
+{
+    return sqrt(var(statistics, band, band));
+}
+
+/*!
+   \brief Helper function for computing variance.
+
+   Computing variance of cell category values
+   in one band within training area.
+
+   \param statistics pointer to statistics structure
+   \param band1 band index
+   \param band2 band index
+
+   \return variance
+
+   \see var_signature
+ */
+float var(IClass_statistics * statistics, int band1, int band2)
+{
+    float product;
+
+    float mean1, mean2;
+
+    int n;
+
+    product = statistics->band_product[band1][band2];
+    mean1 = mean(statistics, band1);
+    mean2 = mean(statistics, band2);
+    n = statistics->ncells;
+
+    return product / n - mean1 * mean2;
+}
+
+/*!
+   \brief Helper function for computing variance for signature file.
+
+   Computing variance of cell category values
+   in one band within training area. Variance is computed
+   in special way.
+
+   \param statistics pointer to statistics structure
+   \param band1 band index
+   \param band2 band index
+
+   \return variance
+
+   \see var
+
+   \todo verify the computation
+ */
+float var_signature(IClass_statistics * statistics, int band1, int band2)
+{
+    float product;
+
+    float sum1, sum2;
+
+    int n;
+
+    product = statistics->band_product[band1][band2];
+    sum1 = statistics->band_sum[band1];
+    sum2 = statistics->band_sum[band2];
+    n = statistics->ncells;
+
+    return (product - sum1 * sum2 / n) / (n - 1);
+}
+
+/* getters */
+/*!
+   \brief Get number of bands.
+
+   \param statistics pointer to statistics structure
+   \param[out] nbands number of bands
+ */
+void I_iclass_statistics_get_nbands(IClass_statistics * statistics,
+				    int *nbands)
+{
+    *nbands = statistics->nbands;
+}
+
+/*!
+   \brief Get category (class).
+
+   \param statistics pointer to statistics structure
+   \param[out] cat category
+ */
+void I_iclass_statistics_get_cat(IClass_statistics * statistics, int *cat)
+{
+    *cat = statistics->cat;
+}
+
+/*!
+   \brief Get category (class) name.
+
+   \note \a name is pointer to already allocated
+   const char * in \a statistics.
+   You should not free it.
+
+   \param statistics pointer to statistics structure
+   \param[out] name category name
+ */
+void I_iclass_statistics_get_name(IClass_statistics * statistics,
+				  const char **name)
+{
+    *name = statistics->name;
+}
+
+/*!
+   \brief Get category (class) color.
+
+   \note \a color is pointer to already allocated
+   const char * in \a statistics.
+   You should not free it.
+
+   \param statistics pointer to statistics structure
+   \param[out] color category color
+ */
+void I_iclass_statistics_get_color(IClass_statistics * statistics,
+				   const char **color)
+{
+    *color = statistics->color;
+}
+
+
+/*!
+   \brief Get number of cells in training areas.
+
+   \param statistics pointer to statistics structure
+   \param[out] ncells number of cells
+ */
+void I_iclass_statistics_get_ncells(IClass_statistics * statistics,
+				    int *ncells)
+{
+    *ncells = statistics->ncells;
+}
+
+/*!
+   \brief Get the multiplier of standard deviation.
+
+   \param statistics pointer to statistics structure
+   \param[out] nstd multiplier of standard deviation
+ */
+void I_iclass_statistics_get_nstd(IClass_statistics * statistics, float *nstd)
+{
+    *nstd = statistics->nstd;
+}
+
+/*!
+   \brief Set the multiplier of standard deviation.
+
+   \param statistics pointer to statistics structure
+   \param nstd multiplier of standard deviation
+ */
+void I_iclass_statistics_set_nstd(IClass_statistics * statistics, float nstd)
+{
+    statistics->nstd = nstd;
+}
+
+/*!
+   \brief Get minimum value in band.
+
+   \param statistics pointer to statistics structure
+   \param band band index
+   \param[out] min minimum value
+
+   \return 1 on success
+   \return 0 band index out of range
+ */
+int I_iclass_statistics_get_min(IClass_statistics * statistics, int band,
+				int *min)
+{
+    if (band >= statistics->nbands) {
+	G_warning(_("Band index out of range"));
+	return 0;
+    }
+
+    *min = statistics->band_min[band];
+
+    return 1;
+}
+
+/*!
+   \brief Get maximum value in band.
+
+   \param statistics pointer to statistics structure
+   \param band band index
+   \param[out] max maximum value
+
+   \return 1 on success
+   \return 0 band index out of range
+ */
+int I_iclass_statistics_get_max(IClass_statistics * statistics, int band,
+				int *max)
+{
+    if (band >= statistics->nbands) {
+	G_warning(_("Band index out of range"));
+	return 0;
+    }
+
+    *max = statistics->band_max[band];
+
+    return 1;
+}
+
+/*!
+   \brief Get sum of values in band.
+
+   \param statistics pointer to statistics structure
+   \param band band index
+   \param[out] sum sum
+
+   \return 1 on success
+   \return 0 band index out of range
+ */
+int I_iclass_statistics_get_sum(IClass_statistics * statistics, int band,
+				float *sum)
+{
+    if (band >= statistics->nbands) {
+	G_warning(_("Band index out of range"));
+	return 0;
+    }
+
+    *sum = statistics->band_sum[band];
+
+    return 1;
+}
+
+/*!
+   \brief Get mean of cell category values in band.
+
+   \param statistics pointer to statistics structure
+   \param band band index
+   \param[out] mean mean
+
+   \return 1 on success
+   \return 0 band index out of range
+ */
+int I_iclass_statistics_get_mean(IClass_statistics * statistics, int band,
+				 float *mean)
+{
+    if (band >= statistics->nbands) {
+	G_warning(_("Band index out of range"));
+	return 0;
+    }
+
+    *mean = statistics->band_mean[band];
+
+    return 1;
+}
+
+/*!
+   \brief Get standard deviation of cell category values in band.
+
+   \param statistics pointer to statistics structure
+   \param band band index
+   \param[out] stddev standard deviation
+
+   \return 1 on success
+   \return 0 band index out of range
+ */
+int I_iclass_statistics_get_stddev(IClass_statistics * statistics, int band,
+				   float *stddev)
+{
+    if (band >= statistics->nbands) {
+	G_warning(_("Band index out of range"));
+	return 0;
+    }
+
+    *stddev = statistics->band_stddev[band];
+
+    return 1;
+}
+
+/*!
+   \brief Get histogram value in band.
+
+   Each band has one value for each raster cell category.
+   Value is number of cells in category.
+
+   \param statistics pointer to statistics structure
+   \param band band index
+   \param cat raster cell category
+   \param[out] value number of cells in category
+
+   \return 1 on success
+   \return 0 band index or cell category value out of range
+ */
+int I_iclass_statistics_get_histo(IClass_statistics * statistics, int band,
+				  int cat, int *value)
+{
+    if (band >= statistics->nbands) {
+	G_warning(_("Band index out of range"));
+	return 0;
+    }
+    if (cat >= MAX_CATS) {
+	G_warning(_("Cell category value out of range"));
+	return 0;
+    }
+
+    *value = statistics->band_histo[band][cat];
+
+    return 1;
+}
+
+/*!
+   \brief Get product value
+
+   Product value of two bands is sum of products
+   of cell category values of two bands.
+   Only cells from training areas are taken into account.
+
+   \param statistics statistics object
+   \param band1 index of first band
+   \param band2 index of second band
+   \param[out] value product value
+
+   \return 1 on success
+   \return 0 band index out of range
+ */
+int I_iclass_statistics_get_product(IClass_statistics * statistics, int band1,
+				    int band2, float *value)
+{
+    if (band1 >= statistics->nbands || band2 >= statistics->nbands) {
+	G_warning(_("Band index out of range"));
+	return 0;
+    }
+
+    *value = statistics->band_product[band1][band2];
+
+    return 1;
+}
+
+/*!
+   \brief Get minimum cell value based on mean and standard deviation for band.
+
+   \param statistics pointer to statistics structure
+   \param band band index
+   \param[out] min minumum value
+
+   \return 1 on success
+   \return 0 band index out of range
+ */
+int I_iclass_statistics_get_range_min(IClass_statistics * statistics,
+				      int band, int *min)
+{
+    if (band >= statistics->nbands) {
+	G_warning(_("Band index out of range"));
+	return 0;
+    }
+
+    *min = statistics->band_range_min[band];
+
+    return 1;
+}
+
+/*!
+   \brief Get maximum cell value based on mean and standard deviation for band.
+
+   \param statistics pointer to statistics structure
+   \param band band index
+   \param[out] max maximum value
+
+   \return 1 on success
+   \return 0 band index out of range
+ */
+int I_iclass_statistics_get_range_max(IClass_statistics * statistics,
+				      int band, int *max)
+{
+    if (band >= statistics->nbands) {
+	G_warning(_("Band index out of range"));
+	return 0;
+    }
+
+    *max = statistics->band_range_max[band];
+
+    return 1;
+}



More information about the grass-commit mailing list