📄 boosting.cpp
字号:
// 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);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -