Я хочу построить гистограмму с заранее определенным количеством бинов, определяемых ключами (в данном случае 12 * 5 = 60) в C ++, и не знаю, как это сделать. Вот минимальный пример:
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;
}*/
}
Теперь я не знаю, как обращаться с 12 корзинами theta_1, потому что я не могу просто сосчитать от 1 до 60 для моих корзин. Я также имею в виду, что может быть лучший способ, чем построение гистограммы (например, unordered_map, map, bucket_sort или что-то в этом роде). Но поэтому мне понадобятся конкретные / уникальные типы для моих ключей.
Таким образом, в конце я хочу посчитать вхождение каждой пары ключей (например, [2,12] имеет 10 вхождений).
Их ключи могут быть не просто парами, а даже тройками или четверками и храниться в vector<vector<float>>
,
Как насчет того, чтобы хранить его на карте? Затем вы можете просматривать карту, чтобы получить ключи и события.
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);
}
Других решений пока нет …