我有以下 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 x 282,即 108,288 像素。但是直方图的 256 个 bin 的内容总数是 4,724(如 MessageBox
代码所示)。总数不应该是 108,288 吗? (也许我缺少直方图概念的基础知识?)
(免责声明:我对图像处理和EMGU CV都是新手,虽然我做过研究,但是这里关于SO的EMGU问题相对较少,而且网络上的所有其他内容似乎都是这里问题的副本。 )
最佳答案
我意识到我在上述方法中有几个错误。我正在尝试计算已调整大小并转换为灰度的图像的直方图,这当然破坏了原始图像的规范!
除此之外,根本问题是对于直方图处理,必须首先将图像分成其 channel (蓝色、绿色、红色)。否则,每个像素值的可能性在 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;
对于有问题的图像(上图),总数如下:
pureWhites: 106,757 (image background)
otherPixels: 1,531 (text)
totals: 108,288 (correct number of pixels in the image)
我希望这在直方图基础知识以及对 EMGU CV 中图像的像素级访问方面有所帮助。
关于opencv - 直方图 bin 总数不等于图像像素大小,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28460035/