📄 classify_util.cpp
字号:
/** All questions regarding the software should be addressed to* * Prof. Charles A. Bouman* Purdue University* School of Electrical and Computer Engineering* 1285 Electrical Engineering Building* West Lafayette, IN 47907-1285* USA* +1 765 494 0340* +1 765 494 3358 (fax)* email: bouman@ecn.purdue.edu* http://www.ece.purdue.edu/~bouman* * Copyright (c) 1995 The Board of Trustees of Purdue University.** Permission to use, copy, modify, and distribute this software and its* documentation for any purpose, without fee, and without written agreement is* hereby granted, provided that the above copyright notice and the following* two paragraphs appear in all copies of this software.** IN NO EVENT SHALL PURDUE UNIVERSITY BE LIABLE TO ANY PARTY FOR DIRECT,* INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE* USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF PURDUE UNIVERSITY HAS* BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.** PURDUE UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A* PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS,* AND PURDUE UNIVERSITY HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT,* UPDATES, ENHANCEMENTS, OR MODIFICATIONS.*/#include "stdafx.h"
#include "clust_defs.h"#include "alloc_util.h"#include "classify_util.h"void ClassLogLikelihood( double *vector, double *ll, /* log likelihood, ll[class] */ struct SigSet *S /* class signatures */){ int m; /* class index */ int k; /* subclass index */ int b1,b2; /* spectral index */ int max_nsubclasses; /* maximum number of subclasses */ int nbands; /* number of spectral bands */ double *subll; /* log likelihood of subclasses */ double *diff; double maxlike; double subsum; struct SigSet::ClassSig *C; struct SigSet::ClassSig::SubSig *SubS; nbands = S->nbands; /* determine the maximum number of subclasses */ max_nsubclasses = 0; for(m=0; m<S->nclasses; m++ ) if(S->ClassSig[m].nsubclasses>max_nsubclasses) max_nsubclasses = S->ClassSig[m].nsubclasses; /* allocate memory */ diff = (double *)G_malloc(nbands*sizeof(double)); subll = (double *)G_malloc(max_nsubclasses*sizeof(double)); /* Compute log likelihood for each class */ /* for each class */ for(m=0; m<S->nclasses; m++ ) { C = &(S->ClassSig[m]); /* compute log likelihood for each subclass */ for(k=0; k<C->nsubclasses; k++) { SubS = &(C->SubSig[k]); subll[k] = SubS->cnst; for(b1=0; b1<nbands; b1++) { diff[b1] = vector[b1] - SubS->means[b1]; subll[k] -= 0.5*diff[b1]*diff[b1]*SubS->Rinv[b1][b1]; } for(b1=0; b1<nbands; b1++) for(b2=b1+1; b2<nbands; b2++) subll[k] -= diff[b1]*diff[b2]*SubS->Rinv[b1][b2]; } /* shortcut for one subclass */ if(C->nsubclasses==1) { ll[m] = subll[0]; } /* compute mixture likelihood */ else { /* find the most likely subclass */ for(k=0; k<C->nsubclasses; k++) { if(k==0) maxlike = subll[k]; if(subll[k]>maxlike) maxlike = subll[k]; } /* Sum weighted subclass likelihoods */ subsum = 0; for(k=0; k<C->nsubclasses; k++) subsum += exp( subll[k]-maxlike )*C->SubSig[k].pi; ll[m] = log(subsum) + maxlike; } } free((char *)diff); free((char *)subll);}
void GMM_Subclass_Prob(struct SigSet *S)
{
int i; /* pixel index */
int npixels; /* no. of pixels */
int m; /* class index */
int k; /* subclass index */
int b1,b2; /* spectral index */
int max_nsubclasses; /* maximum number of subclasses */
int nbands; /* number of spectral bands */
double *subll; /* log likelihood of subclasses */
double *diff;
double prob, prob_all;
struct SigSet::ClassSig *C;
struct SigSet::ClassSig::SubSig *SubS;
/* Initialize constants for Log likelihood calculations */
ClassLogLikelihood_init(S);
nbands = S->nbands;
/* determine the maximum number of subclasses */
max_nsubclasses = 0;
for(m=0; m<S->nclasses; m++ )
if(S->ClassSig[m].nsubclasses>max_nsubclasses)
max_nsubclasses = S->ClassSig[m].nsubclasses;
/* allocate memory */
diff = (double *)G_malloc(nbands*sizeof(double));
subll = (double *)G_malloc(max_nsubclasses*sizeof(double));
/* for each class */
for(m=0; m<S->nclasses; m++ )
{
C = &(S->ClassSig[m]);
/* for each pixel */
npixels = C->ClassData.npixels;
for (i=0; i<npixels; i++)
{
/* for each subclass */
prob_all = 0;
for(k=0; k<C->nsubclasses; k++)
{
SubS = &(C->SubSig[k]);
subll[k] = SubS->cnst;
for(b1=0; b1<nbands; b1++)
{
diff[b1] = C->ClassData.x[i][b1] - SubS->means[b1];
subll[k] -= 0.5*diff[b1]*diff[b1]*SubS->Rinv[b1][b1];
}
for(b1=0; b1<nbands; b1++)
for(b2=b1+1; b2<nbands; b2++)
subll[k] -= diff[b1]*diff[b2]*SubS->Rinv[b1][b2];
/* calculate probability belonging to each subclass */
C->ClassData.p[i][k] = SubS->pi * exp(subll[k]);
prob_all += C->ClassData.p[i][k];
} //k
/* probability for each subclass*/
for(k=0; k<C->nsubclasses; k++)
{
C->ClassData.p[i][k] /= prob_all;
}
/* subclass label with maximum likelihood */
prob = C->ClassData.p[i][0];
C->ClassData.ml_label[i] = 0;
for(k=1; k<C->nsubclasses; k++)
{
if(C->ClassData.p[i][k] > prob)
{
prob = C->ClassData.p[i][k];
C->ClassData.ml_label[i] = k;
}
}
}//i
}//m
free((char *)diff);
free((char *)subll);
}void ClassLogLikelihood_init(struct SigSet *S){ int m; int i; int b1,b2; int nbands; double *lambda; struct SigSet::ClassSig *C; struct SigSet::ClassSig::SubSig *SubS; nbands = S->nbands; /* allocate scratch memory */ lambda = (double *)G_malloc(nbands*sizeof(double)); /* invert matrix and compute constant for each subclass */ /* for each class */ for(m=0; m<S->nclasses; m++ ) { C = &(S->ClassSig[m]); /* for each subclass */ for(i=0; i<C->nsubclasses; i++) { SubS = &(C->SubSig[i]); /* Test for symetric matrix */ for(b1=0; b1<nbands; b1++) for(b2=0; b2<nbands; b2++) { if(SubS->R[b1][b2]!=SubS->R[b2][b1]) { fprintf(stderr,"\nWarning: nonsymetric covariance for class %d ",m+1); fprintf(stderr,"Subclass %d\n",i+1); } SubS->Rinv[b1][b2] = SubS->R[b1][b2]; } /* Test for positive definite matrix */ eigen(SubS->Rinv,lambda,nbands); for(b1=0; b1<nbands; b1++) { if(lambda[b1]<=0.0) { fprintf(stderr,"Warning: nonpositive eigenvalues for class %d",m+1); fprintf(stderr,"Subclass %d\n",i+1); } } /* Precomputes the cnst */ SubS->cnst = (-nbands/2.0)*log(2*PI); for(b1=0; b1<nbands; b1++) { SubS->cnst += - 0.5*log(lambda[b1]); } /* Precomputes the inverse of tex->R */ invert(SubS->Rinv,nbands); } } free((char *)lambda);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -