- Timestamp:
- Jun 6, 2011, 5:55:42 PM (15 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/czw_branch/20110406/psModules/src/imcombine/pmStack.c
r31203 r31607 400 400 CHECKPIX(x, y, "keep: %d : %x (badMask = %x)\n", i, mask->data.PS_TYPE_IMAGE_MASK_DATA[yIn][xIn], *badMask); 401 401 } 402 402 403 pixelData->n = numGood; 403 404 if (variance) { … … 976 977 } 977 978 979 // KMM functions to do bimodality rejection of pixels 980 981 float 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 985 static 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 1097 static 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 1125 static 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 978 1157 979 1158 //////////////////////////////////////////////////////////////////////////////////////////////////////////////
Note:
See TracChangeset
for help on using the changeset viewer.
