예제 #1
0
        /// <summary>
        /// Contrast the image (Contrast by expanding the histogram on all channel)
        /// </summary>
        /// <param name="source">The image to be Contrasted</param>
        /// <returns>The image Contrasted</returns>
        protected override IImageAdapter ProcessFilter(IImageAdapter source)
        {
            // Check Params
            if (source == null)
            {
                throw new ArgumentNullException("source", "Argument cannot be null");
            }

            IImageAdapter retVal = new ImageAdapter(source.Width, source.Height);

            int[]     min       = new int[] { (int)source[0, 0].MinChannelValue, (int)source[0, 0].MinChannelValue, (int)source[0, 0].MinChannelValue, (int)source[0, 0].MinChannelValue };
            int[]     max       = new int[] { (int)source[0, 0].MaxChannelValue, (int)source[0, 0].MaxChannelValue, (int)source[0, 0].MaxChannelValue, (int)source[0, 0].MaxChannelValue };
            Hashtable dico      = IPUtil.BuildHistogram(source);
            Hashtable stretched = new Hashtable();

            for (int channel = 1; channel < IPUtil.intColor.Length; channel++)       // Ignore Alpha Channel
            {
                ArrayList[] list = new ArrayList[256];
                for (int index = 0; index < 256; index++)
                {
                    list[index] = new ArrayList();
                }
                stretched.Add(IPUtil.intColor[channel], list);
            }
            stretched[IPUtil.ALPHA] = ((ArrayList[])dico[IPUtil.ALPHA]).Clone();            // Clone Alpha channel from original Histogram


            // Find the min and max value of the histogram
            for (int channel = 1; channel < IPUtil.intColor.Length; channel++)     // ignore the alpha channel
            {
                bool        minFound = false;
                ArrayList[] array    = (ArrayList[])dico[IPUtil.intColor[channel]];

                for (int index = 0; index < 256; index++)
                {
                    if (array[index].Count != 0)
                    {
                        max[channel] = index;
                        minFound     = true;
                    }
                    else
                    {
                        if (!minFound)
                        {
                            min[channel] = index;
                        }
                    }
                }
            }

            // Stretch the histogram
            // Transformation used :
            //    (min <= i <= max)
            //    Stretch   :   (i - min) * 255 / ( max - min) + 0.5
            for (int channel = 1; channel < IPUtil.intColor.Length; channel++)      // Ignore the Alpha Channel
            {
                ArrayList[] channelOriginal  = (ArrayList[])dico[IPUtil.intColor[channel]];
                ArrayList[] channelStretched = (ArrayList[])stretched[IPUtil.intColor[channel]];
                int         minChannel       = min[channel];
                int         maxChannel       = max[channel];
                float       stretchConstant  = (float)source[0, 0].NormalizedValue / (float)(maxChannel - minChannel);
                float       stretch          = 0f;

                for (int index = minChannel; index <= maxChannel; index++)
                {
                    stretch = (index - minChannel) * stretchConstant + 0.5f;
                    channelStretched[(int)stretch].AddRange(channelOriginal[index]);
                }
            }

            retVal = IPUtil.HistogramToIImageAdapter(stretched, source);

            dico.Clear();
            stretched.Clear();

            return(retVal);
        }
예제 #2
0
        /// <summary>
        /// Equalize the image (Equalize the histogram on all channel, except alpha)
        /// (build and use the histogram of the image to do so)
        /// </summary>
        /// <param name="source">The image to be equalized</param>
        /// <returns>The image equalized</returns>
        protected override IImageAdapter ProcessFilter(IImageAdapter source)
        {
            // Check params
            if (source == null)
            {
                throw new ArgumentNullException("source", "Argument cannot be null");
            }

            int[]         sum       = new int[] { 0, 0, 0, 0 };
            Hashtable     equalized = new Hashtable();
            Hashtable     dico      = IPUtil.BuildHistogram(source);
            IImageAdapter retVal    = new ImageAdapter(source.Width, source.Height);

            // Init HashTable -- contains 4 ArrayList[] : 4 channels of 256 entries ( ArrayList of points )
            for (int channel = 1; channel < IPUtil.intColor.Length; channel++)         // Ignore Alpha Channel
            {
                ArrayList[] list = new ArrayList[256];

                for (int index = 0; index < 256; index++)
                {
                    list[index] = new ArrayList();
                }

                equalized.Add(IPUtil.intColor[channel], list);
            }
            equalized[IPUtil.ALPHA] = ((ArrayList[])dico[IPUtil.ALPHA]).Clone();        // Clone Alpha channel from original Histogram


            // compute the sum per channel
            for (int channel = 0; channel < IPUtil.intColor.Length; channel++)
            {
                ArrayList[] array = (ArrayList[])dico[IPUtil.intColor[channel]];
                for (int index = 0; index < 256; index++)
                {
                    sum[channel] += array[index].Count;
                }
            }

            // Stretch and Normalize the histogram
            // Transformation used :
            //    (min <= i <= max)
            //    Normalize :   0.5 + ( Sum(0,i-1) + ( Sum(i-1,i) / 2 ) ) * 255 / Sum(0,255)
            for (int channel = 1; channel < IPUtil.intColor.Length; channel++)        // Ignore Alpha channel
            {
                ArrayList[] channelOriginal  = (ArrayList[])dico[IPUtil.intColor[channel]];
                ArrayList[] channelEqualized = (ArrayList[])equalized[IPUtil.intColor[channel]];
                float       equalizeConstant = 255.0f / ((sum[channel] != 0) ? sum[channel] : 1);
                int         currentSum       = 0;
                float       equalize         = 0f;
                for (int index = 0; index < 256; index++)
                {
                    equalize    = 0.5f + (currentSum + channelOriginal[index].Count / 2) * equalizeConstant;
                    currentSum += channelOriginal[index].Count;
                    channelEqualized[(int)equalize].AddRange(channelOriginal[index]);
                }
            }

            retVal = IPUtil.HistogramToIImageAdapter(equalized, source);

            equalized.Clear();
            dico.Clear();

            return(retVal);
        }