<html>
  <head>
    <meta content="text/html; charset=ISO-8859-1"
      http-equiv="Content-Type">
  </head>
  <body bgcolor="#FFFFFF" text="#000000">
    <div class="moz-cite-prefix">Here is a discussion of changes I
      propose for dealing with histograms in IJ2.  Sorry it's so length,
      let me know if something is unclear and please comment if you have
      an interest in histograms; I do have some specific questions for
      the group (<b><i>in bold italics</i></b>):<br>
      <br>
      <br>
      1)  First of all I would create some helper methods like the
      following (could just be static methods somewhere)...<br>
      <br>
      // maps a value to a bin index, given the range min...max and the
      number of bins<br>
      int valueToBin(int bins, double min, double max, double value);<br>
      <br>
      // returns array of edge values<br>
      double[] getEdgeValues(int bins, double min, double max);<br>
      <br>
      // returns array of center values<br>
      double[] getCenterValues(int bins, double min, double max);<br>
      <br>
      ...and equivalent set for integer values.<br>
      <br>
      Note that these methods would be used for both computing
      histograms and assigning colors from a LUT.  It's nice to use
      exactly the same code for both.  You can characterize a histogram
      bin or LUT color by the starting or edge value or by the center
      value, I've seen it both ways so I included both flavors.<br>
      <br>
      Having these common methods would also avoid bugs:<br>
      <br>
      i) One bug I saw in several places is to compute (value - min) /
      (max - min) and get a value from 0.0 to 1.0, but multiply that by
      255.  The problem with that is the only way you get bin 255 is if
      value == min.  Ideally each bin should represent a range of
      values; if the data set is uniformly distributed the size of the
      range of values per bin would be about the same.<br>
      <br>
      ii) Another bug was to compute width = max - min + 1.  That's
      certainly the way you do it for integer arithmetic but it doesn't
      work in floating point!<br>
      <br>
      I'd rather fix these bugs by refactoring to call the common helper
      methods.<br>
      <br>
      <br>
      2)  Regarding the "ImageStatistics" class idea that Curtis
      mentioned:<br>
      <br>
      For example it might include methods:<br>
      <br>
      // request certain things ahead of time<br>
      doMinMax();<br>
      doHistogram(int bins);<br>
      doHistogram(int bins, double min, double max);<br>
      doMean();<br>
      <br>
      // do minimal number of passes through the image<br>
      process();<br>
      <br>
      // get accumulated results<br>
      double[] getMinMax();<br>
      long[] getHistogram();<br>
      double getMean;<br>
      <br>
      Here if you don't specify a min/max for doHistogram the code has
      to take an initial pass to get min/max then another to build the
      histogram using that min/max.<br>
      <br>
      <br>
      3) Discussion of  net.imglib2.script.analysis.Histogram:<br>
      <br>
      Both of these ImgLib2 histogram methods combine a single pass
      through the image with generating histogram statistics.<br>
      <br>
      This code exhibits bug (i).<br>
      <br>
      I'm not sure that this handles integral values as well as floating
      point.<br>
      <br>
      The mapping of values to histogram bins counts values that are
      less than the min in the first bin and values that are greater
      than the max in the last bin.  <b><i>Is this really desirable
          behavior?</i> </b> In my usage of histograms I specifically
      don't want to count under- and over-range values.  Similarly when
      using a LUT I like under- and over-range values to appear black. 
      Of course if we need it work both ways we can provide a switch.<br>
      <br>
      The output of this code is actually a JFreeChart image, there's no
      way to get the raw histogram count array.<br>
      <br>
      FYI, uses TreeMap<Double, Long> as an internal
      representation of the histogram count array.  Note that this
      combines what I am calling the edge values with the histogram
      counts.<br>
      <br>
      <br>
      4) Discussion of net.imglib2.algorithm.stats.Histogram:<br>
      <br>
      This has a HistogramBinMapper base class with RealBinMapper and
      IntBinMapper so it's meant to handle real and integral values. 
      The mapper is passed in as a parameter; I think it could be
      inferred from the cursor type T.<br>
      <br>
      Here the RealBinMapper class exhibits bug (ii) when calculating
      binWidth in the constructor.<br>
      <br>
      IntBinMapper doesn't let you specify a bin count, but assumes
      numBins = max - min + 1.  In other words, each bin will track a
      given integer value.  I haven't actually worked with any
      histograms of integral valued images but I thought they should
      work the same way as floating point, that is you could count a
      range of values in a single histogram bin.  <i><b>Is there any
          reason bins and values should always be 1:1 for integral
          valued images?</b></i>  This is so in IJ1 for 8-bit and RGB
      images.<br>
      <br>
      You pass in the minimum and maximum values when you create a
      HistogramBinMapper, but these are described as bin center values. 
      My concept of the minimum and maximum values has been the minimum
      is the lowest value that maps to the first histogram bin and the
      maximum is the highest value that maps to the last histogram bin. 
      If we specify min/max as centers some values slightly below
      minimum and slightly above maximum will map to the first and last
      histogram bins respectively.  <i><b>Do we need to specify min/max
          as bin center values?</b></i><br>
      <br>
      <br>
      Thanks!<br>
      Aivar<br>
      <br>
      <br>
      On 8/10/12 2:44 PM, Curtis Rueden wrote:<br>
    </div>
    <blockquote
cite="mid:CADN69ymmcB1DOPRrxywm9UknHbfx9JNe63Xv3bh8xV9jtTbKyQ@mail.gmail.com"
      type="cite">Hi all,
      <div><br>
      </div>
      <div>Aivar & I also discussed histograms, and our plan for
        those is a bit more nebulous. Aivar is going to investigate
        improving Larry's histogram API in net.imglib2.algorithms.stats.</div>
      <div>
        <br>
      </div>
      <div>The general idea is that computing min/max, computing
        histograms, and computing other statistics are intrinsically
        related, and for performance reasons it is nice to minimize the
        number of passes through the image when computing these. So we
        would like to create a unified ImageStatistics class (sound
        familiar? ;-) that can compute one or more of these in an
        intelligent way, then return the results on demand.</div>
      <div><br>
      </div>
      <div>None of this is reconciled with the
        net.imglib2.script.analysis package (Histogram, ImgMax, ImgMean,
        etc.), but perhaps in the future the net.imglib2.script stuff
        can take more direct advantage of it.</div>
      <div><br>
      </div>
      <div>Regards,</div>
      <div>Curtis</div>
      <div><br>
        <br>
        <div class="gmail_quote">On Tue, Aug 7, 2012 at 4:45 PM, Aivar
          Grislis <span dir="ltr"><<a moz-do-not-send="true"
              href="mailto:grislis@wisc.edu" target="_blank">grislis@wisc.edu</a>></span>
          wrote:<br>
          <blockquote class="gmail_quote" style="margin:0 0 0
            .8ex;border-left:1px #ccc solid;padding-left:1ex">I'd also
            be interested in working on the histogram code.  Mostly the
            code that generates histogram data, also their display,
            perhaps the histogram tool itself.<br>
            <br>
            SLIM Plugin uses histograms in a very dynamic way, as they
            are updated periodically during the fit process.  You can
            change the minimum and maximum values interactively.  So I
            might be an interested consumer of any common histogram
            code.<br>
            <br>
            (I looked at the histogram code in the AutoContrast plugin,
            net.imglib2.algorithm.stats.Histogram, and
            net.imglib2.script.analysis.Histogram and found bugs in all
            of them when binning up the histogram values.)<span
              class="HOEnZb"><font color="#888888"><br>
                <br>
                Aivar<br>
                <br>
              </font></span></blockquote>
        </div>
        <br>
      </div>
    </blockquote>
    <br>
  </body>
</html>