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 }