尝试不使用opencv calcHist()来计算自己的直方图

Alo*_*isD 2 c++ opencv function image-processing histogram

我要做的是编写一个函数,该函数计算带有转发的Bins(anzBin)数的直方图范围被划分的灰度图像的直方图。然后,我遍历Image Pixels将其值补偿为不同的Bin,如果值合适,则将Bin的值增加1

   vector<int> calcuHisto(const IplImage *src_pic, int anzBin) 
   {
   CvSize size = cvGetSize(src_pic);
   int binSize = (size.width / 256)*anzBin;
   vector<int> histogram(anzBin,0);

    for (int y = 0; y<size.height; y++) 
    {
         const uchar *src_pic_point =
        (uchar *)(src_pic->imageData + y*src_pic->widthStep);
       for (int x = 0; x<size.width; x++) 
       {
        for (int z = 0; z < anzBin; z++)
        {
            if (src_pic_point[x] <= z*binSize)
            {
                histogram[src_pic_point[x]]++;
            }

        }

    }
}
return histogram;
}
Run Code Online (Sandbox Code Playgroud)

但不幸的是,它不起作用...这里出了什么问题?请帮忙

and*_*rew 5

我可以看到一些问题

  1. 您的binSize计算错误
  2. 您的分箱算法是单面的,应该是双面的
  3. 找到匹配项时,您没有增加适当的垃圾箱

1. binsize计算

bin size = your range / number of bins

2.双面装箱

if (src_pic_point[x] <= z*binSize)
Run Code Online (Sandbox Code Playgroud)

您需要一个双向的值范围,而不是单边的不等式。想象一下,您有4个bin,值从0到255。您的bin应具有以下范围

bin     low     high
0       0       63.75
1       63.75   127.5
2       127.5   191.25
3       191.25  255
Run Code Online (Sandbox Code Playgroud)

例如:值570应该进入bin0。您的代码说该值进入所有bin!因为它总是<= z*binsize需要一些具有上下限的东西。

3.增加适当的垃圾箱

您正在使用z循环遍历每个bin的方法,因此当找到匹配项时,应该增加bin的z值,除非确定它属于哪个bin,否则不使用实际的像素值

这可能是缓冲区溢出。再次想象一下,您有4个bin,当前像素的值为57。此代码显示增量bin57。但是您只有4个bin(0-3)

histogram[src_pic_point[x]]++;
Run Code Online (Sandbox Code Playgroud)

您只想增加像素值所属的bin

histogram[z]++;
Run Code Online (Sandbox Code Playgroud)

代码
考虑到这一点,这里是经过修订的代码(未经测试,但应该可以使用)

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;
}
Run Code Online (Sandbox Code Playgroud)