• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #pragma version(1)
2 #pragma rs java_package_name(unused)
3 #pragma rs_fp_relaxed
4 
5 #define numStumps 5000
6 #define numStages 22
7 #define numRect 3
8 #define numFeatures 10000
9 
10 typedef struct stag
11 {
12     int first;
13     int ntrees;
14     float threshold;
15 } HaarStage;
16 
17 typedef struct stum
18 {
19     int featureIdx;
20     float threshold;
21     float left;
22     float right;
23 } HaarStump;
24 
25 typedef struct optFe
26 {
27     uint4 ofs0;
28     uint4 ofs1;
29     uint4 ofs2;
30     float4 weight;
31 } HaarOptFeature;
32 
33 typedef struct Fe
34 {
35     int x[numRect];
36     int y[numRect];
37     int width[numRect];
38     int height[numRect];
39     float weight[numRect];
40 } HaarFeature;
41 
42 int sqofs;
43 uint4 nrect;
44 float normRectArea;
45 int stagesSize;
46 int width;
47 int height;
48 int origWidth;
49 int origHeight;
50 int yStep;
51 rs_allocation inAlloc;
52 rs_allocation inAllocSq;
53 
54 static HaarStump stumps[numStumps];
55 static HaarStage stages[numStages];
56 static HaarFeature haarFeatures[numFeatures];
57 static int currStage;
58 static int currStump;
59 static int currHf;
60 
61 static int calcSumOfs(const int x, const int of0, const int of1, const int of2, const int of3, const rs_allocation in) {
62     int t1 = rsGetElementAt_int(in, x + of0);
63     int t2 = rsGetElementAt_int(in, x + of1);
64     int t3 = rsGetElementAt_int(in, x + of2);
65     int t4 = rsGetElementAt_int(in, x + of3);
66     return t1 - t2 - t3 + t4;
67 }
68 
69 static int evaluateIntegral(const int x, const int imgWidth, const int offNum, const HaarFeature _f) {
70     int of0 = _f.x[offNum] + imgWidth * _f.y[offNum];
71     int of1 = _f.x[offNum] + _f.width[offNum] + imgWidth * _f.y[offNum];
72     int of2 = _f.x[offNum] + imgWidth * (_f.y[offNum] + _f.height[offNum]);
73     int of3 = _f.x[offNum] + _f.width[offNum] + imgWidth * (_f.y[offNum] + _f.height[offNum]);
74     return calcSumOfs(x,of0,of1,of2,of3, inAlloc);
75 }
76 
77 static int evaluateIntegralNof(const rs_allocation in, const int x, const int imgWidth) {
78     int of0 = nrect.s0 + imgWidth * nrect.s1;
79     int of1 = nrect.s0 + nrect.s2 + imgWidth * nrect.s1;
80     int of2 = nrect.s0 + imgWidth * (nrect.s1 + nrect.s3);
81     int of3 = nrect.s0 + nrect.s2 + imgWidth * (nrect.s1 + nrect.s3);
82     return calcSumOfs(x,of0,of1,of2,of3,in);
83 }
84 
85 bool RS_KERNEL runAtHaarKernel(const int in, const int x)
86 {
87     int x_check = x % width;
88     int y_check = x / width;
89     if (!(x_check % yStep == 0 && y_check % yStep == 0 ))
90         return false;
91     if( !(x_check < 0 || y_check < 0 ||
92       x_check + origWidth >= width ||
93       y_check + origHeight >= height )) {
94         float varianceNormFactor;
95         int valsum = evaluateIntegralNof(inAlloc,x, width);
96         unsigned valsqsum = (unsigned) evaluateIntegralNof(inAllocSq, x, width);
97         float area = normRectArea;
98         float nf = area * valsqsum - (float)valsum * valsum;
99 
100         if( nf > 0.f ) {
101            nf = sqrt((float)nf);
102            varianceNormFactor = (float)(1./nf);
103            if(!(area*varianceNormFactor < 0.1f)) return false;
104         }
105         else {
106             varianceNormFactor = 1.0f;
107             return false;
108         }
109 
110         int nstages = currStage;
111         float tmp = 0.f;
112         int stumpOfs = 0;
113 
114         for( int stageIdx = 0; stageIdx < nstages; stageIdx++ ) {
115              const HaarStage stage = stages[stageIdx];
116              tmp = 0.f;
117              int ntrees = stage.ntrees;
118 
119              for( int i = 0; i < ntrees; i++ ) {
120                const HaarStump stump = stumps[i + stumpOfs];
121                float ret = haarFeatures[stump.featureIdx].weight[0]
122                     * evaluateIntegral(x, width, 0, haarFeatures[stump.featureIdx])
123                     + haarFeatures[stump.featureIdx].weight[1]
124                     * evaluateIntegral(x, width, 1, haarFeatures[stump.featureIdx]);
125                if( haarFeatures[stump.featureIdx].weight[2] != 0.0f )
126                    ret += haarFeatures[stump.featureIdx].weight[2]
127                         * evaluateIntegral(x, width, 2, haarFeatures[stump.featureIdx]);
128                 ret *= varianceNormFactor;
129                 tmp += ret < stump.threshold ? stump.left : stump.right;
130              }
131 
132              if( tmp < stage.threshold ) return false;
133              stumpOfs += ntrees;
134         }
135         return true;
136     }
137     return false;
138 }
139 
140 void initCurr() {
141     currStump = 0;
142     currStage = 0;
143     currHf = 0;
144 }
145 
146 void addStage(const int first, const int ntrees, const float threshold) {
147     HaarStage h;
148     h.first = first;
149     h.ntrees = ntrees;
150     h.threshold = threshold;
151     stages[currStage] = h;
152     currStage++;
153 }
154 
155 void addStump(const int featureIdx, const float threshold, const float left, const float right) {
156     HaarStump h;
157     h.featureIdx = featureIdx;
158     h.threshold = threshold;
159     h.left = left;
160     h.right = right;
161     stumps[currStump] = h;
162     currStump++;
163 }
164 
165 void addHF(const int x0, const int y0, const int w0, const int h0,
166             const int x1, const int y1, const int w1, const int h1,
167             const int x2, const int y2, const int w2, const int h2,
168             const float we0, const float we1, const float we2) {
169     HaarFeature f;
170     f.x[0] = x0;
171     f.x[1] = x1;
172     f.x[2] = x2;
173 
174     f.y[0] = y0;
175     f.y[1] = y1;
176     f.y[2] = y2;
177 
178     f.width[0] = w0;
179     f.width[1] = w1;
180     f.width[2] = w2;
181 
182     f.height[0] = h0;
183     f.height[1] = h1;
184     f.height[2] = h2;
185 
186     f.weight[0] = we0;
187     f.weight[1] = we1;
188     f.weight[2] = we2;
189 
190     haarFeatures[currHf] = f;
191     currHf++;
192 }