grass
grass copied to clipboard
[EXPERIMENTAL] v.colors: Histogram equalization
Lightness (in HSL)-based color histogram equalization. Calculates probability using feature areas (no cells in vector), but I may not merge it if I fail to fix the following issue.
v.colors map=censusblk_swwake use=attr column=TOTAL_POP color=blues -e
seems to work,

but
v.colors map=censusblk_swwake use=attr column=TOTAL_POP color=rainbow -e
doesn't work.
Method
- RGB => HSL
- Sort areas by L in an ascending order
- For each area, calculate the cumulative area (
sum_area) and probability (L) bysum_area / total_area - Original (H, S) and new L from step 3 => RGB
Issues
This method seems to work for monotonic color maps, but a color map such as rainbow has only two lightnesses 0.5 and 1 and it doesn't really make much sense to histogram equalize two intensities. Maybe, I should do color-averaged equalization.
In fact, these two commands don't work either:
v.colors map=censusblk_swwake use=attr column=TOTAL_POP color=blues -g
v.colors map=censusblk_swwake use=attr column=TOTAL_POP color=blues -a
because Rast_log_colors() and Rast_abs_log_colors() interpolates categories, which doesn't make sense for vector maps. Vector maps require exact categories in the color file, it seems?
This does not work correctly on my Mac. I just cloned and complied it within the past hour. I tested it with the NC census block data. A good place to look is with the TOTAL_POP attribute because it has an area much higher than any others: cat=1319. Checking the histogram equalization box gives unexpected and incorrect results with a multi-color table (check out one of the viridis tables or GRASS bgyr). It seems initially to work with a single color gradient like blues or reds. But even these are incorrect. TOTAL_POP for cat=1319 should be the most intense color but it is not. It looks exactly the same as some other areas like cat=1364. You can try the same equalizations on a raster version of the census block vector area map and it looks correct.
This does not work correctly on my Mac. I just cloned and complied it within the past hour. I tested it with the NC census block data. A good place to look is with the TOTAL_POP attribute because it has an area much higher than any others: cat=1319. Checking the histogram equalization box gives unexpected and incorrect results with a multi-color table (check out one of the viridis tables or GRASS bgyr). It seems initially to work with a single color gradient like blues or reds. But even these are incorrect. TOTAL_POP for cat=1319 should be the most intense color but it is not. It looks exactly the same as some other areas like cat=1364. You can try the same equalizations on a raster version of the census block vector area map and it looks correct.
I see. I think this PR needs some (a lot of?) work. It gets tricky to implement histogram equalization for vector features. BTW, have you tried -a or -g? Do they work for you?
v.colors map=censusblk_swwake use=attr column=TOTAL_POP color=blues -a
v.colors map=censusblk_swwake use=attr column=TOTAL_POP color=blues -g
I see. I think this PR needs some (a lot of?) work. It gets tricky to implement histogram equalization for vector features. BTW, have you tried
-aor-g? Do they work for you?v.colors map=censusblk_swwake use=attr column=TOTAL_POP color=blues -a v.colors map=censusblk_swwake use=attr column=TOTAL_POP color=blues -g
Nope. They don't work (https://github.com/OSGeo/grass/issues/1432#issuecomment-804281748).
@HuidaeCho would you mind to rebase this PR?
@HuidaeCho would you mind to rebase this PR?
@neteler Please try it.
I have tested it again successfully with the following test:
# main
grass ~/grassdata/nc_spm_08_grass7/user1
g.region vector=censusblk_swwake -p
d.mon wx0
# show original, suboptimal color table
d.vect censusblk_swwake
# apply histogram equalization
v.colors map=censusblk_swwake use=attr column=TOTAL_POP color=blues -e
# show with improved color table
d.vect censusblk_swwake
# restore original color table
v.colors map=censusblk_swwake use=attr column=TOTAL_POP color=blues
d.redraw
Which edge cases shall be tested?