Repository navigation
Expand file tree
/
Copy pathDetectedBoxes.cpp
More file actions
97 lines (85 loc) · 3.04 KB
/
Copy pathDetectedBoxes.cpp
File metadata and controls
97 lines (85 loc) · 3.04 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
/* Detected Boxes
*
* From: https://github.com/PokemonAutomation/
*
*/
#include <map>
#include "DetectedBoxes.h"
namespace PokemonAutomation{
void merge_overlapping_boxes(
std::vector<ImagePixelBox>& input_boxes,
double tolerance
){
std::multimap<size_t, ImagePixelBox> boxes; // detection box area -> box
for (const ImagePixelBox& box : input_boxes){
boxes.emplace(box.area(), box);
}
input_boxes.clear();
// cout << "boxes.size() = " << boxes.size() << endl;
// default ratio is 1.2
double ratio = 1.0 + tolerance;
while (!boxes.empty()){
// Start from the smallest box:
auto current = boxes.begin();
const size_t current_area = current->first;
// get a max limit of area, e.g. current_box_area * 1.2
const size_t limit = (size_t)(current_area * ratio);
auto candidate = current;
++candidate;
while (candidate != boxes.end()){
// skip if candidate area > limit
if (candidate->first > limit){
break;
}
// candiate area <= limit, further testing there overlapped area
size_t overlap_area = current->second.overlapping_area(candidate->second);
if ((double)overlap_area * ratio > current_area){
current->second.merge_with(candidate->second);
candidate = boxes.erase(candidate);
}else{
++candidate;
}
}
input_boxes.emplace_back(current->second);
boxes.erase(current);
}
}
void merge_overlapping_boxes(
std::vector<DetectedBox>& input_boxes,
double tolerance
){
std::multimap<double, DetectedBox> boxes; // detection box area -> box
for (const DetectedBox& box : input_boxes){
boxes.emplace(box.box.area(), box);
}
input_boxes.clear();
// cout << "boxes.size() = " << boxes.size() << endl;
// default ratio is 1.2
double ratio = 1.0 + tolerance;
while (!boxes.empty()){
// Start from the smallest box:
auto current = boxes.begin();
const double current_area = current->first;
// get a max limit of area, e.g. current_box_area * 1.2
const double limit = (current_area * ratio);
auto candidate = current;
++candidate;
while (candidate != boxes.end()){
// skip if candidate area > limit
if (candidate->first > limit){
break;
}
// candiate area <= limit, further testing there overlapped area
double overlap_area = current->second.box.overlapping_area(candidate->second.box);
if (overlap_area * ratio > current_area){
current->second.box.merge_with(candidate->second.box);
candidate = boxes.erase(candidate);
}else{
++candidate;
}
}
input_boxes.emplace_back(current->second);
boxes.erase(current);
}
}
}