试图在没有opencv calcHist()的情况下计算我自己的直方图

时间:2016-04-21 20:34:45

标签: c++ function opencv image-processing histogram

我正在尝试做的是编写一个函数来计算灰度图像的直方图,其中包含直方图范围被分割的转发数量(anzBin)。然后我正在运行图像像素计算他们的值为不同的Bins,如果值适合,则将Bin的值增加1

device

但遗憾的是它不起作用...... 这有什么不对? 请帮忙

1 个答案:

答案 0 :(得分:3)

There are a few issues I can see

  1. Your binSize calculation is wrong
  2. Your binning algorithm is one sided, and should be two sided
  3. You aren't incrementing the proper bin when you find a match

1. binsize calculation

bin size = your range / number of bins

2. two sided binning

if (src_pic_point[x] <= z*binSize)

you need a two sided range of values, not a one sided inequality. Imagine you have 4 bins and values from 0 to 255. Your bins should have the following ranges

bin     low     high
0       0       63.75
1       63.75   127.5
2       127.5   191.25
3       191.25  255

For example: a value of 57 should go in bin 0. Your code says the value goes in all the bins! Because its always <= z*binsize You need something something with a lower and upper bound.

3. Incrementing the appropriate bin

You are using z to loop over each bin, so when you find a match you should increment bin z, you don't use the actual pixel value except when determining which bin it belongs to

this would likely be buffer overrun imagine again you have 4 bins, and the current pixel has a value of 57. This code says increment bin 57. But you only have 4 bins (0-3)

histogram[src_pic_point[x]]++;

you want to increment only the bin the pixel value falls into

histogram[z]++;

CODE
With that in mind here is revised code (it is untested, but should work)

vector<int> calcuHisto(const IplImage *src_pic, int anzBin) 
{
    CvSize size = cvGetSize(src_pic);
    double binSize = 256.0 / anzBin;        //new definition
    vector<int> histogram(anzBin,0);        //i don't know if this works so I
                                            //so I will leave it

    //goes through all rows
    for (int y = 0; y<size.height; y++) 
    {
        //grabs an entire row of the imageData
        const uchar *src_pic_point = (uchar *)(src_pic->imageData + y*src_pic->widthStep);

        //goes through each column
        for (int x = 0; x<size.width; x++) 
        {
            //for each bin
            for (int z = 0; z < anzBin; z++)
            {
                //check both upper and lower limits
                if (src_pic_point[x] >= z*binSize && src_pic_point[x] < (z+1)*binSize)
                {
                    //increment the index that contains the point
                    histogram[z]++;
                }
            }
        }
    }
    return histogram;
}