简体   繁体   English

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

[英]How to generate a OpenCV 1D Histogram from 2D data?

I have a data set of paired values like (x,y). 我有一个成对的数据集,如(x,y)。 For example: x ranges from -40 to 60 and y from 0 to 100. Initially they are stored in a std::vector<std::pair<float,float>> but in a loop I convert them to a 2 channel cv::Mat to be able to pass it to OpenCV's cv::calcHist function. 例如:x的范围是-40至60,y的范围是0至100。最初它们存储在std::vector<std::pair<float,float>>但是在循环中,我将它们转换为2通道cv::Mat可以将其传递给OpenCV的cv::calcHist函数。 I'd like to achieve a 1D histogram like so: here . 我想要这样实现一维直方图: 这里 Since I actually have two data ranges, I always end up with a 2D Histogram as a result cv::Mat from cv::calcHist , but I basically would like to calculate based on a given bin_size x_bin for the x-axis the average of values in y. 由于我实际上有两个数据范围,因此我总是得到2D直方图,结果是cv::calcHist cv::Mat结果,但是我基本上想基于给定的bin_size x_bin为x轴计算x的平均值。 y中的值。

Take as an example: x ranges from -40 to 60, desired bins = 10, bin_size = 10, data points (x,y): (-35, 10), (-39, 20) The 1D histogram would then need to calculate the average of y = (10+20)/2 for the bin range from -40 to -30. 例如:x的范围是-40至60,所需的bins = 10,bin_size = 10,数据点(x,y):(-35,10),(-39,20)然后,一维直方图需要计算bin范围从-40到-30的y =(10 + 20)/ 2的平均值。

So the sum of each bin shouldn't be a simple count of values falling in that specific bin range but rather the average of values. 因此,每个bin的总和不应该是落入该特定bin范围内的值的简单计数,而应该是值的平均值。

I hope I could state the problem in an understandable way. 我希望我能以一种可以理解的方式陈述这个问题。 Any help is appreciated. 任何帮助表示赞赏。

I don't think OpenCV's cv::calcHist would be able to give you what you want, especially because you are trying to get stats on Y based on X. Anyway, it's not too hard to do it without OpenCV. 我认为OpenCV的cv::calcHist无法满足您的需求,尤其是因为您试图基于X获得Y的统计信息。无论如何,没有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]);
    }
  }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM