Class AlgorithmAHElocal

java.lang.Object
java.lang.Thread
gov.nih.mipav.model.algorithms.AlgorithmBase
gov.nih.mipav.model.algorithms.AlgorithmAHElocal
All Implemented Interfaces:
ActionListener, WindowListener, Runnable, EventListener

public class AlgorithmAHElocal extends AlgorithmBase
algorithm to apply an adaptive histogram to an image, placing it in a new ModelImage, or returning the changed picture to the same image.

This is an algorithm to apply within a neighborhood, that is it selects a region of adjacent pixels, the number of adjacent pixels is of a user-selected size, and forms the histogram from that region. The region selection routine is adopted from AlgorithmMedian. The value of the cell (the brightness of the pixel at a particular location) is then mapped to the region. Over the entire image, this means that all pixels will still be brighter or darker than other pixels, but the brightness has been shifted making minor variations more apparent. The cumulative distribution is changed so that it becomes step-wise linear, making the darker pixels use the lowest possible values available to the image, the brightest use the highest possible values.

This algorithm may be used to perform a contrast-limited or 'clamped' histogram equalization. It is set by supplying a percentage of the maximum number of pixels in any particular brightness level. As the regional histograms are tabulated, the brightness with the maximum number of pixels attributed to it is remembered. The algorithm will then evenly redistribute the total number of pixels from any brightness which has a greater number than the max times this fraction to all other (less populous) brightnesses. (If the supplied percentage is 80, for instance, the maximum number of pixels to any brightness level, will be four-fifths the largest number number of pixels of any shade found.

The principle methodology of this algorithm, is to take each window, form a histogram; clamp so there is no brightness which can have more than a certain number of pixels; scale the brightnesses so that the values are spread evenly from the maximum to the minimum brightness. (ie., scale * histogram(i)).

  • Primary source: Stark, J Alex. Adaptive Image Contrast Enhancement Using Generalizations of Histogram Equalization.
  • Background Information:
    • Russ, John. Image Processing HandbookM.
    • Tidestav, Claes. Short Introduction to Adaptive Equalization.
    • Rabie, Tamer; Rangayan, Rangaraj; Paranjape, Raman. Adaptive-Neighborhood Image Deblurring.

According to Freedman and Diaconis as summarized in "Recent Developments in NonParametric Density Estimation" by Alan Julian Izenman, Journal of the American Statistical Association, March, 1991, Vol. 86, No. 413, pp. 205 - 224: The ideal histogram bin width W is given by W = 2(IQR)pow(N,-1/3) where IQR is the interquartile range(the 75 percentile minus the 25th percentile) and N is the number of available samples.

The three coordinates of CIELAB represent the lightness of the color(L* = 0 yields black and L* = 100 indicates diffuse white; specular white may be higher), its position between red/magenta and green(a*, negative values indicate green while positive values indicate magenta) and its position between yellow and blue(b*, negative values indicate blue and positive values indicate yellow). The asterisk(*) after L, a, and b are part of the full name, since they represent L*, a*, and b*, to distinguish them from Hunter's L, a, and b. The L* coordinate ranges from 0 to 100. The possible range of a* and b* coordinates depends on the color space that one is converting from. R = 0, G = 0, B = 0 => L* = 0, a* = 0, b* = 0 R = 255, G = 0, B = 0 => L* = 53.2, a* = 80.1, b* = 67.22 R = 0, G = 255, B = 0 => L* = 87.7, a* = -86.2, b* = 83.2 R = 0, G = 0, B = 255 => L* = 32.3, a* = 79.2, b* = -107.9 R = 255, G = 255, B = 0 => L* = 97.1, a* = -21.6, b* = 94.5 R = 255, G = 0, B = 255 => L* = 60.3, a* = 98.3, b* = -60.8 R = 0, G = 255, B = 255 => L* = 91.1, a* = -48.1, b* = -14.1 R = 255, G = 255, B = 255 => L* = 100.0, a* = 0.00525, b* = -0.0104 so the range of a* equals about the range of b* and the range of a* equals about twice the range of L*. The simplest distance metric delta E is CIE76 = sqrt((L2* - L1*)**2 + (a2* - a1*)**2 + (b2* - b1*)**2) XW, YW, and ZW (also called XN, YN, ZN or X0, Y0, Z0) are reference white tristimulus values - typically the white of a perfectly reflecting diffuser under CIE standard D65 illumination(defined by x = 0.3127 and y = 0.3291 in the CIE chromatcity diagram). The 2 degrees, D65 reference tristimulus values are: XN = 95.047, YN = 100.000, and ZN = 1 http://www.easyrgb.com has XYZ -> RGB, RGB -> XYZ, XYZ -> CIEL*ab, CIEL*ab -> XYZ, and XYZ(Tristimulus) Reference values of a perfect reflecting diffuser. Smoothing vs. sharpening of color images - Together or separated by Cristina Perez, Samuel Morillas, and Alberto Conejero, June, 2017. "Histogram equalization is a non-linear process and involves intensity values of the image and not the color components For these reasons, channel splitting and equalizing each channel separately is not the proper way for equalization of contrast. So, the first step is to convert the color space of the image from RGB into other color space which separates intensity values from color components such as HSV, YCbCr, or Lab, and apply equalization over the H, Y, or L channel respectively."
Version:
1.00; 24 Sep 2001
Author:
David Parsons (parsonsd), Matthew J. McAuliffe, Ph.D.
See Also:
  • Field Details

    • SQUARE_KERNEL

      public static final int SQUARE_KERNEL
      square kernel.
      See Also:
    • CROSS_KERNEL

      public static final int CROSS_KERNEL
      cross (+).
      See Also:
    • AXIAL_KERNEL

      public static final int AXIAL_KERNEL
      along the major axis (+).
      See Also:
    • scaleOnLocal

      public static final int scaleOnLocal
      DOCUMENT ME!
      See Also:
    • scaleOnSlice

      public static final int scaleOnSlice
      DOCUMENT ME!
      See Also:
    • scaleOnImage

      public static final int scaleOnImage
      DOCUMENT ME!
      See Also:
    • absMinThreshold

      protected float absMinThreshold
      pixel does not get remapped when pixel is below threshold.
    • bChannel

      protected boolean bChannel
      the blue channel.
    • brightnessLevel

      protected int brightnessLevel
      a pixel (no matter whether represented as a float or int), has a brightnessLevel, which is in the histogram as a value between 0 and totalBins.
    • bufMax

      protected float bufMax
      maximum of the image buffer.
    • bufMin

      protected float bufMin
      minimum of the image buffer.
    • clampingIsNecessary

      protected boolean clampingIsNecessary
      perform a "contrast limited" AHE.
    • clipLevel

      protected float clipLevel
      DOCUMENT ME!
    • currentSlice

      protected int currentSlice
      DOCUMENT ME!
    • entireImage

      protected boolean entireImage
      true means apply to entire image, false only region.
    • gChannel

      protected boolean gChannel
      the green channel.
    • halfK

      protected int halfK
      DOCUMENT ME!
    • histogram

      protected int[] histogram
      (cumulative) histogram.
    • histomap

      protected float[] histomap
      the scaled histogram.
    • imageOffset

      protected float imageOffset
      image minimum; used as offset for images to build histogram.
    • isColorImage

      protected boolean isColorImage
      indicates the image is a color image.
    • kernel

      protected float[] kernel
      DOCUMENT ME!
    • kernelCenter

      protected int kernelCenter
      DOCUMENT ME!
    • kernelMask

      protected byte[] kernelMask
      mask to determine the region of pixels used in a median filter.
    • kernelShape

      protected int kernelShape
      user-selectable shape of the region for neighbor-selection.
    • kernelSize

      protected int kernelSize
      dimension of the kernel (ie., 5 = 5x5, 7 = 7x7, 9 = 9x9, etc.).
    • mask

      protected BitSet mask
      DOCUMENT ME!
    • maskCenter

      protected int maskCenter
      DOCUMENT ME!
    • maxScale

      protected float maxScale
      range of max - min over local kernel, slice, or entire image.
    • maxScaleRule

      protected int maxScaleRule
      flag how/when to set the maximum scale. default per slice
    • minThreshold

      protected float minThreshold
      DOCUMENT ME!
    • minValue

      protected float minValue
      min over local kernel, slice, or entire image.
    • numberOfSlices

      protected int numberOfSlices
      DOCUMENT ME!
    • rChannel

      protected boolean rChannel
      if T, filter the red channel.
    • useCIELab

      private boolean useCIELab
    • sortBuffer

      protected float[] sortBuffer
      here for memory/speed concerns.
    • thresholdingIsNecessary

      protected boolean thresholdingIsNecessary
      threshold the image while processing.
    • totalBins

      protected int totalBins
      number of histogram and histomap values actually used.
    • unitSize

      protected float unitSize
      one unit is one totalBin-th of the distance between max invalid input: '&' min brightness.
    • valuesPerPixel

      protected int valuesPerPixel
      number of elements in a pixel. Monochrome = 1, Color = 4. (a, R, G, B)
    • numColors

      int numColors
    • colorUsed

      int colorUsed
    • imageMax

      private double imageMax
    • scaleMaxCIELab

      private double scaleMaxCIELab
    • Lmin

      float[] Lmin
    • Lmax

      float[] Lmax
  • Constructor Details

    • AlgorithmAHElocal

      public AlgorithmAHElocal(ModelImage srcImg, int kSize, int kShape, boolean wholeImage, boolean useCIELab, float[] Lmin, float[] Lmax)
      Constructor for images in which changes are returned to the source image.
      Parameters:
      srcImg - source image model
      kSize - size of kernel
      kShape - shape of kernel
      wholeImage - If true whole image used
      useCIELab - If color, use intensity L in CIELab space
      Lmin - [0] is lowest color image L value in CIELab space
      Lmax - [0] is highest color image L value in CIELab space
    • AlgorithmAHElocal

      public AlgorithmAHElocal(ModelImage destImg, ModelImage srcImg, int kSize, int kShape, boolean wholeImage, boolean useCIELab, float[] Lmin, float[] Lmax)
      Constructor for images in which changes are placed in a predetermined destination image.
      Parameters:
      destImg - image model where result image is to stored
      srcImg - source image model
      kSize - size of kernel
      kShape - shape of kernel
      wholeImage - If true whole image used
      useCIELab - If color, use intensity L in CIELab space
      Lmin - [0] is lowest color image L value in CIELab space
      Lmax - [0] is highest color image L value in CIELab space
  • Method Details

    • finalize

      public void finalize()
      Prepares this class for destruction.
      Overrides:
      finalize in class AlgorithmBase
    • runAlgorithm

      public void runAlgorithm()
      starts the algorithm.
      Specified by:
      runAlgorithm in class AlgorithmBase
    • setClipLevel

      public void setClipLevel(int sectorPercentage)
      The Clip Level is a percentage of the maximum number of pixels in any particular brightness level. This method allows one to set that percentage. As the regional histograms are tabulated, the brightness with the maximum number of pixels attributed to it is remembered. The algorithm will then evenly redistibute the total number of pixels from any brightness which has a greater number than the max times this fraction to all other (less populous) brightnesses.
      Parameters:
      sectorPercentage - DOCUMENT ME!
    • setContrastLimited

      public void setContrastLimited(boolean beClamped)
      Redistribute from brightnesses with at a least a specified percentage of the brightness with the maximum number of pixels.
      Parameters:
      beClamped - DOCUMENT ME!
    • setHistogramScaleRule

      public void setHistogramScaleRule(int scaleRule)
      permit the user to select the scale on which the algorithm forms the brightness pattern of the histogram. The default is scaleOnSlice.

      The options are:

      • scale On Local neighborhood
      • scale on Slice
      • scale on image
      Parameters:
      scaleRule - DOCUMENT ME!
    • setMinimumThreshold

      public void setMinimumThreshold(float minThresh)
      sets minimum threshold values. Pixels are copied over when both the source pixel and the local neighborhood surrounding the pixel are all less than the given minimum pixel value.
      Parameters:
      minThresh - DOCUMENT ME!
    • setRGBChannelFilter

      public void setRGBChannelFilter(boolean r, boolean g, boolean b)
      RGB images are histogram equalized by 'channel.' That is, each color, red, blue and green, is run independently of the other two colors. This permits selectively filtering any combination of the three channels instead of simply trying to handle all three at once. True filters that channel.
      Parameters:
      r - DOCUMENT ME!
      g - DOCUMENT ME!
      b - DOCUMENT ME!
    • setThresholdImage

      public void setThresholdImage(boolean useThreshold)
      If useThreshold true only copy when both the source pixel and its local neighborhoold are are less than minThreshold.
      Parameters:
      useThreshold - DOCUMENT ME!
    • buildHistogram

      protected int buildHistogram()
      make histogram uses the class-global vars kernel and histogram.
      Returns:
      the index to the bin with the highest count.
    • calcInPlace2D

      protected void calcInPlace2D()
      Histogram equalization on the source image. Replaces the original image with the filtered image.
    • calcInPlace3D

      protected void calcInPlace3D()
      Histogram Equalization on the source image and replaces the source image with the processed image.
    • calcStoreInDest2D

      protected void calcStoreInDest2D()
      This function produces a new image that has had itself histogram equalized. places filtered image in the destination image.
    • calcStoreInDest3D

      protected void calcStoreInDest3D()
      This function produces a new volume image that has been histogram equalized. The Image is changed by filtering each slice individually.
    • clip

      protected final void clip(int[] histogram, int clipLimit)
      after generating a histogram, clip will reduce the number of pixels attributed to that brightness level.

      The idea is to limit any brightness level in the histogram to a set value; the number of pixels that are above the limit are tallied. The total number of pixels that were found above the limit, is then spread evenly among the brightnesses that are below limit.

      Parameters:
      histogram - array where the brightness values of all pixels in the image have been counted.
      clipLimit - no brightness may have any more than this number of pixels. Obviously, this method will not achieve anything when clipLimit is as large or larger than the largest brightness in histogram.
    • copyBuffers

      protected final void copyBuffers(float[] dest, float[] src)
      Copies all values from the srcbuffer to the destination buffer. the format is intended to envision the Organization of dest[i] := src[i] float dest destination array float src source array
      Parameters:
      dest - DOCUMENT ME!
      src - DOCUMENT ME!
    • findBufferMinMax

      protected final void findBufferMinMax(float[] buf, int bufStart, int bufEnd)
      Finds the local maximum and minimum values in the given range in order, as given by the starting and stoping values.
      Parameters:
      buf - float array of values
      bufStart - where to begin looking
      bufEnd - where to stop
    • findImageOffset

      protected final void findImageOffset(int type)
      gets the bottom end of the image. for any image but color images, the bottom end is defined as the buffer minimum for all images except color images; there the offset is defined to be zero
      Parameters:
      type - DOCUMENT ME!
    • findTotalBins

      protected final int findTotalBins(int type, int ideal)
      finds the total number of bins based on the type of image.
      Parameters:
      type - DOCUMENT ME!
      ideal - DOCUMENT ME!
      Returns:
      the total number of bins.
    • getMax

      protected final float getMax(int color)
      gets the image max based on 1st) whether or not the image is color. 2) the color.
      Parameters:
      color - DOCUMENT ME!
      Returns:
      DOCUMENT ME!
    • getMin

      protected final float getMin(int color)
      gets the image max based on 1st) whether or not the image is color. 2) the color.
      Parameters:
      color - DOCUMENT ME!
      Returns:
      DOCUMENT ME!
    • getNeighborList

      protected final void getNeighborList(int i, float[] data)
      Compiles a list of the values neighboring the desired pixel, that are defined in the kernel.

      The Neighbor list reports the monochromatic brightness values. returned in the neighbor list's kernel.

      Parameters:
      i - The central pixel to find neighbors for.
      data - Image data. The data is to be arranged always as a monochromatic, 2d set. Returned in kernel: The neighboring pixel list
    • getThresholdNeighborList

      protected final boolean getThresholdNeighborList(int i, float[] data)
      Compiles a list of the values neighboring the desired pixel, that are defined in the kernel.

      The Neighbor list reports the monochromatic brightness values. returned in the neighbor list's kernel.

      Parameters:
      i - The central pixel to find neighbors for.
      data - Image data. The data is to be arranged always as a monochromatic, 2d set.
      Returns:
      aboveThreshold
    • makeKernel

      protected void makeKernel()
      Makes the kernel. Creates out of memory, sets the center and the size.
    • makeKernelMask

      protected void makeKernelMask()
      Forms kernel.
    • monoSliceEqualizer

      protected final void monoSliceEqualizer(float[] srcBuffer, float[] destBuffer)
      Allows a single monochrome image slice to be filtered. Any color image may be processed in this so long as each color plane is separate and provided one at a time. This means, extract [aRGB aRGB ...] buffer into 3 seperate buffers [RRRRRRRRRRR...] , [GGGGGG....] and [BBBBBBBB] and feed each into the sliceFilter one-at-a-time.

      The benefit is one sliceFilter for all image types; just break up each RGB image into these seperate monochrome images sliceFilter and then reassemble int aRGB.

      Only length of one slice (image.getExtents[0] * image.getExtents[1]) Will be copied at a time. Note that a progressBar must be created first.

      Parameters:
      srcBuffer - source buffer
      destBuffer - destination Buffer
    • printhisto

      protected final void printhisto(int[] histo)
      a debug tool.
      Parameters:
      histo - DOCUMENT ME!
    • procPixel

      protected final float procPixel(int pix, float[] srcBuffer)
      process pixel at pixel pix using data from the srcBuffer. builds a list of monochromatic image values of the neighboring pixels image values (using a map generated by the kernelMask), builds the histogram of those values, clamps when necessary, then scales the cumulative histogram, getting the brightness back out.

      This is the entire algorithm on one pixel.

      Parameters:
      pix - the pixel to process; generates the histogram from the neighbors around this image-data element.
      srcBuffer - all the monochromatic image data -- which means that 4-color image data must be seperated out into monochrome color slices for this method.
      Returns:
      DOCUMENT ME!
    • setKernelMask

      protected void setKernelMask()
      Fill in the mask for which pixels are used in filtering.
    • thresholdProcPixel

      protected final float thresholdProcPixel(int pix, float[] srcBuffer)
      process pixel at pixel pix using data from the srcBuffer. builds a list of monochromatic image values of the neighboring pixels image values (using a map generated by the kernelMask), builds the histogram of those values, clamps when necessary, then scales the cumulative histogram, getting the brightness back out.

      This is the entire algorithm on one pixel.

      Parameters:
      pix - the pixel to process; generates the histogram from the neighbors around this image-data element.
      srcBuffer - all the monochromatic image data -- which means that 4-color image data must be separated out into monochrome color slices for this method.
      Returns:
      DOCUMENT ME!
    • setCopyColorText

      private void setCopyColorText(String colorText)
      If the progress bar is visible, sets the text to:
      Copying all color values ...
      Parameters:
      colorText - the color to use. Eg., "red" or "blue"
    • convertRGBtoCIELab

      private void convertRGBtoCIELab(float[] buffer, float[] L, float[] a, float[] b)
    • convertCIELabtoRGB

      private void convertCIELabtoRGB(float[] L, float[] a, float[] b, float[] buffer)