www.pudn.com > 3AdaBoost.rar > Boosting.cpp, change:2005-02-28,size:28361b


// Boosting.cpp: implementation of the Boosting class. 
// 
////////////////////////////////////////////////////////////////////// 
#include "stdafx.h" 
#include "BoostingLbp.h" 
#include "Boosting.h" 
#include "math.h" 
#include "stdio.h" 
#include "Define.h" 
#include "HarrFeature.h" 
#ifdef _DEBUG 
#undef THIS_FILE 
static char THIS_FILE[]=__FILE__; 
#define new DEBUG_NEW 
#endif 
 
////////////////////////////////////////////////////////////////////// 
// Construction/Destruction 
////////////////////////////////////////////////////////////////////// 
Boosting::Boosting(DWORD posNum, DWORD negNum) 
{ 
        PositiveNum = posNum; 
        NegativeNum = negNum; 
        TotalNegativeNum = negNum; 
        TotalSampleNum = PositiveNum + NegativeNum; 
 
        unsigned char *pFlag = new unsigned char[TOTAL_FEATURE_NUM]; 
        //	FILE *fFlag = fopen(SAVEPATH + "flag", "rb"); 
        //	fread(pFlag, sizeof(unsigned char), TOTAL_FEATURE_NUM, fFlag); 
        //	fclose(fFlag); 
        memset(pFlag, 1, TOTAL_FEATURE_NUM); 
 
        usedFeaCount = 0; 
        for (int c=0; c<TOTAL_FEATURE_NUM; c++) 
        { 
                if (pFlag[c] == 1) usedFeaCount++; 
        } 
        delete []pFlag; 
 
        BinMin = NULL; 
        BinWidth = NULL; 
        FeaValue = NULL; 
        subWinInfo = new FeatureInfo[usedFeaCount]; 
 
        Weight = new double[TotalSampleNum]; 
 
        VotedValue = new double[TotalSampleNum]; 
 
        Label = new unsigned char[TotalSampleNum]; 
 
        memset(Label, 1 , PositiveNum); 
        memset(Label + PositiveNum, 0, NegativeNum); 
} 
 
Boosting::~Boosting() 
{ 
        delete []BinMin; 
        BinMin = NULL; 
        delete []BinWidth; 
        BinWidth = NULL; 
 
        delete []Weight; 
        Weight = NULL; 
 
        delete []VotedValue; 
        VotedValue = NULL; 
 
        delete []Label; 
        Label = NULL; 
 
        if (NULL != FeaValue) 
        { 
                for(int i=0; i<usedFeaCount; i++) 
                {		 
                        if(FeaValue[i] != NULL)  
                        { 
                                delete [] FeaValue[i]; 
                                FeaValue[i] = NULL; 
                        } 
                } 
                FeaValue = NULL; 
        } 
 
        if (subWinInfo != NULL) delete []subWinInfo; 
 
        return; 
} 
 
//Quantize and the LBP bin distance. 
void Boosting::Init(CString szPosName, CString szNegName) 
{ 
        GetAllSubWinInfo(); 
 
        printf("\n"); 
        printf("Total Weak Learner: %d\n", usedFeaCount); 
        printf("Positive Sample Number: %d\n", PositiveNum); 
        printf("Negative Sample Number: %d\n", NegativeNum); 
        printf("\n"); 
 
        CString szPosPath = szPosName; 
        CString szNegPath = szNegName; 
 
        FILE *PosFile = fopen(szPosPath, "rb"); 
        FILE *NegFile = fopen(szNegPath, "rb"); 
 
        //Quantize the distance to be between 0 and 99. 
        BinMin   = new double[usedFeaCount]; 
        BinWidth = new double[usedFeaCount]; 
 
        FeaValue = new WORD*[usedFeaCount]; 
 
        for (int i=0; i<usedFeaCount; i++) 
        { 
                FeaValue[i] = new WORD[TotalSampleNum]; 
        } 
 
        float *RawValue = new float[TotalSampleNum]; 
 
        for (i=0; i<usedFeaCount; i++) 
        { 
                //read in intra-distance.		 
                fread(RawValue, sizeof(float), PositiveNum, PosFile); 
                //read in extra-distance. 
                fread(RawValue + PositiveNum, sizeof(float), NegativeNum, NegFile); 
 
                Discretization(RawValue, i); 
                printf("feaid = %d\r", i); 
        } 
 
        delete []RawValue; 
        RawValue = NULL; 
 
        fclose(PosFile); 
        fclose(NegFile); 
 
} 
 
