GRASS Programmer's Manual
6.4.2(2012)
|
00001 #include <grass/gis.h> 00002 int G_cell_stats_histo_eq(struct Cell_stats *statf, CELL min1, CELL max1, /* input range to be rescaled */ 00003 CELL min2, CELL max2, /* output range */ 00004 int zero, /* include zero if min1 <= 0 <= min2 ? */ 00005 void (*func) (CELL, CELL, CELL)) 00006 { 00007 long count, total; 00008 CELL prev = 0; 00009 CELL cat; 00010 CELL x; 00011 CELL newcat = 0; 00012 int first; 00013 double span, sum; 00014 double range2; 00015 00016 00017 if (min1 > max1 || min2 > max2) 00018 return 0; 00019 00020 total = 0; 00021 G_rewind_cell_stats(statf); 00022 while (G_next_cell_stat(&cat, &count, statf)) { 00023 if (cat < min1) 00024 continue; 00025 if (cat > max1) 00026 break; 00027 if (cat == 0 && !zero) 00028 continue; 00029 00030 total += count; 00031 } 00032 if (total <= 0) 00033 return 0; 00034 00035 range2 = max2 - min2 + 1; 00036 span = total / range2; 00037 00038 first = 1; 00039 sum = 0; 00040 00041 G_rewind_cell_stats(statf); 00042 while (G_next_cell_stat(&cat, &count, statf)) { 00043 if (cat < min1) 00044 continue; 00045 if (cat > max1) 00046 break; 00047 if (cat == 0 && !zero) 00048 continue; 00049 00050 x = (sum + (count / 2.0)) / span; 00051 if (x < 0) 00052 x = 0; 00053 x += min2; 00054 sum += count; 00055 00056 if (first) { 00057 prev = cat; 00058 newcat = x; 00059 first = 0; 00060 } 00061 else if (newcat != x) { 00062 func(prev, cat - 1, newcat); 00063 newcat = x; 00064 prev = cat; 00065 } 00066 } 00067 if (!first) { 00068 func(prev, cat, newcat); 00069 if (!zero && min1 <= 0 && max1 >= 0) 00070 func((CELL) 0, (CELL) 0, (CELL) 0); 00071 } 00072 00073 return first == 0; 00074 }