2015-02-11 72 views
1

我有以下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 282,这使得108288个像素。但是,直方图256个分档的内容总数为4,724个(如MessageBox代码所示)。总数不应该是108,288? (也许我错过了直方图概念的基本原理?)

(声明:我是图像处理和EMGU简历的新手,虽然我已经完成了研究,但是在这里对于SO有相对较少的EMGU问题,网络上的所有其他内容似乎都是这里问题的副本。)

回答

2

我意识到我在上述方法中遇到了几个错误。我试图计算已经调整大小并转换为灰度的图像的直方图,当然这已经破坏了原始图像的规格!

除此之外,基本问题是,对于直方图处理,必须先将图像分离为其通道(蓝色,绿色,红色)。否则,每个像素值的可能性介于0和16,581,375之间(并且试图将每个这样的强度放置在它自己的容器中)可能的需要大小为2的矩阵,其中每个项需要高达2 比特。

以下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:106757(图像背景)
otherPixels: 1531(文本)
总计:108288(图像中的正确的像素数)

我希望这帮助他人在直方图基础知识以及像素级访问EMGU简历中的图像。

+0

我不认为你只能得到RGB像素的直方图。您可以很好地获取灰度值像素的直方图。 我刚刚浏览了EMGU DenseHistogram类的一些文档,但是在代码中找不到任何错误,因此可能错误确实在您创建/调整大小/转换图像的部分内。 – RFerwerda 2015-02-19 12:26:18

+0

@RFerwerda谢谢。在我上面的回答中,我描述了如何获得直方图(如果您真的想要)复合像素值,但您的正确之处在于,典型方法是将颜色分为R,G,B通道。 – Sabuncu 2015-02-19 12:30:46

+0

@Sabuncu所以你在这里散步。 ;) – karlphillip 2015-04-01 01:01:38