2011-11-20 56 views

Respuesta

6

El segmento de código voluntad después de los datos ROJO verde y azul de histograma y ponerlos en una serie de flotadores para cualquier uso que desee.

float[] BlueHist; 
float[] GreenHist; 
float[] RedHist; 

Image<Bgr, Byte> img = new Image<Bgr, byte>("ImageFileName"); 

DenseHistogram Histo = new DenseHistogram(255, new RangeF(0, 255)); 

Image<Gray, Byte> img2Blue = img[0]; 
Image<Gray, Byte> img2Green = img[1]; 
Image<Gray, Byte> img2Red = img[2]; 


Histo.Calculate(new Image<Gray, Byte>[] { img2Blue }, true, null); 
//The data is here 
//Histo.MatND.ManagedArray 
BlueHist = new float[256]; 
Histo.MatND.ManagedArray.CopyTo(BlueHist, 0); 

Histo.Clear(); 

Histo.Calculate(new Image<Gray, Byte>[] { img2Green }, true, null); 
GreenHist = new float[256]; 
Histo.MatND.ManagedArray.CopyTo(GreenHist, 0); 

Histo.Clear(); 

Histo.Calculate(new Image<Gray, Byte>[] { img2Red }, true, null); 
RedHist = new float[256]; 
Histo.MatND.ManagedArray.CopyTo(RedHist, 0); 

y esto hará el histograma de escala de grises:

float[] GrayHist; 

Image<Gray, Byte> img_gray = new Image<Gray, byte>("ImageFileName"); 

Histo.Calculate(new Image<Gray, Byte>[] { img_gray }, true, null); 
//The data is here 
//Histo.MatND.ManagedArray 
GrayHist = new float[256]; 
Histo.MatND.ManagedArray.CopyTo(GrayHist, 0); 

Espero que esto ayude,

Cheers,

Chris

[Editar]

Para dibujar el histograma tendrá que usar controles propios o diseñados como Zedgraph (Esto se proporciona con EMGU). Aquí hay un artículo muy bueno sobre codeproject que muestra su uso.

http://www.codeproject.com/KB/graphics/zedgraph.aspx

Saludos

Chris

+0

La primera Paremeter de Calcular es una serie de imágenes. ¿Significa que puedo darle {img2Blue, img2Red, img2Green} y lo calcula todo? ¿Puedes demostrar este uso? Muchas gracias. – Gqqnbig

+1

Solo una corrección rápida en la publicación de Chris 'DenseHistogram Histo = new DenseHistogram (255, new RangeF (0, 255));' debe ser 'DenseHistogram Histo = new DenseHistogram (256, new RangeF (0, 256));' Else usted faltarán los valores en su bandeja 255 como acabo de experimentar cuando creé un laplaciano de por imagen. – foofunner

2

Viendo histogramas en Emgu es muy fácil y divertido. Simplemente haga un control histogramBox en su formulario, luego llámelo en su ciclo y listo.

 histogramBox1.ClearHistogram(); 
     histogramBox1.GenerateHistograms(frame, 256); 
     histogramBox1.Refresh(); 
0

histograma tridimensional

Image<Bgr, Byte>[] inp = new Image<Bgr, byte>("fileName.jpg"); 
int nBins = 256; 
DenseHistogram hist = new DenseHistogram(new int[] { nBins, nBins, nBins }, new RangeF[] { new RangeF(0, 255), new RangeF(0, 255), new RangeF(0, 255) }); 
hist.Calculate(inp.Split(), false, null); 

// To get value of single bin 
int b = 255; int g = 0; int r = 0; //blue 
int count = Convert.ToInt32(hist.MatND.ManagedArray.GetValue(b, g, r)); //count = no of pixels in color Bgr(b,g,r) 

//To get all values in a single array 
List<Tuple<Bgr, int>> histVal = new List<Tuple<Bgr, int>>(nBins * nBins * nBins); 
for (int i = 0; i < nBins; i++) 
    for (int j = 0; j < nBins; j++) 
     for (int k = 0; k < nBins; k++) 
      histVal.Add(new Tuple<Bgr, int>(new Bgr(i, j, k), Convert.ToInt32(hist.MatND.ManagedArray.GetValue(i, j, k)))); 