//////////////////////////////////////////////////////////////////// 
void Boosting::Discretization(float * RawValue, int FeatureNo) 
{ 
        double MinFeaValue = 999999; 
        double MaxFeaValue = -999999; 
 
        for (int j=0; j<TotalSampleNum; j++) 
        { 
                if (RawValue[j] < MinFeaValue) 
                { 
                        MinFeaValue = RawValue[j]; 
                } 
                if (RawValue[j] > MaxFeaValue) 
                { 
                        MaxFeaValue = RawValue[j]; 
                } 
        }				 
 
        BinWidth[FeatureNo] = (MaxFeaValue - MinFeaValue) / double(BINNUM); 
        BinMin[FeatureNo]   = MinFeaValue; 
 
        for (j=0; j<TotalSampleNum; j++)		 
        { 
                FeaValue [FeatureNo][j] = (RawValue[j] - BinMin[FeatureNo]) 
                        / double(BinWidth[FeatureNo]); 
        } 
} 
 
//////////////////////////////////////////////////////////////////////// 
//Find the best weak classifier. 
void Boosting::UpdateHistClassify(double* MinCriterion, int *SelectedFeaNo,  
                                  int *MinThreshold, int *MinSign) 
{ 
        int    i, j; 
        const int BinNum = BINNUM + 2; 
 
        double *his = new double[BinNum]; 
        double TempCost; 
        int    TempSign; 
 
        *MinCriterion = 9999; 
 
        for (i=0; i<usedFeaCount; i++) 
        { 
                // build the histogram ... 
                memset(his, 0, BinNum * sizeof(double)); 
 
                for (j=0; j<TotalSampleNum; j++) 
                { 
                        //			if (pSampleFlag[j] == 1) 
                        { 
                                his[FeaValue[i][j]] += (Label[j] == 1 ? Weight[j] : -Weight[j]);  
                        } 
                } 
 
                for (j=1; j<BinNum; j++) 
                { 
                        his[j] += his[j-1]; 
                } 
                for (j=0; j<BinNum-1; j++) 
                { 
                        TempCost = his[j] + his[j] - his[BinNum-1]; 
                        TempSign = -1; 
                        TempCost = -TempCost; 
                        TempCost = (1 + TempCost) / 2.0; 
                        if (TempCost > 0.5) 
                        { 
                                TempCost = 1 - TempCost; 
                                TempSign = -TempSign; 
                        } 
                        if (TempCost < *MinCriterion) 
                        { 
                                *MinCriterion = TempCost; 
                                *SelectedFeaNo = i; 
 
                                // the bin with the minimum error 
                                *MinThreshold = j + 1; 
                                *MinSign = TempSign; 
                        } 
                } 
        } 
 
        delete []his; 
        his = NULL; 
} 
 
/////////////////////////////////////////////////////////////////////// 
inline int Boosting::GetFeatureValue(int DataNo, int FeaNo) 
{ 
        return (FeaValue[FeaNo][DataNo]); 
} 
 
