public void SetHistogram( Histogram histogram ) { this.histogram = histogram; histogramControl.Values = histogram.Values; int length = histogram.Values.Length; Text = string.Format( "Histogram - {0} values", length ); statsBox.Text = string.Format( "Min: {0} Max: {1} Mean: {2:F2} Std.Dev.: {3:F2}", histogram.Min, histogram.Max, histogram.Mean, histogram.StdDev ); // set form size int formWidth = System.Math.Min( 800, length ) + 40; int formHeight = HistogramHeight + 120; this.Size = new Size( formWidth, formHeight ); // set histogram control size int width = length + 2; int height = HistogramHeight + 2; int x = ( width > mainPanel.ClientSize.Width ) ? 0 : ( mainPanel.ClientSize.Width - width ) / 2; int y = ( height > mainPanel.ClientSize.Height ) ? 0 : ( mainPanel.ClientSize.Height - height ) / 2; histogramControl.SuspendLayout( ); histogramControl.Size = new Size( width, height ); histogramControl.Location = new System.Drawing.Point( x, y ); histogramControl.ResumeLayout( ); }
public static unsafe void DrawHistogram(Bitmap edgeDetectedBitmap, Histogram histogram) { var pallete = edgeDetectedBitmap.Palette; var palleteEntries = pallete.Entries; palleteEntries[250] = Color.Magenta; palleteEntries[251] = Color.Yellow; palleteEntries[252] = Color.Cyan; palleteEntries[253] = Color.Lime; palleteEntries[254] = Color.Red; palleteEntries[255] = Color.White; edgeDetectedBitmap.Palette = pallete; var histogramHeight = Math.Min(100, edgeDetectedBitmap.Height); var rect = new Rectangle(Point.Empty, edgeDetectedBitmap.Size); var bitmapData = edgeDetectedBitmap.LockBits(rect, ImageLockMode.WriteOnly, PixelFormat.Format8bppIndexed); var histogramMax = histogram.Values.Max(); for (var x = 0; x < edgeDetectedBitmap.Width; x++) { var barHeight = histogram.Values[x] * histogramHeight / histogramMax; Console.WriteLine(barHeight); var pCurrentPixel = (byte*)bitmapData.Scan0.ToPointer() + x; for (var y = 0; y < barHeight; y++) { *pCurrentPixel = 255; pCurrentPixel += bitmapData.Stride; } } edgeDetectedBitmap.UnlockBits(bitmapData); }
// Switch channel public void SwitchChannel(int channel) { if ((channel >= 0) && (channel <= 2)) { if (!stat.IsGrayscale) { histogram.Color = colors[channel]; activeHistogram = (channel == 0) ? stat.Red : (channel == 1) ? stat.Green : stat.Blue; } } else if (channel == 3) { if (stat.IsGrayscale) { histogram.Color = colors[3]; activeHistogram = stat.Gray; } } if (activeHistogram != null) { histogram.Values = activeHistogram.Values; meanLabel.Text = activeHistogram.Mean.ToString("F2"); stdDevLabel.Text = activeHistogram.StdDev.ToString("F2"); medianLabel.Text = activeHistogram.Median.ToString(); minLabel.Text = activeHistogram.Min.ToString(); maxLabel.Text = activeHistogram.Max.ToString(); } }
// return pixele index with maximum point private int getMaxValue(Histogram hist) { int max = -1; //init int index = 0;//init for (int i = 0; i < 255; i++) if (hist.Values[i] > max) { max = hist.Values[i]; index = i; } return index; }
// Set image statistics to display public void SetImageStatistics( ImageStatistics stats ) { this.stats = stats; if ( stats.IsGrayscale ) { activeHistogram = stats.Gray; histogram.Color = Color.Black; channelCombo.Enabled = false; ShowInfoForActiveHistogram( ); } else { channelCombo.Enabled = true; channelCombo.SelectedIndex = 0; SelectChannel( 0 ); } }
// Show histogram for the specified RGB channel private void SelectChannel( int c ) { switch ( c ) { case 0: activeHistogram = stats.Red; histogram.Color = Color.Red; break; case 1: activeHistogram = stats.Green; histogram.Color = Color.Green; break; case 2: activeHistogram = stats.Blue; histogram.Color = Color.Blue; break; } ShowInfoForActiveHistogram( ); }
public ImageInfo(string path) { _disposed = false; // image info _hist = null; _imf = null; _imb = null; _height = _width = 0; this._path = path; try { System.Drawing.Image image = System.Drawing.Image.FromFile(this._path); oirgIm2grayCropped(image); // creates _imGray image.Dispose(); _width = _imGray.Width; _height= _imGray.Height; } catch (Exception e) { throw e; } }
/// <summary> /// return a full depp copy /// </summary> /// <param name="from">Source</param> /// <returns>Copyed reference</returns> private Histogram copyHist(Histogram from) { int[] values = new int[from.Values.Length]; from.Values.CopyTo(values, 0); Histogram to = new Histogram(values); to.Update(); return to; }
/// <summary> /// Gather statistics about specified image. /// </summary> /// /// <param name="image">Unmanaged image to process.</param> /// private void ProcessImage( UnmanagedImage image ) { CheckSourceFormat( image.PixelFormat ); // get image dimension int width = image.Width; int height = image.Height; pixels = pixelsWithoutBlack = 0; // check pixel format if ( grayscale = ( image.PixelFormat == PixelFormat.Format8bppIndexed ) ) { // alloc arrays int[] g = new int[256]; int[] gwb = new int[256]; byte value; int offset = image.Stride - width; // do the job unsafe { byte * p = (byte*) image.ImageData.ToPointer( ); // for each pixel for ( int y = 0; y < height; y++ ) { // for each pixel for ( int x = 0; x < width; x++, p++ ) { // get pixel value value = *p; g[value]++; pixels++; if ( value != 0 ) { gwb[value]++; pixelsWithoutBlack++; } } p += offset; } } // create historgram for gray level gray = new Histogram( g ); grayWithoutBlack = new Histogram( gwb ); } else { // alloc arrays int[] r = new int[256]; int[] g = new int[256]; int[] b = new int[256]; int[] rwb = new int[256]; int[] gwb = new int[256]; int[] bwb = new int[256]; byte rValue, gValue, bValue; int pixelSize = ( image.PixelFormat == PixelFormat.Format24bppRgb ) ? 3 : 4; int offset = image.Stride - width * pixelSize; // do the job unsafe { byte * p = (byte*) image.ImageData.ToPointer( ); // for each line for ( int y = 0; y < height; y++ ) { // for each pixel for ( int x = 0; x < width; x++, p += pixelSize ) { // get pixel values rValue = p[RGB.R]; gValue = p[RGB.G]; bValue = p[RGB.B]; r[rValue]++; g[gValue]++; b[bValue]++; pixels++; if ( ( rValue != 0 ) || ( gValue != 0 ) || ( bValue != 0 ) ) { rwb[rValue]++; gwb[gValue]++; bwb[bValue]++; pixelsWithoutBlack++; } } p += offset; } } // create histograms red = new Histogram( r ); green = new Histogram( g ); blue = new Histogram( b ); redWithoutBlack = new Histogram( rwb ); greenWithoutBlack = new Histogram( gwb ); blueWithoutBlack = new Histogram( bwb ); } }
/// <summary> /// Gather horizontal intensity statistics for specified image. /// </summary> /// /// <param name="image">Source image.</param> /// private void ProcessImage( UnmanagedImage image ) { PixelFormat pixelFormat = image.PixelFormat; // get image dimension int width = image.Width; int height = image.Height; // do the job unsafe { // check pixel format if ( pixelFormat == PixelFormat.Format8bppIndexed ) { // 8 bpp grayscale image byte* p = (byte*) image.ImageData.ToPointer( ); int offset = image.Stride - width; // histogram array int[] g = new int[width]; // for each pixel for ( int y = 0; y < height; y++ ) { // for each pixel for ( int x = 0; x < width; x++, p++ ) { g[x] += *p; } p += offset; } // create historgram for gray level gray = new Histogram( g ); } else if ( pixelFormat == PixelFormat.Format16bppGrayScale ) { // 16 bpp grayscale image int basePtr = (int) image.ImageData.ToPointer( ); int stride = image.Stride; // histogram array int[] g = new int[width]; // for each pixel for ( int y = 0; y < height; y++ ) { ushort* p = (ushort*) ( basePtr + stride * y ); // for each pixel for ( int x = 0; x < width; x++, p++ ) { g[x] += *p; } } // create historgram for gray level gray = new Histogram( g ); } else if ( ( pixelFormat == PixelFormat.Format24bppRgb ) || ( pixelFormat == PixelFormat.Format32bppRgb ) || ( pixelFormat == PixelFormat.Format32bppArgb ) ) { // 24/32 bpp color image byte* p = (byte*) image.ImageData.ToPointer( ); int pixelSize = ( pixelFormat == PixelFormat.Format24bppRgb ) ? 3 : 4; int offset = image.Stride - width * pixelSize; // histogram arrays int[] r = new int[width]; int[] g = new int[width]; int[] b = new int[width]; // for each line for ( int y = 0; y < height; y++ ) { // for each pixel for ( int x = 0; x < width; x++, p += pixelSize ) { r[x] += p[RGB.R]; g[x] += p[RGB.G]; b[x] += p[RGB.B]; } p += offset; } // create histograms red = new Histogram( r ); green = new Histogram( g ); blue = new Histogram( b ); } else if ( ( pixelFormat == PixelFormat.Format48bppRgb ) || ( pixelFormat == PixelFormat.Format64bppArgb ) ) { // 48/64 bpp color image int basePtr = (int) image.ImageData.ToPointer( ); int stride = image.Stride; int pixelSize = ( pixelFormat == PixelFormat.Format48bppRgb ) ? 3 : 4; // histogram arrays int[] r = new int[width]; int[] g = new int[width]; int[] b = new int[width]; // for each line for ( int y = 0; y < height; y++ ) { ushort* p = (ushort*) ( basePtr + stride * y ); // for each pixel for ( int x = 0; x < width; x++, p += pixelSize ) { r[x] += p[RGB.R]; g[x] += p[RGB.G]; b[x] += p[RGB.B]; } } // create histograms red = new Histogram( r ); green = new Histogram( g ); blue = new Histogram( b ); } } }
// Selection changed in channels combo private void channelCombo_SelectedIndexChanged(object sender, System.EventArgs e) { AForge.Math.Histogram h = null; Color color = Color.White; IntRange input = new IntRange(0, 255); IntRange output = new IntRange(0, 255); int index = channelCombo.SelectedIndex; if (!imgStat.IsGrayscale) { // RGB image histogram.Color = colors[index]; switch (index) { case 0: // red h = imgStat.Red; input = inRed; output = outRed; color = Color.FromArgb(255, 0, 0); break; case 1: // green h = imgStat.Green; input = inGreen; output = outGreen; color = Color.FromArgb(0, 255, 0); break; case 2: // blue h = imgStat.Blue; input = inBlue; output = outBlue; color = Color.FromArgb(0, 0, 255); break; } } else { // grayscale image histogram.Color = colors[3]; h = imgStat.Gray; input = inGreen; output = outGreen; } histogram.Values = h.Values; inMinBox.Text = input.Min.ToString( ); inMaxBox.Text = input.Max.ToString( ); outMinBox.Text = output.Min.ToString( ); outMaxBox.Text = output.Max.ToString( ); // input slider inSlider.Color2 = color; inSlider.Min = input.Min; inSlider.Max = input.Max; // output slider outSlider.Color2 = color; outSlider.Min = output.Min; outSlider.Max = output.Max; }
// Switch channel public void SwitchChannel( int channel ) { if ( ( channel >= 0 ) && ( channel <= 2 ) ) { if ( !stat.IsGrayscale ) { histogram.Color = colors[channel]; activeHistogram = ( channel == 0 ) ? stat.Red : ( channel == 1 ) ? stat.Green : stat.Blue; } } else if ( channel == 3 ) { if ( stat.IsGrayscale ) { histogram.Color = colors[3]; activeHistogram = stat.Gray; } } if ( activeHistogram != null ) { histogram.Values = activeHistogram.Values; meanLabel.Text = activeHistogram.Mean.ToString( "F2" ); stdDevLabel.Text = activeHistogram.StdDev.ToString( "F2" ); medianLabel.Text = activeHistogram.Median.ToString( ); minLabel.Text = activeHistogram.Min.ToString( ); maxLabel.Text = activeHistogram.Max.ToString( ); } }
/// <summary> /// Remove peaks from the histogram, which don't contain maximum value. /// </summary> /// /// <param name="histogram">Histogram to process.</param> /// private void FilterNoisyPeaks( Histogram histogram ) { int[] values = histogram.Values; int globalMax = 0; // find global maximum value for ( int k = 0; k < values.Length; k++ ) { if ( values[k] > globalMax ) { globalMax = values[k]; } } int i = 0; // process all peaks while ( i < values.Length ) { // find start of next peak while ( ( i < values.Length ) && ( values[i] == 0 ) ) { i++; } int localMax = 0; // find peak's maximum value while ( ( i < values.Length ) && ( values[i] != 0 ) ) { if ( values[i] > localMax ) { localMax = values[i]; } i++; } // remove this peak if it does not contain global maximum if ( localMax < globalMax ) { int j = i - 1; while ( ( j >= 0 ) && ( values[j] != 0 ) ) { values[j] = 0; j--; } } } histogram.Update( ); }
/// <summary> /// Copyies _imGray with newSize, updates size and and null's the rest of the valeus /// </summary> /// <param name="origIm"></param> /// <param name="newSize"></param> public ImageInfo(ImageInfo origIm, Size newSize) { _disposed = false; _imGray = new Bitmap(origIm.getIm(), newSize); _hist = null; _imf = null; _imb = null; _path = null; _width = newSize.Width; _height = newSize.Height; }
/// <summary> /// Gets the content. /// </summary> /// <param name="mincross">Минимальная разница яркости ячейки с кретсиком</param> /// <param name="maxcross">Максимальная разница яркости ячейки с кретсиком</param> public void GetContent(double mincross, double maxcross) { _content = false; _neurocontent = CellContent.Free; List<double> _lrange = new List<double>(); BitmapData data = _parentimage.LockBits(_rect, ImageLockMode.ReadWrite, _parentimage.PixelFormat); VerticalIntensityStatistics vis = new VerticalIntensityStatistics(data); histogram = vis.Gray; HorizontalIntensityStatistics his = new HorizontalIntensityStatistics(data); Histogram hhistogram = his.Gray; List<double> _hrange = new List<double>(); _parentimage.UnlockBits(data); for (int i = 8; i <= 15; i++) { _lrange.Add((histogram.Values[i]+hhistogram.Values[i])/2); // _hrange.Add(hhistogram.Values[i]); } // _britnessdispertion = (1 - RecogCore.Statistics.Mean(_lrange) / histogram.Values.Max()) + (1 - RecogCore.Statistics.Mean(_hrange) / hhistogram.Values.Max()); _britnessdispertion = 1 - RecogCore.Statistics.Mean(_lrange) / histogram.Values.Max(); if (_britnessdispertion <= mincross) { _neurocontent = CellContent.Free; _content = false; } if (_britnessdispertion > mincross & _britnessdispertion <= maxcross) { _neurocontent = CellContent.Cross; _content = true; } if (_britnessdispertion > maxcross) { _neurocontent = CellContent.Miss; _content = false; } }
/// <summary> /// this construr gets the _imGray of an ImageInfo in order to get another object /// of that image without any more data, can be used when running filters on images /// </summary> /// <param name="imGray"></param> private ImageInfo(Bitmap imGray) { _disposed = false; _path = null; _hist = null; _imf = null; _imGray = (Bitmap)imGray.Clone(); _width = _imGray.Width; _height = _imGray.Height; }
//mathod return true if image is bad contrast private bool isBadContrast(Histogram hist) { int range; //num of pixels in range int max = getMaxValue(hist); // index of maximum point if (max < 20) // check range [0,20] range = pixelRange(hist, 0, 20); else if (max > 235) // check range [235,255] range = pixelRange(hist, 235, 255); else // check range [max-20,max+20] range = pixelRange(hist, max - 20, max + 20); double parcent = (double)range / (double)hist.TotalCount * 100; //parcent of range from image if (parcent > 70) // if is biggest than 70% return bad contrast return true; double bright = (double)pixelRange(hist, 235, 255) / (double)hist.TotalCount * 100; //bright parcent if (max < 20 && parcent + bright > 70 ) // if max is dark and the rest picture is bright return bad contrast return true; double dark = (double)pixelRange(hist, 0, 35) / (double)hist.TotalCount * 100; // dark parcent if (max > 240 && dark + parcent > 70) // id max is bright and the rest picture is dark return bad contrast return true; return false; // picture not bad contrast }
/// <summary> /// **** THIS FUNCTION CAN BE CALLED ONLY ONES IN THE OBJECT LIFE TIME*** /// creates an AForge.Math.Histogram object from _imGray into _hist /// </summary> private Histogram createHist() { lock (histLcok) { if (_hist != null) return _hist; _hist = (new ImageStatistics(_imGray)).Gray; return _hist; } }
//return sum of pixeles in range [start,end] private int pixelRange(Histogram hist,int start, int end) { int sum = 0; for (int i = start; i < end; i++) sum += hist.Values[i]; return sum; }
/// <summary> /// DeepCopy Constructor /// </summary> /// <param name="from">Copied Source</param> public ImageInfo(ImageInfo from) { _disposed = false; // copy path _path = from.getPath(); // copy gray image _imGray = new Bitmap(from.getIm()); // copy histogram _hist = from.getHist() == null ? null : copyHist(from.getHist()); // copy _imf if (from.getImF() != null) { _imf = new float[from.getImF().Length]; from.getImF().CopyTo(_imf, 0); } else { _imf = null; } // copy _imb if (from.getImF() != null) { _imb = new byte[from.getImb().Length]; from.getImb().CopyTo(_imb, 0); } else { _imb = null; } // copy size _width = from.Width; _height = from.Height; }
// TODO - check if the arrays can be disposed somehow wthout massing the GC work flow protected virtual void Dispose(bool disposing) { if (!_disposed) { if (disposing) { _imGray.Dispose(); _imGray = null; _imb = null; _imf = null; _hist = null; } _disposed = true; } }
// Gather statistics private void ProcessImage( BitmapData imageData, int width, int height, PixelFormat pixelFormat ) { pixels = pixelsWithoutBlack = 0; if ( grayscale = ( pixelFormat == PixelFormat.Format8bppIndexed ) ) { // alloc arrays int[] g = new int[256]; int[] gwb = new int[256]; byte gv; int offset = imageData.Stride - width; // do the job unsafe { byte * p = (byte *) imageData.Scan0.ToPointer( ); // for each pixel for ( int y = 0; y < height; y++ ) { // for each pixel for ( int x = 0; x < width; x++, p++ ) { // get pixel value gv = *p; g[gv]++; pixels++; if ( gv != 0 ) { gwb[gv]++; pixelsWithoutBlack++; } } p += offset; } } // create historgram for gray level gray = new Histogram( g ); grayWithoutBlack = new Histogram( gwb ); } else { // alloc arrays int[] r = new int[256]; int[] g = new int[256]; int[] b = new int[256]; int[] rwb = new int[256]; int[] gwb = new int[256]; int[] bwb = new int[256]; byte rv, gv, bv; int offset = imageData.Stride - width * 3; // do the job unsafe { byte * p = (byte *) imageData.Scan0.ToPointer( ); // for each line for ( int y = 0; y < height; y++ ) { // for each pixel for ( int x = 0; x < width; x++, p += 3 ) { // get pixel values rv = p[RGB.R]; gv = p[RGB.G]; bv = p[RGB.B]; r[rv]++; g[gv]++; b[bv]++; pixels++; if ( ( rv != 0 ) || ( gv != 0 ) || ( bv != 0 ) ) { rwb[rv]++; gwb[gv]++; bwb[bv]++; pixelsWithoutBlack++; } } p += offset; } } // create histograms red = new Histogram( r ); green = new Histogram( g ); blue = new Histogram( b ); redWithoutBlack = new Histogram( rwb ); greenWithoutBlack = new Histogram( gwb ); blueWithoutBlack = new Histogram( bwb ); } }
/// <summary> /// Filter histogram's low values. /// </summary> /// /// <param name="histogram">Histogram to filter.</param> /// private void FilterLowValues( Histogram histogram ) { int[] values = histogram.Values; int globalMax = 0; // find global maximum value for ( int k = 0; k < values.Length; k++ ) { if ( values[k] > globalMax ) { globalMax = values[k]; } } // filter values, which are below 10% of max int filterLevel = (int) ( (double) globalMax / 10 ); // do filtering for ( int k = 0; k < values.Length; k++ ) { if ( values[k] <= filterLevel ) { values[k] = 0; } } histogram.Update( ); }