我有一个像(x,y)这样的成对值的数据集。例如:x的范围从-40到60,y的范围从0到100。最初,它们存储在std::vector<std::pair<float,float>>
中,但在循环中,我将它们转换为2通道cv::Mat
,以便能够将其传递给OpenCV的cv::calcHist
函数。我想实现这样的1D直方图:在这里。由于我实际上有两个数据范围,我总是得到一个2D直方图作为cv::calcHist
的结果cv::Mat
,但我基本上想基于x轴的给定bin_size x_bin
来计算y中值的平均值。
举个例子:x的范围从-40到60,所需的bins=10,bin_size=10,数据点(x,y):(-35,10),(-39,20)然后,1D直方图将需要计算从-40到-30的区间的y=(10+20)/2的平均值。
因此,每个bin的总和不应该是落在特定bin范围内的值的简单计数,而是值的平均值。
我希望我能用一种可以理解的方式来说明这个问题。感谢您的帮助。
我不认为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]);
}
}
}