001    /*
002     * NormalizeHistogram
003     * 
004     * Copyright (c) 2001, 2002 Marco Schmidt.
005     * All rights reserved.
006     */
007    
008    package net.sourceforge.jiu.color.adjustment;
009    
010    import net.sourceforge.jiu.color.analysis.Histogram1DCreator;
011    import net.sourceforge.jiu.color.data.Histogram1D;
012    import net.sourceforge.jiu.data.IntegerImage;
013    import net.sourceforge.jiu.ops.LookupTableOperation;
014    import net.sourceforge.jiu.ops.OperationFailedException;
015    
016    /**
017     * Normalize the image using histogram information, separately for each
018     * channel.
019     * Works for intensity-based image types like {@link net.sourceforge.jiu.data.Gray8Image} or 
020     * {@link net.sourceforge.jiu.data.RGB24Image}.
021     *
022     * @author Marco Schmidt
023     * @since 0.6.0
024     */
025    public class NormalizeHistogram extends LookupTableOperation
026    {
027            /**
028             * Creates an object of this class and initializes the lookup
029             * tables with the argument input image.
030             */
031            public NormalizeHistogram(IntegerImage in) throws OperationFailedException
032            {
033                    super(in.getNumChannels());
034                    setInputImage(in);
035                    initTables(in);
036            }
037    
038            private void initTables(IntegerImage in) throws OperationFailedException
039            {
040                    for (int channelIndex = 0; channelIndex < in.getNumChannels(); channelIndex++)
041                    {
042                            Histogram1DCreator hc = new Histogram1DCreator();
043                            hc.setImage(in, channelIndex);
044                            hc.process();
045                            Histogram1D hist = hc.getHistogram();
046    
047                            int min = 0;
048                            while (hist.getEntry(min) == 0)
049                            {
050                                    min++;
051                            }
052                            int maxSample = in.getMaxSample(channelIndex);
053                            int max = maxSample;
054                            while (hist.getEntry(max) == 0)
055                            {
056                                    max--;
057                            }
058                            int[] data = new int[maxSample + 1];
059                            int usedInterval = max - min + 1;
060                            for (int i = 0; i < data.length; i++)
061                            {
062                                    data[i] = min + usedInterval * i / data.length;
063                            }
064                            setTable(channelIndex, data);
065                    }
066            }
067    }