Как нарисовать гистограмму с помощью EmguCV и C # - PullRequest
7 голосов
/ 21 ноября 2011

Мне нужно нарисовать гистограмму двух типов, а именно: одномерную и трехмерную. Я новичок в EMGU, и все сэмплы, которые я нашел в сети, находятся на C ++ или C. Есть ли сэмплы с использованием C # и Emgucv?

Спасибо за помощь.

Ответы [ 5 ]

7 голосов
/ 21 ноября 2011

Следующий код сегментирует данные RED GREEN и BLUE Histogram и помещает их в массив с плавающей точкой для любого использования.

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

и это сделает гистограмму оттенков серого:

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

Надеюсь, это поможет,

Приветствия

Chris

[Изменить]

Чтобы нарисовать гистограмму, вам нужно будет использовать либо свои собственные, либо разработанные элементы управления, такие как Zedgraph (поставляется с EMGU). Вот очень хорошая статья о проекте кода, показывающая его использование.

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

Приветствия

Chris

3 голосов
/ 06 июня 2013

Отображение гистограмм в Эмгу очень просто и весело. Просто создайте элемент управления histogramBox в своей форме, затем вызовите его в цикле, и все готово.

        histogramBox1.ClearHistogram();
        histogramBox1.GenerateHistograms(frame, 256);
        histogramBox1.Refresh();
0 голосов
/ 29 января 2018

Здесь вы можете найти ответ на Рисование гистограммы серого изображения с помощью Emgucv в контексте метода MVFM WPF. Надеюсь, это будет кому-то полезно

MainWindow.xaml

Это вид

<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

это класс модели представления

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

это класс модели

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;
    }
}
0 голосов
/ 19 мая 2016

Важно следовать процедуре, чтобы добавить Emgu.CV.UI.dll в набор инструментов в Windows Forms, чтобы использовать все элементы управления Windows Forms, предоставляемые Emgu CV (включая HistogramBox.)

Прежде всего, вам нужно открыть форму в режиме конструктора. На панели инструментов щелкните правой кнопкой мыши в пустом месте столбца «Общие». Должно появиться меню выбора, в котором доступен выбор «Выбрать элементы», см. Изображение ниже.

Designer Form View

После этого нажмите «Выбрать элементы»; Вы увидите диалог «Выбор элемента панели инструментов». Оттуда нажмите кнопку «Обзор» в правом нижнем углу диалогового окна.

enter image description here

Выберите файл «Emgu.CV.UI.dll» в диалоговом окне «Открыть», нажмите кнопку «Открыть». Теперь вы должны заметить, что элемент управления ImageBox был добавлен в диалог «Выбор элементов панели инструментов». Нажмите «ОК». Затем вы должны обратить внимание на следующие элементы управления, добавленные к вашей панели инструментов (относится к версии 3.10 Emgu. Некоторые другие версии Emgu могут иметь другие элементы управления или не иметь элементов управления, указанных ниже.)

  • HistogramBox
  • ImageBox
  • MatrixBox
  • PanAndZoomPictureBox.

ToolBoxControls

Тогда вы сможете перетащить в свою форму, как считаете нужным элементы управления Windows Forms, которые встроены в Emgu CV. Или вы должны иметь возможность использовать их программно:

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(); 

Этот ответ был вдохновлен в учебнике Add Image Box Control .

0 голосов
/ 18 июля 2013

Трехмерная гистограмма

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

Одномерная гистограмма

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);
...