如何使用 EmguCV 和 C# 绘制直方图

Posted

技术标签:

【中文标题】如何使用 EmguCV 和 C# 绘制直方图【英文标题】:How to draw histogram using EmguCV and C# 【发布时间】:2012-01-02 12:56:40 【问题描述】:

我需要绘制两种类型的直方图,即一维和三维。 我是 EMGU 的新手,我在网上找到的所有示例都是 C++ 或 C。是否有使用 C# 和 Emgucv 的示例?

感谢您的帮助。

【问题讨论】:

【参考方案1】:

以下代码将分割 RED GREEN 和 BLUE 直方图数据并将它们放入浮点数组中以供您使用。

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

希望这会有所帮助,

干杯,

克里斯

[编辑]

要绘制直方图,您需要使用您自己或设计的控件,例如 Zedgraph(随 EMGU 提供),这是一篇关于 codeproject 的非常好的文章,展示了它的用法。

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

干杯

克里斯

【讨论】:

Calculate的第一个参数是一个Image数组。这是否意味着我可以给它 img2Blue, img2Red,img2Green 并计算所有?你能证明这种用法吗?非常感谢。 对 Chris 的帖子 DenseHistogram Histo = new DenseHistogram(255, new RangeF(0, 255)); 进行快速更正应该是 DenseHistogram Histo = new DenseHistogram(256, new RangeF(0, 256)); 否则您将丢失 255 bin 中的任何值,就像我刚刚在按图像创建拉普拉斯算子时所经历的那样。【参考方案2】:

在 Emgu 中显示直方图非常简单有趣。只需在表单上创建一个 histogramBox 控件,然后在循环中调用它即可完成。

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

【讨论】:

【参考方案3】:

遵循将 Emgu.CV.UI.dll 添加到 Windows 窗体中的工具箱的过程非常重要,以便使用 Emgu CV 提供的所有 Windows 窗体控件(包括直方图框。)

首先,您需要在设计器视图中打开表单。从工具箱中,右键单击“常规”列的空白处。这应该会弹出一个选择菜单,其中可以选择“选择项目”,见下图。

然后,点击“选择项目”;您将看到一个“选择工具箱项目”对话框。从那里单击对话框右下角的“浏览..”按钮。

从“打开”对话框中选择“Emgu.CV.UI.dll”文件,单击“打开”按钮。 现在您应该注意到 ImageBox 控件已添加到“选择工具箱项”对话框中。单击“确定”。然后您应该注意添加到您的工具箱中的以下控件(适用于 Emgu 3.10 版本。某些其他版本的 Emgu 可能具有其他控件或缺少下面提到的控件。)

直方图框 图像框 矩阵框 PanAndZoomPictureBox。

然后,您应该能够将 Emgu CV 内置的 Windows 窗体控件拖放到您认为合适的窗体中。或者您应该能够以编程方式使用它们:

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 教程。

【讨论】:

【参考方案4】:

立体直方图

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

【讨论】:

以上是关于如何使用 EmguCV 和 C# 绘制直方图的主要内容,如果未能解决你的问题,请参考以下文章

EmguCV:使用光流在运动物体上绘制轮廓?

如何在带有Canvas的Kibana中使用Elastic SQL绘制时间序列直方图?

matlab如何画直方图

如何在R中将两个直方图一起绘制?

如何在 Pandas 中使用预聚合数据绘制直方图?

绘制直方图,使条形高度总和为 1(概率)