/////////////////////////////////////////////////////////////////////// 
int Boosting::SimpleDiscretClassify(int DataNo, int iteration) 
{ 
        /*	double  rawFeature; 
        rawFeature = GetRawFeaValue( SelectedFea[iteration],  
        GetFeatureValue(DataNo, SelectedFea[iteration]) ); 
        double  rawThreshold; 
        rawThreshold = GetRawFeaValue( SelectedFea[iteration],  
        DiscretThreshold[iteration] ); 
        */ 
        int value = ( GetFeatureValue(DataNo, SelectedFea[iteration]) - 
                DiscretThreshold[iteration] )  
                * Sign[iteration]; 
 
        if (value > 0)  
                return 1; 
        else  
                return 0; 
} 
 
///////////////////////////////////////////////////////////////////// 
int Boosting::StrongDiscretClassify (int DataNo, double tempThreshold) 
{ 
        double s = 0; 
 
        for (int i=0; i<WeakLearnerNum; i++) 
        { 
                s += apha[i] * ( SimpleDiscretClassify(DataNo,i)==1 ); 
        } 
 
        return (s >= tempThreshold ? 1 : 0); 
} 
 
///////////////////////////////////////////////////////////////////////////////////// 
void Boosting::CheckAccuracy(double *Accuracy, double *FalseAlarm, double tempThreshold) 
{ 
        int CorrectPositiveNum = 0; 
        int CorrectNegativeNum = 0; 
 
        for (int i=0; i<TotalSampleNum; i++) 
        { 
                if ( (StrongDiscretClassify(i,tempThreshold) == Label[i]) ) 
                { 
                        CorrectPositiveNum += (Label[i]==1); 
                        CorrectNegativeNum += (Label[i]==0); 
                }	 
        } 
        *Accuracy = double(CorrectPositiveNum) / double(PositiveNum); 
        *FalseAlarm = 1 - double(CorrectNegativeNum) / double(NegativeNum); 
 
} 
 
//////////////////////////////////////////////////////////////////////////// 
void Boosting::CheckAccuracyWithVotedValue(double *Accuracy, double tempThreshold) 
{ 
        int CorrectPositiveNum = 0; 
 
        for (int i=0; i<TotalSampleNum; i++) 
        { 
                //		if (pSampleFlag[i] == 0) continue; 
                if ( (Label[i] == 1) && (VotedValue[i] >= tempThreshold) ) 
                { 
                        CorrectPositiveNum += 1;			 
                } 
        } 
        *Accuracy = double(CorrectPositiveNum) / double(PositiveNum);	 
} 
 
////////////////////////////////////////////////////////////////////////////// 
void Boosting::CheckFalseAlarmWithVotedValue(double *FalseAlarm, double tempThreshold) 
{ 
        int CorrectNegativeNum = 0; 
 
        for (int i=0; i<TotalSampleNum; i++) 
        { 
                //		if (pSampleFlag[i] == 0) continue; 
                if ( (Label[i] == 0) && (VotedValue[i] < tempThreshold) ) 
                { 
                        CorrectNegativeNum += 1; 
                } 
        } 
        *FalseAlarm = 1 - double(CorrectNegativeNum) / double(curNegNum); 
} 
 
