我想在C ++中构建一个具有由键定义的预定数量的bin(在这种情况下为12 * 5 = 60)的直方图,并且不知道如何操作。这是一个最低限度的例子:
using namespace std;
using namespace cv;
// Function to calculate the keys defining specific ranges of r1 and theta_1
void getKeys(vector<float> r1_vector, vector<float> theta_1_vector, vector<vector<float>> &keys) {
int r1_bin = 0;
int r2_bin = 0;
int theta1_bin = 0;
vector<float> key;
// r1 is divided equally into 5 bins ranging from -0.3 to 1.3
for (size_t i = 0; i < r1_vector.size(); i++) {
if (-0.3 <= r1_vector[i] && r1_vector[i] < 0.02) {
r1_bin = 1;
}
else if (0.02 <= r1_vector[i] && r1_vector[i] < 0.34) {
r1_bin = 2;
}
else if (0.34 <= r1_vector[i] && r1_vector[i] < 0.66) {
r1_bin = 3;
}
else if (0.66 <= r1_vector[i] && r1_vector[i] < 0.98) {
r1_bin = 4;
}
else if (0.98 <= r1_vector[i] && r1_vector[i] <= 1.30) {
r1_bin = 5;
}
// theta_1 is divided equally into 12 bins ranging from 0 to 2*PI
if (0 <= theta_1_vector[i] && theta_1_vector[i] < CV_PI / 6) {
theta1_bin = 1;
}
else if (CV_PI / 6 <= theta_1_vector[i] && theta_1_vector[i] < CV_PI / 3) {
theta1_bin = 2;
}
else if (CV_PI / 6 <= theta_1_vector[i] && theta_1_vector[i] < CV_PI / 2) {
theta1_bin = 3;
}
else if (CV_PI / 2 <= theta_1_vector[i] && theta_1_vector[i] < 2 * CV_PI / 3) {
theta1_bin = 4;
}
else if (2 * CV_PI / 3 <= theta_1_vector[i] && theta_1_vector[i] < 5 * CV_PI / 6) {
theta1_bin = 5;
}
else if (5 * CV_PI / 6 <= theta_1_vector[i] && theta_1_vector[i] < CV_PI) {
theta1_bin = 6;
}
else if (CV_PI <= theta_1_vector[i] && theta_1_vector[i] < 7 * CV_PI / 6) {
theta1_bin = 7;
}
else if (7 * CV_PI / 6 <= theta_1_vector[i] && theta_1_vector[i] < 4 * CV_PI / 3) {
theta1_bin = 8;
}
else if (4 * CV_PI / 3 <= theta_1_vector[i] && theta_1_vector[i] < 3 * CV_PI / 2) {
theta1_bin = 9;
}
else if (3 * CV_PI / 2 <= theta_1_vector[i] && theta_1_vector[i] < 5 * CV_PI / 3) {
theta1_bin = 10;
}
else if (5 * CV_PI / 3 <= theta_1_vector[i] && theta_1_vector[i] < 11 * CV_PI / 6) {
theta1_bin = 11;
}
else if (11 * CV_PI / 6 <= theta_1_vector[i] && theta_1_vector[i] <= 2 * CV_PI) {
theta1_bin = 12;
}
key.push_back(r1_bin);
key.push_back(theta1_bin);
keys.push_back(key);
key.clear();
}
}
int main(int argc, char** argv)
{
// Create some values - both vectors have the same size
vector<float> r1_vec;
r1_vec.push_back(-0.2);
r1_vec.push_back(1.2);
r1_vec.push_back(0.2);
r1_vec.push_back(0.3);
r1_vec.push_back(0.35);
r1_vec.push_back(0.2);
r1_vec.push_back(0.8);
r1_vec.push_back(0.8);
vector<float> theta_vec;
theta_vec.push_back(1.4);
theta_vec.push_back(2.4);
theta_vec.push_back(3.7);
theta_vec.push_back(2.4);
theta_vec.push_back(1.5);
theta_vec.push_back(1.6);
theta_vec.push_back(2.4);
theta_vec.push_back(5.8);
vector<vector<float>> keys;
getKeys(r1_vec, theta_vec, keys);
// Print values
/*for (size_t i = 0; i < keys.size(); i++) {
cout << "The keys for line one are: " << keys[i][0] << ", " << keys[i][1] << endl;
}*/
}
现在我不知道如何处理theta_1的12个箱子,因为我的箱子不能简单地计算从1到60。我还记得,可能有比构建直方图更好的方法(例如unordered_map,map,bucket_sort或类似的东西)。但因此我需要特定/唯一类型的键。
所以最后我想计算每对键的出现次数(例如[2,12]有10个出现)。
它们的键可能不仅仅是成对,而是三倍或四倍,并存储在vector<vector<float>>
中。
答案 0 :(得分:1)
如何将它存储在地图中呢?然后,您可以通过地图进行交互以获取键和出现。
class Histogram
{
map<int, int> HistMap; //key is the bin, value is count in bin
void InsertIntoHMap(int);
void CheckR1(float);
void CheckTheta1(float);
public:
Histogram() {}
void FillHistMap(vector<float>&, vector<float>&);
map<int, int>& GetHMap();
~Histogram() {}
};
void Histogram::InsertIntoHMap(int bin)
{
if(HistMap.find(bin) == HistMap.end()) HistMap.insert({bin, 1});
else HistMap[bin]++;
}
void Histogram::CheckR1(float r1)
{
if (-0.3 <= r1 && r1 < 0.02) InsertIntoHMap(1);
else if (0.02 <= r1 && r1 < 0.34) InsertIntoHMap(2);
else if (0.34 <= r1 && r1 < 0.66) InsertIntoHMap(3);
else if (0.66 <= r1 && r1 < 0.98) InsertIntoHMap(4);
else if (0.98 <= r1 && r1 <= 1.30) InsertIntoHMap(5);
}
void Histogram::CheckTheta1(float t1)
{
// theta_1 is divided equally into 12 bins ranging from 0 to 2*PI
if (0 <= t1 && t1 < CV_PI / 6) InsertIntoHMap(1);
else if (CV_PI / 6 <= t1 && t1 < CV_PI / 3) InsertIntoHMap(2);
else if (CV_PI / 6 <= t1 && t1 < CV_PI / 2) InsertIntoHMap(3);
else if (CV_PI / 2 <= t1 && t1 < 2 * CV_PI / 3) InsertIntoHMap(4);
else if (2 * CV_PI / 3 <= t1 && t1 < 5 * CV_PI / 6) InsertIntoHMap(5);
else if (5 * CV_PI / 6 <= t1 && t1 < CV_PI) InsertIntoHMap(6);
else if (CV_PI <= t1 && t1 < 7 * CV_PI / 6) InsertIntoHMap(7);
else if (7 * CV_PI / 6 <= t1 && t1 < 4 * CV_PI / 3) InsertIntoHMap(8);
else if (4 * CV_PI / 3 <= t1 && t1 < 3 * CV_PI / 2) InsertIntoHMap(9);
else if (3 * CV_PI / 2 <= t1 && t1 < 5 * CV_PI / 3) InsertIntoHMap(10);
else if (5 * CV_PI / 3 <= t1 && t1 < 11 * CV_PI / 6) InsertIntoHMap(11);
else if (11 * CV_PI / 6 <= t1 && t1 <= 2 * CV_PI) InsertIntoHMap(12)
}
void Histogram::FillHistMap(vector<float>& r1_vector, vector<float>& theta_1_vector)
{
for (size_t i = 0; i < r1_vector.size(); i++)
{
CheckR1(r1_vector[i]);
CheckTheta1(theta_1_vector[i]);
}
}
int main()
{
vector<float> r1_vec;
r1_vec.push_back(-0.2);
r1_vec.push_back(1.2);
r1_vec.push_back(0.2);
r1_vec.push_back(0.3);
r1_vec.push_back(0.35);
r1_vec.push_back(0.2);
r1_vec.push_back(0.8);
r1_vec.push_back(0.8);
vector<float> theta_vec;
theta_vec.push_back(1.4);
theta_vec.push_back(2.4);
theta_vec.push_back(3.7);
theta_vec.push_back(2.4);
theta_vec.push_back(1.5);
theta_vec.push_back(1.6);
theta_vec.push_back(2.4);
theta_vec.push_back(5.8);
Histogram H;
H.FillHistMap(r1_vec, theta_vec);
}
答案 1 :(得分:0)
类似的东西怎么样
#include <map>
#include <random>
#include <iostream>
struct histogram
{
histogram(const std::initializer_list<double>& edges)
{
for (auto e : edges) _bins[e] = 0;
}
histogram(size_t n, double low, double high)
{
double x = low;
double dx = (high-low) / n;
while (x <= high) { _bins[x] = 0; x += dx; }
}
void fill(double val)
{
if (val < _bins.begin()->first || val > _bins.rbegin()->first)
return;
std::prev(_bins.upper_bound(val))->second++;
}
void print(std::ostream& o) const
{
for (auto b1 = _bins.begin(), b2 = std::next(b1) ;
b2 != _bins.end(); ++b1, ++b2)
o << b1->first << "\t- " << b2->first << ":\t"
<< std::string(b1->second,'*')
<< std::endl;
}
std::map<double,size_t> _bins;
};
int main()
{
std::default_random_engine rnd(12345);
std::normal_distribution<double> norm(0,1);
histogram h1(6,-3,3);
histogram h2{-3,-2,-1,0,1,2,3};
for (size_t i = 0; i < 100; i++) {
auto x = norm(rnd);
h1.fill(x);
h2.fill(x);
}
std::cout << "h1: " << std::endl;
h1.print(std::cout);
std::cout << "h2: " << std::endl;
h2.print(std::cout);
return 0;
}
这使用 std::map<K,V>::lower_bound
来查找 bin。剩下的主要是糖。