Class AlgorithmAHElocal

  • All Implemented Interfaces:
    java.awt.event.ActionListener, java.awt.event.WindowListener, java.lang.Runnable, java.util.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:
    AlgorithmMedian
    • Field Detail

      • AXIAL_KERNEL

        public static final int AXIAL_KERNEL
        along the major axis (+).
        See Also:
        Constant Field Values
      • 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 java.util.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 & 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 Detail

      • 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 Detail

      • finalize

        public void finalize()
        Prepares this class for destruction.
        Overrides:
        finalize 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​(java.lang.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)