/////////////////////////////////////////////////////////////////////////////// 
void Boosting::AdjustThrehold(double AccuracyWanted, double FalseAlarmWanted, 
                              double *PresentAccuracy0, double *PresentFalseAlarm0, 
                              double *PresentAccuracy, double *PresentFalseAlarm, 
                              double *ThresholdWanted) 
{ 
        const int MaxCount = 200; 
        double MaxErrorRate = 0 / double(PositiveNum); 
        double threshold; 
        double threshold2 = FinalThreshold * 5; 
        double threshold1 = 0; 
        int count; 
 
        CheckAccuracyWithVotedValue(PresentAccuracy0, FinalThreshold); 
        CheckFalseAlarmWithVotedValue(PresentFalseAlarm0, FinalThreshold); 
        printf("Detection Rate = %lf    False Alarm Rate = %lf\n",*PresentAccuracy0,*PresentFalseAlarm0);		 
 
        *PresentAccuracy = 0; 
        *PresentFalseAlarm = 1.0; 
        *ThresholdWanted = FinalThreshold; 
        count = 0; 
 
        while ( ( (*PresentAccuracy < AccuracyWanted) 
                || (*PresentFalseAlarm - 0.0000001 > FalseAlarmWanted) 
                ) && (count <= MaxCount) ) 
        { 
                count++; 
 
                threshold = (threshold1 + threshold2) / 2.0; 
 
                CheckAccuracyWithVotedValue(PresentAccuracy, threshold); 
                CheckFalseAlarmWithVotedValue(PresentFalseAlarm, threshold); 
 
                if (*PresentAccuracy >= AccuracyWanted) 
                { 
                        *ThresholdWanted = threshold; 
                        threshold1 = threshold;	 
                } 
                else 
                { 
                        threshold2 = threshold; 
                } 
        } 
 
        CheckAccuracyWithVotedValue(PresentAccuracy, *ThresholdWanted); 
        CheckFalseAlarmWithVotedValue(PresentFalseAlarm, *ThresholdWanted); 
} 
 
/*******************************************************\ 
Function description: 
Framework to do Adaboost 
 
History: 
 
\*******************************************************/ 
void Boosting::AdaBoost(int stage) 
{ 
        static double TargetFalseAlarm[10] = {0.00000030, 0.45, 0.60, 0.70, 0.80, 
                0.85, 0.85, 0.90, 0.90, 0.95}; 
        double AccuracyWanted = 0.9987; 
        double FalseAlarmWanted = 0; 
        int	   i; 
 
        int	   tempResult; 
        double s, beta; 
        double PresentAccuracy0,  PresentFalseAlarm0, 
                PresentAccuracy = 0, PresentFalseAlarm = 1, 
                PresentThreshold; 
        double FA = 1.0; 
 
        for (i=0; i<PositiveNum; i++) 
        { 
                //		if (pSampleFlag[i] == 1) 
                //		if (PositiveNum - i < 1900) 
                //			Weight[i] = 0.5 / double(PositiveNum) * 0.7; 
                //		else 
                Weight[i] = 0.5 / double(PositiveNum); 
        } 
        for (i=PositiveNum; i<TotalSampleNum; i++) 
        { 
                //		if (pSampleFlag[i] == 1) 
                Weight[i] = 0.5 / double(curNegNum); 
        } 
 
        memset(VotedValue, 0, TotalSampleNum * sizeof(double)); 
 
        int    iteration = 0; 
        FinalThreshold = 0; 
        printf("================= stage%d ==================\n", stage); 
        while (   iteration<MaxIteration  
                && (PresentFalseAlarm>TargetFalseAlarm[stage-1]  
                || PresentAccuracy<AccuracyWanted)  ) 
                { 
                        s = 0; 
                        for (i=0; i<TotalSampleNum; i++) 
                        { 
                                //			if (pSampleFlag[i] == 1) 
                                s += Weight[i]; 
                        } 
                        if (s == 0) s = 1; 
                        for (i=0; i<TotalSampleNum; i++) 
                        { 
                                //			if (pSampleFlag[i] == 1) 
                                Weight[i] /= s; 
                        } 
 
                        //=============Select the most discriminate feature=============// 
                        double MinCriterion; 
                        UpdateHistClassify(&MinCriterion, &SelectedFea[iteration],  
                                &DiscretThreshold[iteration], &Sign[iteration]); 
 
                        //================print to screen====================// 
                        printf("stage%-2d:Iteration=%d   Feature=%d  NegNum = %d  ", 
                                stage, iteration, SelectedFea[iteration], curNegNum); 
 
                        //=======Get "alpha" and "error rate"========// 
                        beta = MinCriterion / (1 - MinCriterion); 
                        apha[iteration] = log( (1 - MinCriterion) / MinCriterion ); 
                        m_m_Error[iteration] = MinCriterion; 
 
                        //==========re-weight===========// 
                        for (i=0; i<TotalSampleNum; i++) 
                        { 
                                //			if (pSampleFlag[i] == 0) continue; 
                                tempResult = SimpleDiscretClassify(i, iteration); 
 
                                if (tempResult == 1) 
                                { 
                                        VotedValue[i] += apha[iteration]; 
                                } 
 
                                if (tempResult == Label[i]) 
                                { 
                                        Weight[i] *= beta; 
                                } 
 
                        } 
 
                        printf("Weighted Error= %lf\n", MinCriterion); 
                        FinalThreshold += apha[iteration] / 2.0; 
                        double tempThreshold = FinalThreshold; 
                        WeakLearnerNum = iteration; 
 
                        AdjustThrehold(AccuracyWanted, FalseAlarmWanted, 
                                &PresentAccuracy0, &PresentFalseAlarm0, 
                                &PresentAccuracy, &PresentFalseAlarm, 
                                &PresentThreshold); 
 
                        double testAccuracy, testFalseAlarm; 
                        CheckAccuracy(&testAccuracy, &testFalseAlarm, PresentThreshold); 
                        FinalThreshold = PresentThreshold; 
 
                        printf("Detection Rate = %lf    False Alarm Rate = %lf  Total FA= %.8f\n", 
                                PresentAccuracy, PresentFalseAlarm, FA); 
 
                        WriteIterationResult(iteration, MinCriterion, 
                                PresentAccuracy0, PresentFalseAlarm0, 
                                PresentAccuracy, PresentFalseAlarm, stage); 
 
                        WriteModelResult("mResultFile", iteration, PresentAccuracy, stage, iteration); 
 
                        printf("finalthreshold=%lf   FinalThreshold = %lf\n", tempThreshold, FinalThreshold); 
                        printf("----------------------------------------------\n", stage); 
 
                        iteration++; 
                } 
                //	markSampleFlag(FinalThreshold, pSampleFlag); 
 
} 
 
