/// <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); }
/// <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); }