opencv 如何在C++中使用std::map从矢量中生成面元直方图?

lnlaulya  于 2022-11-15  发布在  其他
关注(0)|答案(1)|浏览(208)

我有一个浮点型的std::vector,包含1300个数据,即{1.45890123,1.47820920,1.48326172,...}我想使用std::map构建该向量的直方图,然后使用OpenCV绘制直方图。这就是我如何使用std::map获得每个数据的计数,但我不知道如何进行分组?

size_t frames = 1300
float_t *tdata = (float_t *)malloc(frames * sizeof(float_t));

std::vector<float_t> hdata(tdata, tdata + frames);
std::vector<double> hdata_range, hdata_count;
std::map<float_t, int> hgram;
for (const auto &x : hdata) ++hgram[x];
transform(hgram.begin(), hgram.end(), back_inserter(hdata_range), [](const auto& val){return val.first;});
transform(hgram.begin(), hgram.end(), back_inserter(hdata_count), [](const auto& val){return val.second;});

然后我用OpenCV绘制直方图,

Ptr<plot::Plot2d> plot_1b = plot::Plot2d::create(hdata_range, hdata_count);
    plot_1b->setNeedPlotLine(true);
    plot_1b->setShowText(false);
    plot_1b->setShowGrid(false);
    plot_1b->setPlotBackgroundColor(Scalar(255, 255, 255));
    plot_1b->setPlotLineColor(Scalar(0, 0, 0));
    plot_1b->setPlotLineWidth(5);
    plot_1b->setInvertOrientation(true);
    plot_1b->setPlotTextColor(Scalar(0, 0, 0));
    plot_1b->render(cv_display_hdata);

出现一个包含直方图的窗口,但由于我没有进行面元划分,因此每个数据的计数通常为1。但我想将面元划分添加到直方图中,以生成高斯(正态)分布直方图。
如何使用std::map实现这一点?
谢了,罗莉
用帕迪的解决方案,我能够产生一个更好的直方图,但最大计数是不同的Matlab,知道为什么吗?
No binning histogramMatlab histogram x1c 0d1x中的一个

ruyhziif

ruyhziif1#

如果你想使用std::map来划分数据,你可以简单地选择bin的起始值作为键。为此,除以bin的大小,然后计算floor。这将给予你一个唯一标识bin的整数。

float_t binsize = 1.0f;
std::map<float_t, int> hgram;
for (auto x : hdata) {
    ++hgram[std::floor(x / binsize)];
}

要将直方图数据范围转换为问题中使用的形式,只需按bin大小缩放键即可。您可以选择任何一个值来表示bin。它可以是bin的开始值或结束值。或者,在下面的示例中,我选择bin的中心:

hdata_range.reserve(hgram.size());
hdata_count.reserve(hgram.size());
for (const auto& keyval : hgram)
{
    hdata_range.push_back((keyval.first + 0.5f) * binsize);
    hdata_count.push_back(keyval.second);
}

相关问题