forked from brodyh/caffe
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathgroup_rectangles_with_aux.cpp
102 lines (89 loc) · 2.82 KB
/
group_rectangles_with_aux.cpp
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
98
99
100
101
102
#include <vector>
#include <iostream>
#include <opencv2/objdetect/objdetect.hpp>
using namespace std;
using cv::Rect;
class SimilarRects {
public:
SimilarRects(double _eps) : eps(_eps) {}
inline bool operator() (const vector<float>& r1, const vector<float>& r2) const {
double delta = eps * (std::min(r1[2], r2[2]) + std::min(r1[3], r2[3])) * 0.5;
return std::abs(r1[0] - r2[0]) <= delta &&
std::abs(r1[1] - r2[1]) <= delta &&
std::abs(r1[0] + r1[2] - r2[0] - r2[2]) <= delta &&
std::abs(r1[1] + r1[3] - r2[1] - r2[3]) <= delta;
}
double eps;
};
int groupRectanglesWithAux(float* input, int groupThreshold, float eps,
float* output, int* scores, int nrows, int ncols) {
if (groupThreshold <= 0 || nrows == 0) {
return 0;
}
vector<vector<float> > rectList(nrows, vector<float>(ncols));
for (int i = 0; i < nrows; ++i) {
int base_index = i * ncols;
for (int j = 0; j < ncols; ++j) {
if (j < 4) {
rectList[i][j] = cv::saturate_cast<int>(input[base_index + j]);
} else {
rectList[i][j] = input[base_index + j];
}
}
}
vector<int> labels;
int nclasses = cv::partition(rectList, labels, SimilarRects(eps));
vector<vector<float> > frects(nclasses, vector<float>(ncols));
vector<int> rweights(nclasses, 0);
int nlabels = (int) labels.size();
for (int i = 0; i < nlabels; i++) {
int cls = labels[i];
for (int j = 0; j < ncols; ++j) {
frects[cls][j] += rectList[i][j];
}
rweights[cls]++;
}
for (int i = 0; i < nclasses; i++) {
float s = 1.f / rweights[i];
for (int j = 0; j < ncols; ++j) {
float scaled = frects[i][j] * s;
if (j < 4) {
frects[i][j] = cv::saturate_cast<int>(scaled);
} else {
frects[i][j] = scaled;
}
}
}
int j;
int num_output = 0;
for (int i = 0; i < nclasses; i++) {
int r1 = i;
int n1 = rweights[i];
if (n1 <= groupThreshold)
continue;
// filter out small face rectangles inside large rectangles
for (j = 0; j < nclasses; j++) {
int n2 = rweights[j];
if (j == i || n2 <= groupThreshold)
continue;
int r2 = j;
int dx = cv::saturate_cast<int>(frects[r2][2] * eps);
int dy = cv::saturate_cast<int>(frects[r2][3] * eps);
if (i != j &&
frects[r1][0] >= frects[r2][0] - dx &&
frects[r1][1] >= frects[r2][1] - dy &&
frects[r1][0] + frects[r1][2] <= frects[r2][0] + frects[r2][2] + dx &&
frects[r1][1] + frects[r1][3] <= frects[r2][1] + frects[r2][3] + dy &&
(n2 > std::max(3, n1) || n1 < 3))
break;
}
if (j == nclasses) {
for (int k = 0; k < ncols; ++k) {
output[num_output * ncols + k] = frects[r1][k];
}
scores[num_output] = n1;
num_output++;
}
}
return num_output;
}