⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 classify_util.cpp

📁 高斯混合模型的C语言实现
💻 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 + -