///////////////////////////////////////////////////////////////////////////////////////////////// 
void Boosting::WriteIterationResult(int i,double WeightedError, 
                                    double Recall1, double FalseAlarm1, 
                                    double Recall2, double FalseAlarm2, int stage) 
{ 
 
        CString filename = SAVEPATH + "Temp.txt"; 
        FILE *stream = fopen(filename, "at");		 
        fprintf(stream,"stage=%d T=%3d Fea=%5d Error=%.2f  Re=%.4f FA=%.4f      Re=%.4f Fa=%.8f NegNum=%d\n", 
                stage, i, SelectedFea[i], WeightedError, Recall1, FalseAlarm1,  
                Recall2, FalseAlarm2, curNegNum); 
        fclose(stream); 
} 
 
 
/////////////////////////////////////////////////////////////////////////////////////////////////// 
void Boosting::WriteModelResult(CString ResultFile, int nId, double recall, int stage, int newstage) 
{ 
        CString filename; 
        FILE *stream;		 
        filename.Format("%sModel.txt", SAVEPATH); 
        stream = fopen(filename, "at"); 
 
        int index = SelectedFea[nId]; 
 
        fprintf(stream,"%d %d %d %d %d %d %lf %lf %lf %lf\n", 
                subWinInfo[index].type, 
                subWinInfo[index].size.x, subWinInfo[index].size.y, 
                subWinInfo[index].pos.x, subWinInfo[index].pos.y, 
                Sign[nId], 
                GetRawFeaValue(index, DiscretThreshold[nId]), 
                apha[nId], FinalThreshold, recall); 
 
        fclose(stream); 
} 
 
//////////////////////////////////////////////////////////////////// 
inline double Boosting::GetRawFeaValue(int FeaNo, int BinNo) 
{ 
        return (BinWidth[FeaNo] * BinNo + BinMin[FeaNo]); 
} 
 
