[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