如何从2D数据生成OpenCV 1D直方图?

时间:2016-07-23 07:40:28

标签: c++ opencv histogram opencv3.0

我有一个配对值的数据集,如(x,y)。例如:x的范围是-40到60,y是0到100.最初它们存储在std::vector<std::pair<float,float>>中,但在循环中我将它们转换为2通道cv::Mat以便能够通过它到OpenCV的cv::calcHist功能。我想像这样实现一维直方图:here。由于我实际上有两个数据范围,因此我总是从cv::Mat得到一个二维直方图作为结果cv::calcHist,但我基本上想根据给定的bin_size x_bin进行计算。 x轴是y的平均值。

举个例子:x的范围是-40到60,所需的bin = 10,bin_size = 10,数据点(x,y):( - 35,10),( - 39,20) 然后,1D直方图需要计算从-40到-30的bin范围的y =(10 + 20)/ 2的平均值。

因此,每个bin的总和不应该是落在特定bin范围内的值的简单计数,而是值的平均值。

我希望我能以一种可以理解的方式陈述问题。任何帮助表示赞赏。

1 个答案:

答案 0 :(得分:1)

我不认为OpenCV的cv::calcHist能够为你提供你想要的东西,特别是因为你试图在Y上获得基于X的统计数据。无论如何,没有OpenCV就不难做到这一点。

void calcHist(const std::vector<std::pair<float, float>>& data, const float min_x, const float max_x, const int num_bins, std::vector<float>& hist)
{
  hist.resize(num_bins, 0.f);
  std::vector<int> hist_counts(num_bins, 0);
  float bin_size = (max_x-min_x)/num_bins;
  for (const auto& p : data) {
    // Assign bin
    int bin = static_cast<int>((p.first-min_x)/bin_size);
    // Avoid out of range
    bin = std::min(std::max(bin, 0), num_bins-1);
    hist[bin] += p.second;
    hist_counts[bin]++;
  }
  // Compute average
  for (int i = 0;i < num_bins; ++i) {
    if (hist_counts[i]) {
      hist[i] /= static_cast<float>(hist_counts[i]);
    }
  }
}