Commit bb586c3d6d3f3dbbed5ab2bd2b772854e7679027

Authored by Scott Klum
2 parents ab5f003b 0fc931ed

Merge pull request #454 from biometrics/haar_memory_opt

allocate less memory
openbr/plugins/representation/haar.cpp
@@ -40,37 +40,51 @@ class HaarRepresentation : public Representation @@ -40,37 +40,51 @@ class HaarRepresentation : public Representation
40 void init() 40 void init()
41 { 41 {
42 if (features.isEmpty()) { 42 if (features.isEmpty()) {
43 - int offset = winWidth + 1; 43 + // Pre-determine the size of features to avoid reallocations
  44 + int numFeatures = 0;
  45 + for (int x = 0; x < winWidth; x++)
  46 + for (int y = 0; y < winHeight; y++)
  47 + for (int dx = 1; dx <= winWidth; dx++)
  48 + for (int dy = 1; dy <= winHeight; dy++)
  49 + numFeatures += ((x+dx*2 <= winWidth) && (y+dy <= winHeight))
  50 + + ((x+dx <= winWidth) && (y+dy*2 <= winHeight))
  51 + + ((x+dx*3 <= winWidth) && (y+dy <= winHeight))
  52 + + ((x+dx <= winWidth) && (y+dy*3 <= winHeight))
  53 + + ((x+dx*2 <= winWidth) && (y+dy*2 <= winHeight));
  54 + features.reserve(numFeatures);
  55 +
  56 + const int offset = winWidth + 1;
  57 + int index = 0;
44 for (int x = 0; x < winWidth; x++) { 58 for (int x = 0; x < winWidth; x++) {
45 for (int y = 0; y < winHeight; y++) { 59 for (int y = 0; y < winHeight; y++) {
46 for (int dx = 1; dx <= winWidth; dx++) { 60 for (int dx = 1; dx <= winWidth; dx++) {
47 for (int dy = 1; dy <= winHeight; dy++) { 61 for (int dy = 1; dy <= winHeight; dy++) {
48 // haar_x2 62 // haar_x2
49 if ((x+dx*2 <= winWidth) && (y+dy <= winHeight)) 63 if ((x+dx*2 <= winWidth) && (y+dy <= winHeight))
50 - features.append(Feature(offset, 64 + features[index++] = Feature(offset,
51 x, y, dx*2, dy, -1, 65 x, y, dx*2, dy, -1,
52 - x+dx, y, dx , dy, +2)); 66 + x+dx, y, dx , dy, +2);
53 // haar_y2 67 // haar_y2
54 if ((x+dx <= winWidth) && (y+dy*2 <= winHeight)) 68 if ((x+dx <= winWidth) && (y+dy*2 <= winHeight))
55 - features.append(Feature(offset, 69 + features[index++] = Feature(offset,
56 x, y, dx, dy*2, -1, 70 x, y, dx, dy*2, -1,
57 - x, y+dy, dx, dy, +2)); 71 + x, y+dy, dx, dy, +2);
58 // haar_x3 72 // haar_x3
59 if ((x+dx*3 <= winWidth) && (y+dy <= winHeight)) 73 if ((x+dx*3 <= winWidth) && (y+dy <= winHeight))
60 - features.append(Feature(offset, 74 + features[index++] = Feature(offset,
61 x, y, dx*3, dy, -1, 75 x, y, dx*3, dy, -1,
62 - x+dx, y, dx , dy, +3)); 76 + x+dx, y, dx , dy, +3);
63 // haar_y3 77 // haar_y3
64 if ((x+dx <= winWidth) && (y+dy*3 <= winHeight)) 78 if ((x+dx <= winWidth) && (y+dy*3 <= winHeight))
65 - features.append(Feature(offset, 79 + features[index++] = Feature(offset,
66 x, y, dx, dy*3, -1, 80 x, y, dx, dy*3, -1,
67 - x, y+dy, dx, dy, +3)); 81 + x, y+dy, dx, dy, +3);
68 // x2_y2 82 // x2_y2
69 if ((x+dx*2 <= winWidth) && (y+dy*2 <= winHeight)) 83 if ((x+dx*2 <= winWidth) && (y+dy*2 <= winHeight))
70 - features.append(Feature(offset, 84 + features[index++] = Feature(offset,
71 x, y, dx*2, dy*2, -1, 85 x, y, dx*2, dy*2, -1,
72 x, y, dx, dy, +2, 86 x, y, dx, dy, +2,
73 - x+dx, y+dy, dx, dy, +2)); 87 + x+dx, y+dy, dx, dy, +2);
74 88
75 89
76 } 90 }
@@ -89,7 +103,7 @@ class HaarRepresentation : public Representation @@ -89,7 +103,7 @@ class HaarRepresentation : public Representation
89 103
90 float evaluate(const Template &src, int idx) const 104 float evaluate(const Template &src, int idx) const
91 { 105 {
92 - return (float)features[idx].calc(src.m()); 106 + return features[idx].calc(src.m());
93 } 107 }
94 108
95 Mat evaluate(const Template &src, const QList<int> &indices) const 109 Mat evaluate(const Template &src, const QList<int> &indices) const
@@ -126,24 +140,23 @@ class HaarRepresentation : public Representation @@ -126,24 +140,23 @@ class HaarRepresentation : public Representation
126 float calc(const Mat &img) const; 140 float calc(const Mat &img) const;
127 141
128 struct { 142 struct {
129 - Rect r;  
130 float weight; 143 float weight;
131 - } rect[3];  
132 -  
133 - struct {  
134 int p0, p1, p2, p3; 144 int p0, p1, p2, p3;
135 } fastRect[3]; 145 } fastRect[3];
136 }; 146 };
137 147
138 - QList<Feature> features; 148 + QVector<Feature> features;
139 }; 149 };
140 150
141 BR_REGISTER(Representation, HaarRepresentation) 151 BR_REGISTER(Representation, HaarRepresentation)
142 152
143 HaarRepresentation::Feature::Feature() 153 HaarRepresentation::Feature::Feature()
144 { 154 {
145 - rect[0].r = rect[1].r = rect[2].r = Rect(0,0,0,0);  
146 - rect[0].weight = rect[1].weight = rect[2].weight = 0; 155 + fastRect[0].p0 = fastRect[1].p0 = fastRect[2].p0 = 0;
  156 + fastRect[0].p1 = fastRect[1].p1 = fastRect[2].p1 = 0;
  157 + fastRect[0].p2 = fastRect[1].p2 = fastRect[2].p2 = 0;
  158 + fastRect[0].p3 = fastRect[1].p3 = fastRect[2].p3 = 0;
  159 + fastRect[0].weight = fastRect[1].weight = fastRect[2].weight = 0;
147 } 160 }
148 161
149 HaarRepresentation::Feature::Feature(int offset, 162 HaarRepresentation::Feature::Feature(int offset,
@@ -151,38 +164,21 @@ HaarRepresentation::Feature::Feature(int offset, @@ -151,38 +164,21 @@ HaarRepresentation::Feature::Feature(int offset,
151 int x1, int y1, int w1, int h1, float wt1, 164 int x1, int y1, int w1, int h1, float wt1,
152 int x2, int y2, int w2, int h2, float wt2) 165 int x2, int y2, int w2, int h2, float wt2)
153 { 166 {
154 - rect[0].r.x = x0;  
155 - rect[0].r.y = y0;  
156 - rect[0].r.width = w0;  
157 - rect[0].r.height = h0;  
158 - rect[0].weight = wt0;  
159 -  
160 - rect[1].r.x = x1;  
161 - rect[1].r.y = y1;  
162 - rect[1].r.width = w1;  
163 - rect[1].r.height = h1;  
164 - rect[1].weight = wt1;  
165 -  
166 - rect[2].r.x = x2;  
167 - rect[2].r.y = y2;  
168 - rect[2].r.width = w2;  
169 - rect[2].r.height = h2;  
170 - rect[2].weight = wt2;  
171 -  
172 - for (int j = 0; j < 3; j++) {  
173 - if( rect[j].weight == 0.0F )  
174 - break;  
175 - CV_SUM_OFFSETS(fastRect[j].p0, fastRect[j].p1, fastRect[j].p2, fastRect[j].p3, rect[j].r, offset)  
176 - } 167 + CV_SUM_OFFSETS(fastRect[0].p0, fastRect[0].p1, fastRect[0].p2, fastRect[0].p3, Rect(x0, y0, w0, h0), offset)
  168 + CV_SUM_OFFSETS(fastRect[1].p0, fastRect[1].p1, fastRect[1].p2, fastRect[1].p3, Rect(x1, y1, w1, h1), offset)
  169 + CV_SUM_OFFSETS(fastRect[2].p0, fastRect[2].p1, fastRect[2].p2, fastRect[2].p3, Rect(x2, y2, w2, h2), offset)
  170 + fastRect[0].weight = wt0;
  171 + fastRect[1].weight = wt1;
  172 + fastRect[2].weight = wt2;
177 } 173 }
178 174
179 inline float HaarRepresentation::Feature::calc(const Mat &img) const 175 inline float HaarRepresentation::Feature::calc(const Mat &img) const
180 { 176 {
181 const int* ptr = img.ptr<int>(); 177 const int* ptr = img.ptr<int>();
182 - float ret = rect[0].weight * (ptr[fastRect[0].p0] - ptr[fastRect[0].p1] - ptr[fastRect[0].p2] + ptr[fastRect[0].p3]) +  
183 - rect[1].weight * (ptr[fastRect[1].p0] - ptr[fastRect[1].p1] - ptr[fastRect[1].p2] + ptr[fastRect[1].p3]);  
184 - if (rect[2].weight != 0.0f)  
185 - ret += rect[2].weight * (ptr[fastRect[2].p0] - ptr[fastRect[2].p1] - ptr[fastRect[2].p2] + ptr[fastRect[2].p3]); 178 + float ret = fastRect[0].weight * (ptr[fastRect[0].p0] - ptr[fastRect[0].p1] - ptr[fastRect[0].p2] + ptr[fastRect[0].p3]) +
  179 + fastRect[1].weight * (ptr[fastRect[1].p0] - ptr[fastRect[1].p1] - ptr[fastRect[1].p2] + ptr[fastRect[1].p3]);
  180 + if (fastRect[2].weight != 0.0f)
  181 + ret += fastRect[2].weight * (ptr[fastRect[2].p0] - ptr[fastRect[2].p1] - ptr[fastRect[2].p2] + ptr[fastRect[2].p3]);
186 return ret; 182 return ret;
187 } 183 }
188 184