//////////////////////////////////////////////////////////////////// 
void Boosting::GetAllSubWinInfo() 
{ 
        POINT imageSize; 
        POINT FeatureStPos, FeatureScale; 
        int   FeatureType; 
 
        imageSize.x = SRCIMAGEX; 
        imageSize.y = SRCIMAGEY; 
 
        unsigned char *pFlag = new unsigned char[TOTAL_FEATURE_NUM]; 
        //	FILE *fFlag = fopen(SAVEPATH + "flag", "rb"); 
        //	fread(pFlag, sizeof(unsigned char), TOTAL_FEATURE_NUM, fFlag); 
        //	fclose(fFlag); 
        memset(pFlag, 1, TOTAL_FEATURE_NUM); 
 
        long feaCount = 0; 
        long count = -1; 
        FeatureStPos.y = 1; 
        while (FeatureStPos.y < imageSize.y-1)//行扫描 
        { 
                FeatureStPos.x = 1; 
                while (FeatureStPos.x < imageSize.x-1)//列扫描 
                { 
                        //====== 计算A类特征 ====== 
                        FeatureScale.y = 2; 
                        FeatureType = 0; 
                        while (FeatureStPos.y + FeatureScale.y < imageSize.y)//特征y方向放大 
                        { 
                                FeatureScale.x = 2;  
                                while (FeatureStPos.x + 2 * FeatureScale.x < imageSize.x)//特征x方向放大 
                                { 
                                        count++; 
                                        if (pFlag[count] == 1)  
                                        { 
                                                subWinInfo[feaCount].imageSize.x = imageSize.x; 
                                                subWinInfo[feaCount].imageSize.y = imageSize.y; 
                                                subWinInfo[feaCount].pos.x = FeatureStPos.x; 
                                                subWinInfo[feaCount].pos.y = FeatureStPos.y; 
                                                subWinInfo[feaCount].size.x = FeatureScale.x; 
                                                subWinInfo[feaCount].size.y = FeatureScale.y; 
                                                subWinInfo[feaCount].type = FeatureType; 
                                                feaCount++; 
                                        } 
                                        FeatureScale.x += 1; 
                                } 
                                FeatureScale.y += 1; 
                        } 
                        //========= 计算B类特征 ========== 
                        FeatureScale.y = 2; 
                        FeatureType = 1; 
                        while (FeatureStPos.y + 2 * FeatureScale.y < imageSize.y)//特征y方向放大 
                        { 
                                FeatureScale.x = 2; 
                                while (FeatureStPos.x + FeatureScale.x < imageSize.x)//特征x方向放大 
                                { 
                                        count++; 
                                        if (pFlag[count] == 1) 
                                        { 
                                                subWinInfo[feaCount].imageSize.x = imageSize.x; 
                                                subWinInfo[feaCount].imageSize.y = imageSize.y; 
                                                subWinInfo[feaCount].pos.x = FeatureStPos.x; 
                                                subWinInfo[feaCount].pos.y = FeatureStPos.y; 
                                                subWinInfo[feaCount].size.x = FeatureScale.x; 
                                                subWinInfo[feaCount].size.y = FeatureScale.y; 
                                                subWinInfo[feaCount].type = FeatureType; 
                                                feaCount++; 
                                        } 
                                        FeatureScale.x += 1; 
                                } 
                                FeatureScale.y += 1;  
                        } 
                        //========= 计算C类特征 ========== 
                        FeatureScale.y = 2; 
                        FeatureType = 2; 
                        while (FeatureStPos.y + FeatureScale.y < imageSize.y) 
                        { 
                                FeatureScale.x = 2;  
                                while (FeatureStPos.x+3*FeatureScale.x < imageSize.x) 
                                { 
                                        count++; 
                                        if (pFlag[count] == 1) 
                                        { 
                                                subWinInfo[feaCount].imageSize.x = imageSize.x; 
                                                subWinInfo[feaCount].imageSize.y = imageSize.y; 
                                                subWinInfo[feaCount].pos.x = FeatureStPos.x; 
                                                subWinInfo[feaCount].pos.y = FeatureStPos.y; 
                                                subWinInfo[feaCount].size.x = FeatureScale.x; 
                                                subWinInfo[feaCount].size.y = FeatureScale.y; 
                                                subWinInfo[feaCount].type = FeatureType; 
                                                feaCount++; 
                                        } 
                                        FeatureScale.x += 1; 
                                } 
                                FeatureScale.y += 1; 
                        } 
                        //========= 计算D类特征 ========== 
                        FeatureScale.y = 2; 
                        FeatureType = 3; 
                        while (FeatureStPos.y + 2 * FeatureScale.y < imageSize.y) 
                        { 
                                FeatureScale.x = 2; 
                                while (FeatureStPos.x + 2 * FeatureScale.x < imageSize.x) 
                                { 
                                        count++; 
                                        if (pFlag[count] == 1) 
                                        { 
                                                subWinInfo[feaCount].imageSize.x = imageSize.x; 
                                                subWinInfo[feaCount].imageSize.y = imageSize.y; 
                                                subWinInfo[feaCount].pos.x = FeatureStPos.x; 
                                                subWinInfo[feaCount].pos.y = FeatureStPos.y; 
                                                subWinInfo[feaCount].size.x = FeatureScale.x; 
                                                subWinInfo[feaCount].size.y = FeatureScale.y; 
                                                subWinInfo[feaCount].type = FeatureType; 
                                                feaCount++; 
                                        } 
                                        FeatureScale.x += 1; 
                                } 
                                FeatureScale.y += 1; 
                        } 
                        //========= 计算E类特征 ========== 
                        FeatureScale.y = 2; 
                        FeatureType = 4; 
                        while (FeatureStPos.y + 3 * FeatureScale.y < imageSize.y) 
                        { 
                                FeatureScale.x = 2;  
                                while (FeatureStPos.x + FeatureScale.x < imageSize.x) 
                                { 
                                        count++; 
                                        if (pFlag[count] == 1) 
                                        { 
                                                subWinInfo[feaCount].imageSize.x = imageSize.x; 
                                                subWinInfo[feaCount].imageSize.y = imageSize.y; 
                                                subWinInfo[feaCount].pos.x = FeatureStPos.x; 
                                                subWinInfo[feaCount].pos.y = FeatureStPos.y; 
                                                subWinInfo[feaCount].size.x = FeatureScale.x; 
                                                subWinInfo[feaCount].size.y = FeatureScale.y; 
                                                subWinInfo[feaCount].type = FeatureType; 
                                                feaCount++; 
                                        } 
                                        FeatureScale.x += 1; 
                                } 
                                FeatureScale.y += 1; 
                        } 
                        FeatureStPos.x += 1; 
                } 
                FeatureStPos.y += 1; 
        } 
 
        delete []pFlag; 
        return; 
} 
 
 
//////////////////////////////////////////////////////////////////////////// 
void Boosting::markSampleFlag(double Threshold, unsigned char* &pSampleFlag) 
{ 
 
        for (int i=0; i<TotalSampleNum; i++) 
        { 
                if (pSampleFlag[i] == 0 || Label[i] == 1) continue; 
 
                if ( VotedValue[i] < Threshold ) 
                { 
                        curNegNum--; 
                        pSampleFlag[i] = 0; 
                } 
        } 
 
        return; 
} 
 
//////////////////////////////////////////////////////////////////////////// 
void Boosting::TrainCascade() 
{ 
        int stageNum = 1; 
        int stage = 0; 
 
        pSampleFlag = new unsigned char[TotalSampleNum]; 
        memset(pSampleFlag, 1, TotalSampleNum); 
 
        curNegNum = NegativeNum; 
 
        for (int i=0; i<stageNum; i++) 
        { 
                AdaBoost(i+1); 
        } 
 
        delete []pSampleFlag; 
        pSampleFlag = NULL; 
 
        return; 
}