histo_eq.c 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. /**************************************************************
  2. * G_histogram_eq (histo, map, min, max)
  3. *
  4. * struct Histogram *histo; histogram as returned by G_read_histogram()
  5. * unsigned char **map; equalized category mapping
  6. * CELL *min, *max; min,max category for map
  7. *
  8. * perform histogram equalization
  9. * inputs are histo, output is map,min,max
  10. ****************************************************************/
  11. #include <grass/gis.h>
  12. int G_histogram_eq(const struct Histogram *histo,
  13. unsigned char **map, CELL * min, CELL * max)
  14. {
  15. int i;
  16. int x;
  17. CELL cat, prev;
  18. double total;
  19. double sum;
  20. double span;
  21. int ncats;
  22. long count;
  23. unsigned char *xmap;
  24. int len;
  25. int first, last;
  26. ncats = G_get_histogram_num(histo);
  27. if (ncats == 1) {
  28. *min = *max = G_get_histogram_cat(0, histo);
  29. *map = xmap = (unsigned char *)G_malloc(1);
  30. *xmap = 0;
  31. return 0;
  32. }
  33. if ((*min = G_get_histogram_cat(first = 0, histo)) == 0)
  34. *min = G_get_histogram_cat(++first, histo);
  35. if ((*max = G_get_histogram_cat(last = ncats - 1, histo)) == 0)
  36. *max = G_get_histogram_cat(--last, histo);
  37. len = *max - *min + 1;
  38. *map = xmap = (unsigned char *)G_malloc(len);
  39. total = 0;
  40. for (i = first; i <= last; i++) {
  41. if (G_get_histogram_cat(i, histo) == 0)
  42. continue;
  43. count = G_get_histogram_count(i, histo);
  44. if (count > 0)
  45. total += count;
  46. }
  47. if (total <= 0) {
  48. for (i = 0; i < len; i++)
  49. xmap[i] = 0;
  50. return 0;
  51. }
  52. span = total / 256;
  53. sum = 0.0;
  54. cat = *min - 1;
  55. for (i = first; i <= last; i++) {
  56. prev = cat + 1;
  57. cat = G_get_histogram_cat(i, histo);
  58. count = G_get_histogram_count(i, histo);
  59. if (count < 0 || cat == 0)
  60. count = 0;
  61. x = (sum + (count / 2.0)) / span;
  62. if (x < 0)
  63. x = 0;
  64. else if (x > 255)
  65. x = 255;
  66. sum += count;
  67. while (prev++ <= cat)
  68. *xmap++ = x;
  69. }
  70. return 0;
  71. }