iclass_statistics.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765
  1. /*!
  2. \file lib/imagery/iclass_statistics.c
  3. \brief Imagery library - functions for wx.iclass
  4. Computation based on training areas for supervised classification.
  5. Based on i.class module (GRASS 6).
  6. Computing statistical values (mean, min, max, ...) from given area
  7. perimeters for each band.
  8. Copyright (C) 1999-2007, 2011 by the GRASS Development Team
  9. This program is free software under the GNU General Public License
  10. (>=v2). Read the file COPYING that comes with GRASS for details.
  11. \author David Satnik, Central Washington University (original author)
  12. \author Markus Neteler <neteler itc.it> (i.class module)
  13. \author Bernhard Reiter <bernhard intevation.de> (i.class module)
  14. \author Brad Douglas <rez touchofmadness.com>(i.class module)
  15. \author Glynn Clements <glynn gclements.plus.com> (i.class module)
  16. \author Hamish Bowman <hamish_b yahoo.com> (i.class module)
  17. \author Jan-Oliver Wagner <jan intevation.de> (i.class module)
  18. \author Anna Kratochvilova <kratochanna gmail.com> (rewriting for wx.iclass)
  19. \author Vaclav Petras <wenzeslaus gmail.com> (rewriting for wx.iclass)
  20. */
  21. #include <math.h>
  22. #include <grass/imagery.h>
  23. #include <grass/glocale.h>
  24. #include <grass/colors.h>
  25. #include "iclass_local_proto.h"
  26. /*!
  27. \brief Initialize statistics.
  28. \param[out] statistics pointer to statistics structure
  29. \param category category (class)
  30. \param name class name
  31. \param color class color
  32. \param nstd standard deviation
  33. */
  34. void I_iclass_init_statistics(IClass_statistics * statistics, int category,
  35. const char *name, const char *color, float nstd)
  36. {
  37. G_debug(4, "init_statistics() category=%d, name=%s, color=%s, nstd=%f",
  38. category, name, color, nstd);
  39. statistics->cat = category;
  40. statistics->name = G_store(name);
  41. statistics->color = G_store(color);
  42. statistics->nstd = nstd;
  43. statistics->ncells = 0;
  44. statistics->nbands = 0;
  45. statistics->band_min = NULL;
  46. statistics->band_max = NULL;
  47. statistics->band_sum = NULL;
  48. statistics->band_mean = NULL;
  49. statistics->band_stddev = NULL;
  50. statistics->band_product = NULL;
  51. statistics->band_histo = NULL;
  52. statistics->band_range_min = NULL;
  53. statistics->band_range_max = NULL;
  54. }
  55. /*!
  56. \brief Allocate space for statistics.
  57. \param statistics pointer to statistics structure
  58. \param nbands number of band files
  59. */
  60. void alloc_statistics(IClass_statistics * statistics, int nbands)
  61. {
  62. int i;
  63. G_debug(4, "alloc_statistics()");
  64. statistics->nbands = nbands;
  65. statistics->band_min = (int *)G_calloc(nbands, sizeof(int));
  66. statistics->band_max = (int *)G_calloc(nbands, sizeof(int));
  67. statistics->band_sum = (float *)G_calloc(nbands, sizeof(float));
  68. statistics->band_mean = (float *)G_calloc(nbands, sizeof(float));
  69. statistics->band_stddev = (float *)G_calloc(nbands, sizeof(float));
  70. statistics->band_product = (float **)G_calloc(nbands, sizeof(float *));
  71. statistics->band_histo = (int **)G_calloc(nbands, sizeof(int *));
  72. statistics->band_range_min = (int *)G_calloc(nbands, sizeof(int));
  73. statistics->band_range_max = (int *)G_calloc(nbands, sizeof(int));
  74. for (i = 0; i < nbands; i++) {
  75. statistics->band_product[i] =
  76. (float *)G_calloc(nbands, sizeof(float));
  77. statistics->band_histo[i] = (int *)G_calloc(MAX_CATS, sizeof(int));
  78. }
  79. }
  80. /*!
  81. \brief Free space allocated for statistics attributes.
  82. Frees all allocated arrays in statistics structure.
  83. \param statistics pointer to statistics structure
  84. \param nbands number of band files
  85. */
  86. void I_iclass_free_statistics(IClass_statistics * statistics)
  87. {
  88. int i;
  89. G_debug(4, "free_statistics()");
  90. G_free(statistics->name);
  91. G_free(statistics->color);
  92. G_free(statistics->band_min);
  93. G_free(statistics->band_max);
  94. G_free(statistics->band_sum);
  95. G_free(statistics->band_mean);
  96. G_free(statistics->band_stddev);
  97. G_free(statistics->band_range_max);
  98. G_free(statistics->band_range_min);
  99. for (i = 0; i < statistics->nbands; i++) {
  100. G_free(statistics->band_histo[i]);
  101. G_free(statistics->band_product[i]);
  102. }
  103. G_free(statistics->band_histo);
  104. G_free(statistics->band_product);
  105. }
  106. /*!
  107. \brief Calculate statistics for all training areas.
  108. \param statistics pointer to statistics structure
  109. \param perimeters list of all area perimeters
  110. \param band_buffer buffer to read band rows into
  111. \param band_fd band files descriptors
  112. \return 1 on succes
  113. \return 0 on failure
  114. */
  115. int make_all_statistics(IClass_statistics * statistics,
  116. IClass_perimeter_list * perimeters,
  117. CELL ** band_buffer, int *band_fd)
  118. {
  119. int i, b, b2, nbands;
  120. float mean_value, stddev_value;
  121. G_debug(5, "make_all_statistics()");
  122. nbands = statistics->nbands;
  123. for (b = 0; b < nbands; b++) {
  124. statistics->band_sum[b] = 0.0;
  125. statistics->band_min[b] = MAX_CATS;
  126. statistics->band_max[b] = 0;
  127. for (b2 = 0; b2 < nbands; b2++)
  128. statistics->band_product[b][b2] = 0.0;
  129. for (b2 = 0; b2 < MAX_CATS; b2++)
  130. statistics->band_histo[b][b2] = 0;
  131. }
  132. for (i = 0; i < perimeters->nperimeters; i++) {
  133. if (!make_statistics
  134. (statistics, &perimeters->perimeters[i], band_buffer, band_fd)) {
  135. return 0;
  136. }
  137. }
  138. for (b = 0; b < statistics->nbands; b++) {
  139. mean_value = mean(statistics, b);
  140. stddev_value = stddev(statistics, b);
  141. statistics->band_stddev[b] = stddev_value;
  142. statistics->band_mean[b] = mean_value;
  143. band_range(statistics, b);
  144. }
  145. return 1;
  146. }
  147. /*!
  148. \brief Calculate statistics for one training area.
  149. \param statistics[out] pointer to statistics structure
  150. \param perimeter area perimeter
  151. \param band_buffer buffer to read band rows into
  152. \param band_fd band files descriptors
  153. \return 1 on succes
  154. \return 0 on failure
  155. */
  156. int make_statistics(IClass_statistics * statistics,
  157. IClass_perimeter * perimeter, CELL ** band_buffer,
  158. int *band_fd)
  159. {
  160. int b, b2;
  161. int value;
  162. int i;
  163. int x0, x1;
  164. int x, y;
  165. int ncells;
  166. int nbands;
  167. G_debug(5, "make_statistics()");
  168. nbands = statistics->nbands;
  169. if (perimeter->npoints % 2) {
  170. G_warning(_("prepare_signature: outline has odd number of points."));
  171. return 0;
  172. }
  173. ncells = 0;
  174. for (i = 1; i < perimeter->npoints; i += 2) {
  175. y = perimeter->points[i].y;
  176. if (y != perimeter->points[i - 1].y) {
  177. G_warning(_("prepare_signature: scan line %d has odd number of points."),
  178. (i + 1) / 2);
  179. return 0;
  180. }
  181. read_band_row(band_buffer, band_fd, nbands, y);
  182. x0 = perimeter->points[i - 1].x - 1;
  183. x1 = perimeter->points[i].x - 1;
  184. if (x0 > x1) {
  185. G_warning(_("signature: perimeter points out of order."));
  186. return 0;
  187. }
  188. for (x = x0; x <= x1; x++) {
  189. ncells++; /* count interior points */
  190. for (b = 0; b < nbands; b++) {
  191. value = band_buffer[b][x];
  192. G_debug(5, "make_statistics() read value: %d", value);
  193. if (value < 0 || value > MAX_CATS - 1) {
  194. G_warning(_("prepare_signature: data error."));
  195. return 0;
  196. }
  197. statistics->band_sum[b] += value; /* sum for means */
  198. statistics->band_histo[b][value]++; /* histogram */
  199. if (statistics->band_min[b] > value)
  200. statistics->band_min[b] = value; /* absolute min, max */
  201. if (statistics->band_max[b] < value) {
  202. statistics->band_max[b] = value;
  203. G_debug(5,
  204. "make_statistics() statistics->band_max[%d]: %d",
  205. b, statistics->band_max[b]);
  206. }
  207. for (b2 = 0; b2 <= b; b2++) /* products for variance */
  208. statistics->band_product[b][b2] +=
  209. value * band_buffer[b2][x];
  210. }
  211. }
  212. }
  213. statistics->ncells += ncells;
  214. return 1;
  215. }
  216. /*!
  217. \brief Create raster map based on statistics.
  218. \param statistics pointer to statistics structure
  219. \param band_buffer buffer to read band rows into
  220. \param band_fd band files descriptors
  221. \param raster_name name of new raster map
  222. */
  223. void create_raster(IClass_statistics * statistics, CELL ** band_buffer,
  224. int *band_fd, const char *raster_name)
  225. {
  226. int fd;
  227. CELL *buffer;
  228. int n;
  229. int col;
  230. int nbands;
  231. int row, nrows, ncols;
  232. struct Colors raster_colors;
  233. int r, g, b;
  234. int cell_in_ranges;
  235. nbands = statistics->nbands;
  236. /* build new raster based on current signature and Nstd */
  237. fd = Rast_open_c_new(raster_name);
  238. buffer = Rast_allocate_c_buf();
  239. nrows = Rast_window_rows();
  240. ncols = Rast_window_cols();
  241. for (row = 0; row < nrows; row++) {
  242. read_band_row(band_buffer, band_fd, nbands, row);
  243. for (col = 0; col < ncols; col++) {
  244. buffer[col] = (CELL) 0;
  245. cell_in_ranges = 1;
  246. for (n = 0; n < nbands; n++) {
  247. if (band_buffer[n][col] < statistics->band_range_min[n] ||
  248. band_buffer[n][col] > statistics->band_range_max[n]) {
  249. /* out of at least 1 range */
  250. cell_in_ranges = 0;
  251. }
  252. }
  253. if (cell_in_ranges) {
  254. /* if in range do the assignment */
  255. buffer[col] = (CELL) 1;
  256. }
  257. }
  258. Rast_put_row(fd, buffer, CELL_TYPE);
  259. }
  260. Rast_close(fd);
  261. /* generate and write the color table for the mask */
  262. Rast_init_colors(&raster_colors);
  263. G_str_to_color(statistics->color, &r, &g, &b);
  264. Rast_set_c_color((CELL) 1, r, g, b, &raster_colors);
  265. Rast_write_colors(raster_name, G_mapset(), &raster_colors);
  266. }
  267. /* helpers */
  268. /*!
  269. \brief Helper function for computing min and max range in one band.
  270. Computing min and max range value (distance from mean
  271. dependent on number od std ddevs).
  272. \param statistics pointer to statistics structure
  273. \param band band index
  274. */
  275. void band_range(IClass_statistics * statistics, int band)
  276. {
  277. float dist;
  278. dist = statistics->nstd * statistics->band_stddev[band];
  279. statistics->band_range_min[band] =
  280. statistics->band_mean[band] - dist + 0.5;
  281. statistics->band_range_max[band] =
  282. statistics->band_mean[band] + dist + 0.5;
  283. }
  284. /*!
  285. \brief Helper function for computing mean.
  286. Computing mean value of cell category values
  287. in one band within training area.
  288. \param statistics pointer to statistics structure
  289. \param band band index
  290. \return mean value
  291. */
  292. float mean(IClass_statistics * statistics, int band)
  293. {
  294. return statistics->band_sum[band] / statistics->ncells;
  295. }
  296. /*!
  297. \brief Helper function for standard deviation.
  298. Computing standard deviation of cell category values
  299. in one band within training area.
  300. \param statistics pointer to statistics structure
  301. \param band band index
  302. \return standard deviation
  303. */
  304. float stddev(IClass_statistics * statistics, int band)
  305. {
  306. return sqrt(var(statistics, band, band));
  307. }
  308. /*!
  309. \brief Helper function for computing variance.
  310. Computing variance of cell category values
  311. in one band within training area.
  312. \param statistics pointer to statistics structure
  313. \param band1 band index
  314. \param band2 band index
  315. \return variance
  316. \see var_signature
  317. */
  318. float var(IClass_statistics * statistics, int band1, int band2)
  319. {
  320. float product;
  321. float mean1, mean2;
  322. int n;
  323. product = statistics->band_product[band1][band2];
  324. mean1 = mean(statistics, band1);
  325. mean2 = mean(statistics, band2);
  326. n = statistics->ncells;
  327. return product / n - mean1 * mean2;
  328. }
  329. /*!
  330. \brief Helper function for computing variance for signature file.
  331. Computing variance of cell category values
  332. in one band within training area. Variance is computed
  333. in special way.
  334. \param statistics pointer to statistics structure
  335. \param band1 band index
  336. \param band2 band index
  337. \return variance
  338. \see var
  339. \todo verify the computation
  340. */
  341. float var_signature(IClass_statistics * statistics, int band1, int band2)
  342. {
  343. float product;
  344. float sum1, sum2;
  345. int n;
  346. product = statistics->band_product[band1][band2];
  347. sum1 = statistics->band_sum[band1];
  348. sum2 = statistics->band_sum[band2];
  349. n = statistics->ncells;
  350. return (product - sum1 * sum2 / n) / (n - 1);
  351. }
  352. /* getters */
  353. /*!
  354. \brief Get number of bands.
  355. \param statistics pointer to statistics structure
  356. \param[out] nbands number of bands
  357. */
  358. void I_iclass_statistics_get_nbands(IClass_statistics * statistics,
  359. int *nbands)
  360. {
  361. *nbands = statistics->nbands;
  362. }
  363. /*!
  364. \brief Get category (class).
  365. \param statistics pointer to statistics structure
  366. \param[out] cat category
  367. */
  368. void I_iclass_statistics_get_cat(IClass_statistics * statistics, int *cat)
  369. {
  370. *cat = statistics->cat;
  371. }
  372. /*!
  373. \brief Get category (class) name.
  374. \note \a name is pointer to already allocated
  375. const char * in \a statistics.
  376. You should not free it.
  377. \param statistics pointer to statistics structure
  378. \param[out] name category name
  379. */
  380. void I_iclass_statistics_get_name(IClass_statistics * statistics,
  381. const char **name)
  382. {
  383. *name = statistics->name;
  384. }
  385. /*!
  386. \brief Get category (class) color.
  387. \note \a color is pointer to already allocated
  388. const char * in \a statistics.
  389. You should not free it.
  390. \param statistics pointer to statistics structure
  391. \param[out] color category color
  392. */
  393. void I_iclass_statistics_get_color(IClass_statistics * statistics,
  394. const char **color)
  395. {
  396. *color = statistics->color;
  397. }
  398. /*!
  399. \brief Get number of cells in training areas.
  400. \param statistics pointer to statistics structure
  401. \param[out] ncells number of cells
  402. */
  403. void I_iclass_statistics_get_ncells(IClass_statistics * statistics,
  404. int *ncells)
  405. {
  406. *ncells = statistics->ncells;
  407. }
  408. /*!
  409. \brief Get the multiplier of standard deviation.
  410. \param statistics pointer to statistics structure
  411. \param[out] nstd multiplier of standard deviation
  412. */
  413. void I_iclass_statistics_get_nstd(IClass_statistics * statistics, float *nstd)
  414. {
  415. *nstd = statistics->nstd;
  416. }
  417. /*!
  418. \brief Set the multiplier of standard deviation.
  419. \param statistics pointer to statistics structure
  420. \param nstd multiplier of standard deviation
  421. */
  422. void I_iclass_statistics_set_nstd(IClass_statistics * statistics, float nstd)
  423. {
  424. statistics->nstd = nstd;
  425. }
  426. /*!
  427. \brief Get minimum value in band.
  428. \param statistics pointer to statistics structure
  429. \param band band index
  430. \param[out] min minimum value
  431. \return 1 on success
  432. \return 0 band index out of range
  433. */
  434. int I_iclass_statistics_get_min(IClass_statistics * statistics, int band,
  435. int *min)
  436. {
  437. if (band >= statistics->nbands) {
  438. G_warning(_("Band index out of range"));
  439. return 0;
  440. }
  441. *min = statistics->band_min[band];
  442. return 1;
  443. }
  444. /*!
  445. \brief Get maximum value in band.
  446. \param statistics pointer to statistics structure
  447. \param band band index
  448. \param[out] max maximum value
  449. \return 1 on success
  450. \return 0 band index out of range
  451. */
  452. int I_iclass_statistics_get_max(IClass_statistics * statistics, int band,
  453. int *max)
  454. {
  455. if (band >= statistics->nbands) {
  456. G_warning(_("Band index out of range"));
  457. return 0;
  458. }
  459. *max = statistics->band_max[band];
  460. return 1;
  461. }
  462. /*!
  463. \brief Get sum of values in band.
  464. \param statistics pointer to statistics structure
  465. \param band band index
  466. \param[out] sum sum
  467. \return 1 on success
  468. \return 0 band index out of range
  469. */
  470. int I_iclass_statistics_get_sum(IClass_statistics * statistics, int band,
  471. float *sum)
  472. {
  473. if (band >= statistics->nbands) {
  474. G_warning(_("Band index out of range"));
  475. return 0;
  476. }
  477. *sum = statistics->band_sum[band];
  478. return 1;
  479. }
  480. /*!
  481. \brief Get mean of cell category values in band.
  482. \param statistics pointer to statistics structure
  483. \param band band index
  484. \param[out] mean mean
  485. \return 1 on success
  486. \return 0 band index out of range
  487. */
  488. int I_iclass_statistics_get_mean(IClass_statistics * statistics, int band,
  489. float *mean)
  490. {
  491. if (band >= statistics->nbands) {
  492. G_warning(_("Band index out of range"));
  493. return 0;
  494. }
  495. *mean = statistics->band_mean[band];
  496. return 1;
  497. }
  498. /*!
  499. \brief Get standard deviation of cell category values in band.
  500. \param statistics pointer to statistics structure
  501. \param band band index
  502. \param[out] stddev standard deviation
  503. \return 1 on success
  504. \return 0 band index out of range
  505. */
  506. int I_iclass_statistics_get_stddev(IClass_statistics * statistics, int band,
  507. float *stddev)
  508. {
  509. if (band >= statistics->nbands) {
  510. G_warning(_("Band index out of range"));
  511. return 0;
  512. }
  513. *stddev = statistics->band_stddev[band];
  514. return 1;
  515. }
  516. /*!
  517. \brief Get histogram value in band.
  518. Each band has one value for each raster cell category.
  519. Value is number of cells in category.
  520. \param statistics pointer to statistics structure
  521. \param band band index
  522. \param cat raster cell category
  523. \param[out] value number of cells in category
  524. \return 1 on success
  525. \return 0 band index or cell category value out of range
  526. */
  527. int I_iclass_statistics_get_histo(IClass_statistics * statistics, int band,
  528. int cat, int *value)
  529. {
  530. if (band >= statistics->nbands) {
  531. G_warning(_("Band index out of range"));
  532. return 0;
  533. }
  534. if (cat >= MAX_CATS) {
  535. G_warning(_("Cell category value out of range"));
  536. return 0;
  537. }
  538. *value = statistics->band_histo[band][cat];
  539. return 1;
  540. }
  541. /*!
  542. \brief Get product value
  543. Product value of two bands is sum of products
  544. of cell category values of two bands.
  545. Only cells from training areas are taken into account.
  546. \param statistics statistics object
  547. \param band1 index of first band
  548. \param band2 index of second band
  549. \param[out] value product value
  550. \return 1 on success
  551. \return 0 band index out of range
  552. */
  553. int I_iclass_statistics_get_product(IClass_statistics * statistics, int band1,
  554. int band2, float *value)
  555. {
  556. if (band1 >= statistics->nbands || band2 >= statistics->nbands) {
  557. G_warning(_("Band index out of range"));
  558. return 0;
  559. }
  560. *value = statistics->band_product[band1][band2];
  561. return 1;
  562. }
  563. /*!
  564. \brief Get minimum cell value based on mean and standard deviation for band.
  565. \param statistics pointer to statistics structure
  566. \param band band index
  567. \param[out] min minumum value
  568. \return 1 on success
  569. \return 0 band index out of range
  570. */
  571. int I_iclass_statistics_get_range_min(IClass_statistics * statistics,
  572. int band, int *min)
  573. {
  574. if (band >= statistics->nbands) {
  575. G_warning(_("Band index out of range"));
  576. return 0;
  577. }
  578. *min = statistics->band_range_min[band];
  579. return 1;
  580. }
  581. /*!
  582. \brief Get maximum cell value based on mean and standard deviation for band.
  583. \param statistics pointer to statistics structure
  584. \param band band index
  585. \param[out] max maximum value
  586. \return 1 on success
  587. \return 0 band index out of range
  588. */
  589. int I_iclass_statistics_get_range_max(IClass_statistics * statistics,
  590. int band, int *max)
  591. {
  592. if (band >= statistics->nbands) {
  593. G_warning(_("Band index out of range"));
  594. return 0;
  595. }
  596. *max = statistics->band_range_max[band];
  597. return 1;
  598. }