IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Ignore:
Timestamp:
Jun 6, 2011, 5:55:42 PM (15 years ago)
Author:
watersc1
Message:

Added KMM code. Unclear how to add this to the existing code to update the rejection list, but I'll sort that out tomorrow.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/czw_branch/20110406/psModules/src/imcombine/pmStack.c

    r31203 r31607  
    400400        CHECKPIX(x, y, "keep: %d : %x (badMask = %x)\n", i, mask->data.PS_TYPE_IMAGE_MASK_DATA[yIn][xIn], *badMask);
    401401    }
     402   
    402403    pixelData->n = numGood;
    403404    if (variance) {
     
    976977}
    977978
     979// KMM functions to do bimodality rejection of pixels
     980
     981float gaussian(float x, float m, float s) {
     982  return(pow(s * sqrt(2 * M_PI),-1) * exp(-0.5 * pow( (x - m) / s, 2)));
     983}
     984
     985static void KMMcalculate(const psVector *values,
     986                         float *Punimodal,
     987                         float *pi1, float *m1, float *s1,
     988                         float *pi2, float *m2, float *s2) {
     989  double logL_bimodal = 0, logL_unimodal;
     990  float mU,sU;
     991  psVector *P1 = psVectorAlloc(values->n,PS_TYPE_F32);
     992  psVector *P2 = psVectorAlloc(values->n,PS_TYPE_F32);
     993  int i;
     994 
     995  // Calculate unimodal properties
     996  mU = 0;
     997  sU = 0;
     998  logL_unimodal = 0;
     999  for (i = 0; i < values->n; i++) { // Calculate mean
     1000    mU += values->data.F32[i];
     1001  }
     1002  mU /= values->n;
     1003  for (i = 0; i < values->n; i++) { // Calculate sigma
     1004    sU += pow(values->data.F32[i] - mU,2);
     1005  }
     1006  sU = sqrt(sU / values->n);
     1007  for (i = 0; i < values->n; i++) { // Calculate log likelihood
     1008    logL_unimodal += log(gaussian(values->data.F32[i],mU,sU));
     1009  }
     1010
     1011  // Do EM loop
     1012  float dL = 0;
     1013  float oldL = -999;
     1014  int k = 0;
     1015  logL_bimodal = logL_unimodal;
     1016  *m1 = mU - 3 * sU;
     1017  *m2 = mU + 3 * sU;
     1018  *s1 = sU / 2;
     1019  *s2 = sU / 2;
     1020  *pi1 = 0.5;
     1021  *pi2 = 0.5;
     1022
     1023  float g1,g2,norm;
     1024  float w1,w2;
     1025
     1026  while (((dL > KMM_TOLERANCE)||(k < 3))&&(k < KMM_MAX_ITERATIONS)) {
     1027    k++;
     1028    dL = fabs(logL_bimodal - oldL);
     1029    oldL = logL_bimodal;
     1030
     1031    // Expectation/P-stage
     1032    for (i = 0; i < values->n; i++) { // Calculate probabilities for each mode
     1033      g1 = gaussian(values->data.F32[i],*m1,*s1);
     1034      g2 = gaussian(values->data.F32[i],*m2,*s2);
     1035      norm = (*pi1 * g1 + *pi2 * g2);
     1036      P1->data.F32[i] = (*pi1 * g1) / norm;
     1037      P2->data.F32[i] = (*pi2 * g2) / norm;
     1038    }
     1039    // Maximization/M-stage
     1040    logL_bimodal = 0;
     1041    w1 = 0;
     1042    w2 = 0;
     1043    for (i = 0; i < values->n; i++) { // Calculate log likelihood
     1044      if (!((*pi1 == 0)||(*pi2 == 0))) {
     1045        logL_bimodal += log(*pi1 * gaussian(values->data.F32[i],*m1,*s1) +
     1046                            *pi2 * gaussian(values->data.F32[i],*m2,*s2));
     1047      }
     1048    }
     1049    *m1 = 0;
     1050    *m2 = 0;
     1051    *s1 = 0;
     1052    *s2 = 0;
     1053    for (i = 0; i < values->n; i++) { // Calculate new means
     1054      *m1 += values->data.F32[i] * P1->data.F32[i];
     1055      *m2 += values->data.F32[i] * P2->data.F32[i];
     1056
     1057      w1 += P1[i];
     1058      w2 += P2[i];
     1059    }
     1060    *m1 /= w1;
     1061    *m2 /= w2;
     1062    for (i = 0; i < values->n; i++) { // Calculate new sigmas
     1063      *s1 += pow(values->data.F32[i] - *m1,2) * P1->data.F32[i];
     1064      *s2 += pow(values->data.F32[i] - *m2,2) * P2->data.F32[i];
     1065    }
     1066    *s1 = sqrt(*s1 / w1);
     1067    *s2 = sqrt(*s2 / w2);
     1068
     1069    *pi1 = w1 / values->n;
     1070    *pi2 = w2 / values->n;
     1071
     1072    if (!isfinite(*pi1)) { // finite checks
     1073      *pi1 = 0.0;
     1074    }
     1075    if (!isfinite(*pi2)) { // finite checks
     1076      *pi2 = 0.0;
     1077    }
     1078    if (*s1 == 0) { // sigma may not be zero
     1079      *s1 = KMM_SMALL_NUMBER * *m1;
     1080    }
     1081    if (*s2 == 0) { // sigma may not be zero
     1082      *s2 = KMM_SMALL_NUMBER * *m2;
     1083    }
     1084  } // End EM phase
     1085
     1086  // Calculate Punimodal
     1087  double lambda = -2.0 * (logL_unimodal - logL_bimodal);
     1088  int    df     = 2 + 2 * 1;
     1089  if (lambda > 0) {
     1090    *Punimodal = gsl_cdf_chisq_Q(lambda,df);
     1091  }
     1092  else {
     1093    *Punimodal = 1.0;
     1094  } 
     1095}
     1096
     1097static void KMMrejectUnpopular(const psVector *values, psArray *reject) {
     1098  float Punimodal,pi1,m1,s1,pi2,m2,s2;
     1099  KMMcalculate(values,&Punimodal,
     1100               &pi1,&m1,&s1,
     1101               &pi2,&m2,&s2);
     1102  if (Punimodal < KMM_MINIMUM_PVALUE) {
     1103    int i;
     1104    float g1,g2;
     1105    float P1,P2;
     1106
     1107    for (i = 0; i < values->n; i++) { // Calculate probabilities for each mode
     1108      g1 = gaussian(values->data.F32[i],m1,s1);
     1109      g2 = gaussian(values->data.F32[i],m2,s2);
     1110      norm = (pi1 * g1 + pi2 * g2);
     1111      P1 = (pi1 * g1) / norm;
     1112      P2 = (pi2 * g2) / norm;
     1113
     1114      if ((pi1 > pi2)&&(P1 < P2)) { // mode 1 is more popular, but this element belongs to mode 2
     1115        reject_input(reject,i);
     1116      }
     1117      if ((pi1 < pi2)&&(P1 > P2)) { // mode 2 is more popular, but this element belongs to mode 1
     1118        reject_input(reject,i);
     1119      }
     1120    }
     1121  }
     1122  // else do nothing.
     1123}
     1124
     1125static void KMMrejectBright(const psVector *values, psArray *reject) {
     1126  KMMcalculate(values,&Punimodal,
     1127               &pi1,&m1,&s1,
     1128               &pi2,&m2,&s2);
     1129  if (Punimodal < KMM_MINIMUM_PVALUE) {
     1130    int i;
     1131    float g1,g2;
     1132    float P1,P2;
     1133
     1134    for (i = 0; i < values->n; i++) { // Calculate probabilities for each mode
     1135      g1 = gaussian(values->data.F32[i],m1,s1);
     1136      g2 = gaussian(values->data.F32[i],m2,s2);
     1137      norm = (pi1 * g1 + pi2 * g2);
     1138      P1 = (pi1 * g1) / norm;
     1139      P2 = (pi2 * g2) / norm;
     1140
     1141      if ((m1 > m2)&&(P1 > P2)) { // m1 is larger, and this element belongs to mode 1
     1142        reject_input(reject,i);
     1143      }
     1144      if ((m1 < m2)&&(P1 < P2)) { // m2 is larger, and this element belongs to mode 2
     1145        reject_input(reject,i);
     1146      }
     1147    }
     1148  }
     1149  // else do nothing.
     1150}
     1151                               
     1152                               
     1153   
     1154 
     1155 
     1156 
    9781157
    9791158//////////////////////////////////////////////////////////////////////////////////////////////////////////////
Note: See TracChangeset for help on using the changeset viewer.