histograma unidimensional

int nBins = 256; 
float[] valHist = new float[nBins]; 
Image<Gray, Byte>[] inp = new Image<Gray, byte>("fileName.jpg"); 
DenseHistogram hist = new DenseHistogram(nBins, new RangeF(0, 255)); 
hist.Calculate(new Image<Gray, Byte>[] { inp }, true, null); 
hist.MatND.ManagedArray.CopyTo(valHist,0); 
0

Es importante seguir el procedimiento para agregar el Emgu.CV.UI.dll a su caja de herramientas de Windows Forms con el fin para utilizar todo el controles de Windows Forms que Emgu CV proporciona (HistogramBox incluido.)

En primer lugar, debe abrir su formulario en la vista del diseñador. Desde Toolbox, haga clic derecho en el espacio vacío de la columna 'General'. Esto debería mostrar un menú de selección, donde está disponible la opción 'Elegir elementos', ver imagen a continuación.

Designer Form View

A continuación, haga clic en 'Elegir elementos'; verá un cuadro de diálogo 'Elegir elemento de cuadro de herramientas'. Desde allí, haga clic en el botón 'Examinar ...' en la esquina inferior derecha del cuadro de diálogo. archivo

enter image description here

Seleccione 'Emgu.CV.UI.dll' de diálogo 'Abrir', haga clic en el botón 'Abrir'. Ahora debe observar que el control ImageBox se ha agregado al cuadro de diálogo 'Elegir elementos de la caja de herramientas'. Haga clic en Aceptar'. Luego debe tener en cuenta los siguientes controles agregados a su Toolbox (se aplica para la versión 3.10 de Emgu. Algunas otras versiones de Emgu pueden tener otros controles o carecen de los controles mencionados a continuación.)

  • HistogramBox
  • ImageBox
  • MatrixBox
  • PanAndZoomPictureBox.

ToolBoxControls

, entonces debería ser capaz de arrastrar y soltar a su forma como mejor le parezca Windows Forms controles que Emgu CV ha incorporado ella. O usted debería ser capaz de utilizarlas mediante programación:

Form frm = new Form(); 
var img = CvInvoke.Imread(this.PictureBox.ImageLocation, Emgu.CV.CvEnum.LoadImageType.Grayscale).ToImage<Gray, Byte>(); 

HistogramBox histo = new HistogramBox(); 

histo.ClearHistogram(); 
histo.GenerateHistograms(img, 256); 
histo.Dock = DockStyle.Fill; 
histo.Refresh(); 

frm.Controls.Add(histo); 

frm.ShowDialog(); 

Esta respuesta se inspiró en el Add Image Box Control tutorial.

0

Aquí puede encontrar respuesta a dibujar el histograma de la imagen gris usando Emgucv en el contexto del método de MVVM WPF .. espero que sea útil para alguien

MainWindow.xaml

Esta es la opinión

<Window x:Class="Histogram.MainWindow" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
    xmlns:vm="clr-namespace:HistogramAndOverlayingMVVM.ViewModel" 
    xmlns:local="clr-namespace:Histogram" 
    mc:Ignorable="d" 
    Title="MainWindow" WindowState="Maximized"> 
<Window.DataContext> 
    <vm:MainWindowViewModel/> 
</Window.DataContext> 
<Grid> 
    <Button Content="LoadImage" Command="{Binding OpenImg}" HorizontalAlignment="Left" VerticalAlignment="Top" Width="Auto" Height="Auto" Margin="31,5,0,0" /> 
    <Button Content="Histogram" Command="{Binding Histogram}"HorizontalAlignment="Left" Margin="135,5,0,0" VerticalAlignment="Top" Width="Auto" Height="Auto"/> 
    <Image Source="{Binding Image.Source}" HorizontalAlignment="Left" Height="346" Margin="9,39,0,0" VerticalAlignment="Top" Width="546"/> 
    <Image Source="{Binding Hist.Source}" HorizontalAlignment="Left" Height="346" Margin="569,39,-353.4,0" VerticalAlignment="Top" Width="546"/> 
