Summed Area Tables or Integral Images
Posted: 2009-06-27T16:37:47-07:00
I wanted to bring a technique to the IM user groups attention, called summed area tables (sat) or integral images.
http://en.wikipedia.org/wiki/Summed_area_table
This is a rather old technique that was originally developed for antialiasing images as an alternate to multi-resolution images (MIP maps).
http://www.soe.ucsc.edu/classes/cmps160 ... 7-crow.pdf
One basically sums or integrates the (normalized) graylevels over the image and uses differences from this table as local averages for later antialiasing. (Anthony may find this of interest for potential multi-resolution antialiased interpolation for -distort)
But has seen use also for HDR images tone mapping, shadow mapping and feature (face) detection:
http://www.inf.ufrgs.br/~oliveira/pubs_ ... GI2008.pdf
http://ati.amd.com/developer/gdc/GDC200 ... ctions.pdf
http://www.cgl.uwaterloo.ca/poster/andrew_I3D07.pdf
http://en.wikipedia.org/wiki/Robust_rea ... _detection
http://research.microsoft.com/en-us/um/ ... s_IJCV.pdf
My interest at the moment is much more limited (to 1D images) and has to do with my recent attempts to speed up my redist, histmatch and omnistretch scripts. In these scripts, I need to generate a 1D function (such as a gaussian) or generate the image histogram, then integrate the function or histogram (to make the cumulative histogram) and then finally create a 1D (look up table image) lut from the 1D integrated function and the 1D cumulative histogram to use with -clut to transform the image in a way that redistributes the histogram of the image.
In the past, I did all this (except applying -clut) in the shell of my scripts. The histogram of the image was extracted as text using histogram:info, then filtered with the unix commands sed and sort and then added in the empty bins so that it contained every bin from 0 to 255 (whether empty or not). (Note that IM text histograms do not include any empty bins in the listing).
I recently realized I could create the histogram directly as a 1D image as follows (using the zelda image in grayscale, but works similarly in color):
convert zelda3.jpg -colorspace gray histogram:- | convert - -scale 256x1! zelda3g_hist.png
which when graphed looks like:
Then I realized that I could integrate the histogram image or any 1D function image (normalized between 0 and 1), but it is rather slow as it has to iterate multiple IM commands 256 times. For example here is the algorithm for the zelda histogram.
norm=`convert zelda3g_hist.png -format "%[fx:1/(mean*w)]" info:`
i=0
convert -size 1x1 xc:black tmp_cumhist.mpc
while [ $i -lt 256 ]; do
ww=`expr $i + 1`
fact=`convert xc: -format "%[fx:$ww*$norm]" info:`
convert tmp_cumhist.mpc \
\( zelda3g_hist.png[${ww}x1+0+0] -scale 1x1! -evaluate multiply $fact \) \
+append tmp_cumhist.mpc
i=`expr $i + 1`
done
convert tmp_cumhist.mpc[256x1+1+0] zelda3g_cumhist.png
which when graphed looks as follows:
Likewise a gaussian distribution can be created as follows:
sigma=48
den=`convert xc: -format "%[fx:2*($sigma/256)^2]" info:`
convert -size 256x1 xc: -monitor -fx "exp(-(((i-0.5*w)/w)^2)/($den))" gauss48.png
which when graphed looks as follows:
and when integrated as above, looks as follows:
As a confirmation, if one integrates a constant, one should get a function y=x or diagonal line.
convert -size 256x1 xc:"gray(50%)" test_uni_hist.png
which when graphed looks as follows:
and when integrated and graphed looks as follow:
I am wondering if anyone knows a more efficient method of doing the integration of the 1D function/histogram image using IM processing?
http://en.wikipedia.org/wiki/Summed_area_table
This is a rather old technique that was originally developed for antialiasing images as an alternate to multi-resolution images (MIP maps).
http://www.soe.ucsc.edu/classes/cmps160 ... 7-crow.pdf
One basically sums or integrates the (normalized) graylevels over the image and uses differences from this table as local averages for later antialiasing. (Anthony may find this of interest for potential multi-resolution antialiased interpolation for -distort)
But has seen use also for HDR images tone mapping, shadow mapping and feature (face) detection:
http://www.inf.ufrgs.br/~oliveira/pubs_ ... GI2008.pdf
http://ati.amd.com/developer/gdc/GDC200 ... ctions.pdf
http://www.cgl.uwaterloo.ca/poster/andrew_I3D07.pdf
http://en.wikipedia.org/wiki/Robust_rea ... _detection
http://research.microsoft.com/en-us/um/ ... s_IJCV.pdf
My interest at the moment is much more limited (to 1D images) and has to do with my recent attempts to speed up my redist, histmatch and omnistretch scripts. In these scripts, I need to generate a 1D function (such as a gaussian) or generate the image histogram, then integrate the function or histogram (to make the cumulative histogram) and then finally create a 1D (look up table image) lut from the 1D integrated function and the 1D cumulative histogram to use with -clut to transform the image in a way that redistributes the histogram of the image.
In the past, I did all this (except applying -clut) in the shell of my scripts. The histogram of the image was extracted as text using histogram:info, then filtered with the unix commands sed and sort and then added in the empty bins so that it contained every bin from 0 to 255 (whether empty or not). (Note that IM text histograms do not include any empty bins in the listing).
I recently realized I could create the histogram directly as a 1D image as follows (using the zelda image in grayscale, but works similarly in color):
convert zelda3.jpg -colorspace gray histogram:- | convert - -scale 256x1! zelda3g_hist.png
which when graphed looks like:
Then I realized that I could integrate the histogram image or any 1D function image (normalized between 0 and 1), but it is rather slow as it has to iterate multiple IM commands 256 times. For example here is the algorithm for the zelda histogram.
norm=`convert zelda3g_hist.png -format "%[fx:1/(mean*w)]" info:`
i=0
convert -size 1x1 xc:black tmp_cumhist.mpc
while [ $i -lt 256 ]; do
ww=`expr $i + 1`
fact=`convert xc: -format "%[fx:$ww*$norm]" info:`
convert tmp_cumhist.mpc \
\( zelda3g_hist.png[${ww}x1+0+0] -scale 1x1! -evaluate multiply $fact \) \
+append tmp_cumhist.mpc
i=`expr $i + 1`
done
convert tmp_cumhist.mpc[256x1+1+0] zelda3g_cumhist.png
which when graphed looks as follows:
Likewise a gaussian distribution can be created as follows:
sigma=48
den=`convert xc: -format "%[fx:2*($sigma/256)^2]" info:`
convert -size 256x1 xc: -monitor -fx "exp(-(((i-0.5*w)/w)^2)/($den))" gauss48.png
which when graphed looks as follows:
and when integrated as above, looks as follows:
As a confirmation, if one integrates a constant, one should get a function y=x or diagonal line.
convert -size 256x1 xc:"gray(50%)" test_uni_hist.png
which when graphed looks as follows:
and when integrated and graphed looks as follow:
I am wondering if anyone knows a more efficient method of doing the integration of the 1D function/histogram image using IM processing?