Home | History | Annotate | Download | only in rs
      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 }