</Grid></Window> 

MainWindowViewModel.cs

esta es la clase modelo de vista

class MainWindowViewModel 
{ 
    public ICommand OpenImg { get; set; } 
    Image<Bgr, byte> imgInput; 

    Histogram his = new Histogram(); 

    public MainWindowViewModel() 
    { 
     OpenImg = new RelayCommand(openImg, (obj) => true); 
     _image = new System.Windows.Controls.Image(); 
     _hist = new System.Windows.Controls.Image(); 
    } 
    private void openImg(object obj = null) 
    { 
     OpenFileDialog op = new OpenFileDialog(); 
     op.Title = "Select a picture"; 
     op.Filter = "All supported graphics|*.jpg;*.jpeg;*.png;*.bmp;*.tiff|" + 
      "JPEG (*.jpg;*.jpeg)|*.jpg;*.jpeg|" + 
      "Portable Network Graphic (*.png)|*.png"; 
     if (op.ShowDialog() == true) 
     { 
      string ImgPath = op.FileName; 
      imgInput = new Image<Bgr, byte>(ImgPath); 
      Image.Source = BitmapSourceConvert.ToBitmapSource(imgInput); 

     } 
    } 
    private System.Windows.Controls.Image _image; 
    public System.Windows.Controls.Image Image 
    { 
     get { return _image; } 
     set 
     { 
      _image = value; 
     } 
    } 

    private ICommand _histogram; 
    public ICommand Histogram 
    { 
     set { _histogram = value; } 
     get 
     { 
      if(_histogram == null) 
      { 
       _histogram = new RelayCommand(param => DrawHistogram((EventArgs)param)); 
      } 
      return _histogram; 
     } 
    } 
    private void DrawHistogram(EventArgs e) 
    { 
     Bitmap img; 
     img = his.ApplyHistogram(imgInput); 
     Hist.Source = BitmapSourceConvert.BitmapToImageSource(img);    
    } 
    private System.Windows.Controls.Image _hist; 
    public System.Windows.Controls.Image Hist 
    { 
     get { return _hist; } 
     set 
     { 
      _hist = value; 
     } 
    } 
} 

Histogram.cs

esta clase de modelo es

public class Histogram 
{ 
    public Bitmap ApplyHistogram(Image<Bgr,byte> imgInput) 
    { 
     Image<Gray, Byte> src = imgInput.Convert<Gray, byte>(); 

     DenseHistogram hist = new DenseHistogram(256, new RangeF(0.0f, 255f)); 
     hist.Calculate(new Image<Gray, byte>[] { src }, true, null); 

     // Get the max value of histogram 
     double minVal = 0.0; 
     double maxVal = 0.0; 
     Point minLoc = new Point(); 
     Point maxLoc = new Point(); 

     CvInvoke.MinMaxLoc(hist, ref minVal, ref maxVal, ref minLoc, ref maxLoc); 

     // Scale histogram 
     const int width = 256; 
     const int height = 250; 
     var histData = hist.GetBinValues(); 

     Bitmap histo = DrawHistogram(maxVal, width, height, histData); 
     return histo;   
    }  
    private static Bitmap DrawHistogram(double maxVal, int width, int height, float[] histData) 
    { 
     Bitmap histo = new Bitmap(width, height); 
     Graphics g = Graphics.FromImage(histo); 
     g.Clear(SystemColors.Window); 
     Pen penGray = new Pen(Brushes.DarkGray); 

     for (var i = 0; i < histData.GetLength(0); i++) 
     { 
      var val = (float)histData.GetValue(i); 
      val = (float)(val * (maxVal != 0 ? height/maxVal : 0.0)); 

      Point s = new Point(i, height); 
      Point e = new Point(i, height - (int)val); 
      g.DrawLine(penGray, s, e); 
     } 
     return histo; 
    } 
} 
Cuestiones relacionadas