forked from wikimedia/integration-uprightdiff
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathRollingBlockCounter.h
76 lines (70 loc) · 1.86 KB
/
RollingBlockCounter.h
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
#include <opencv2/core/core.hpp>
template <class Mat>
class RollingBlockCounter {
public:
RollingBlockCounter(const Mat & mat, int centreX, int window);
void purge() {
m_valid = false;
}
int operator ()(int centreY);
private:
inline static cv::Rect GetBounds(int width, int height, int centreX, int window);
int m_halfWindow;
Mat m_strip;
int m_cy;
bool m_valid;
int m_count;
};
template <class Mat>
RollingBlockCounter<Mat>::RollingBlockCounter(const Mat & mat, int cx, int window)
: m_halfWindow((window - 1) / 2),
m_strip(mat, GetBounds(mat.cols, mat.rows, cx, window)),
m_cy(0), m_valid(false), m_count(0)
{}
template <class Mat>
cv::Rect RollingBlockCounter<Mat>::GetBounds(int width, int height, int cx, int window) {
int halfWindow = (window - 1) / 2;
int left = std::max(cx - halfWindow, 0);
int right = std::min(cx + halfWindow + 1, width);
return cv::Rect(left, 0, right - left, height);
}
template <class Mat>
int RollingBlockCounter<Mat>::operator ()(int cy) {
int delta = 0;
if (m_valid && cy == m_cy) {
// No update needed
} else if (m_valid && cy == m_cy + 1) {
// Incremental calculation
// Subtract top row (if any)
int topY = cy - m_halfWindow - 1;
if (topY >= 0) {
auto * row = m_strip[topY];
for (int x = 0; x < m_strip.cols; x++) {
delta -= row[x];
}
}
// Add bottom row
int bottomY = cy + m_halfWindow;
if (bottomY < m_strip.rows) {
auto * row = m_strip[bottomY];
for (int x = 0; x < m_strip.cols; x++) {
delta += row[x];
}
}
m_count += delta;
} else {
// Calculate from scratch
int topY = std::max(cy - m_halfWindow, 0);
int bottomY = std::min(cy + m_halfWindow, m_strip.rows - 1);
for (int y = topY; y <= bottomY; y++) {
auto * row = m_strip[y];
for (int x = 0; x < m_strip.cols; x++) {
delta += row[x];
}
}
m_count = delta;
}
m_valid = true;
m_cy = cy;
return m_count;
}