我有以下EMGU CV代码可为灰度图像创建直方图:
Image<Bgr, Byte> img = new Image<Bgr,
Byte>(fileNameTextBox.Text).Resize(400, 400,
Emgu.CV.CvEnum.INTER.CV_INTER_LINEAR, true);
// Convert to grayscale and filter out noise.
Image<Gray, Byte> gray = img.Convert<Gray, Byte>().PyrDown().PyrUp();
DenseHistogram dh = new DenseHistogram(256, new RangeF(0, 255));
dh.Calculate(new Image<Gray, Byte>[] { gray }, false, null);
float[] valHist = new float[256]; // # of bins: 256
dh.MatND.ManagedArray.CopyTo(valHist, 0);
float total = 0F;
for (int ii = 0; ii < 256; ii++)
{
total += valHist[ii];
}
MessageBox.Show("Bins total: " + total);
我用下面的图像运行上面的代码(原始图像不包含其周围的边框-我在此处添加了它以便进行分界):
图像为384像素乘384像素,即108,288像素。但是直方图的256个bin的总内容为4,724(如
MessageBox
代码所示)。总数不应该是108,288吗? (也许我错过了直方图概念的基础知识?)(免责声明:我对图像处理和EMGU CV还是陌生的,尽管我已经做过研究,但SO上这里的EMGU问题相对较少,网络上的所有其他内容似乎都是这里的问题的副本。)
最佳答案
我意识到上述方法存在一些错误。我正在尝试为已调整大小并转换为灰度的图像计算直方图,这当然破坏了原始图像的规格!
除此之外,根本的问题是,对于直方图处理,必须首先将图像分离为其通道(蓝色,绿色,红色)。否则,每个像素值的可能性在0到16,581,375之间(224),并且尝试将每个这样的强度放在其自己的bin中可能会需要大小为224的矩阵,而每个项目最多需要217位。
以下C#代码总计纯白色像素和其他像素。在这种情况下,总计结果正确无误:
int pureWhites = 0;
int otherPixels = 0;
int totals = 0;
Bgra tmp;
for (int ii = 0; ii < 282; ii++)
{
for (int jj = 0; jj < 384; jj++)
{
tmp = img[ii,jj];
if (tmp.Blue == 255 && tmp.Green == 255 && tmp.Red == 255)
pureWhites++;
else
otherPixels++;
}
}
totals = purewhites + otherPixels;
对于上述图像(上图),总计如下:
我希望这可以帮助其他人在直方图基础知识以及EMGU CV中对图像进行像素级访问方面。