1777 lines
No EOL
49 KiB
C++
1777 lines
No EOL
49 KiB
C++
#include "memory.h"
|
|
#include "HeadTracker.h"
|
|
#include "Fern.h"
|
|
#include "stdlib.h"
|
|
#include "math.h"
|
|
|
|
extern u32 ConstantRandom();
|
|
extern unsigned short RandBase;
|
|
|
|
u32 LastErrorDetected;
|
|
Ferns FernUsed[8][NUM_OF_FERNS];
|
|
Ferns FernOptimsed[8][NUM_OF_FERNS];
|
|
#define ERROR_T (NUM_OF_FERNS - 4)//(NUM_OF_FERNS>>5))
|
|
|
|
void FERN_InitBase(LearnBase *Ret)
|
|
{
|
|
/* Init ferns */
|
|
Ret->p_FernUsed = Ret->FernUsed[0];
|
|
RandBase = 0;
|
|
for (u32 Counter = 0 ; Counter < NUM_OF_FERNS ; Counter++)
|
|
{
|
|
u32 CounterComp;
|
|
CounterComp = NUM_OF_BINTEST;
|
|
while(CounterComp--)
|
|
{
|
|
s32 X,Y,X2,Y2;
|
|
do{
|
|
X = ConstantRandom()%PatchSize;
|
|
Y = ConstantRandom()%PatchSize;
|
|
} while (((X - (PatchSize>>1))*(X - (PatchSize>>1)) + (Y - (PatchSize>>1)) * (Y - (PatchSize>>1)) > ((PatchSize * PatchSize) >> 2))) ;
|
|
Ret->FernUsed[0][Counter].Compar[CounterComp * 2 + 0] = X + (Y << 8);
|
|
Ret->FernUsed[8][Counter].Compar[CounterComp * 2 + 0] = (PatchSize - X) + (Y << 8);
|
|
X2 = X;
|
|
Y2 = Y;
|
|
do{
|
|
X = ConstantRandom()%PatchSize;
|
|
Y = ConstantRandom()%PatchSize;
|
|
} while (
|
|
((X - (PatchSize>>1))*(X - (PatchSize>>1)) + (Y - (PatchSize>>1)) * (Y - (PatchSize>>1)) > ((PatchSize * PatchSize) >> 2)) &&
|
|
((X - X2)*(X - X2) + (Y - Y2) * (Y - Y2) < (2*2)) &&
|
|
((X - X2)*(X - X2) + (Y - Y2) * (Y - Y2) > (7*7)) //*/
|
|
)//*/
|
|
;
|
|
Ret->FernUsed[0][Counter].Compar[CounterComp * 2 + 1] = X + (Y << 8);
|
|
Ret->FernUsed[8][Counter].Compar[CounterComp * 2 + 1] = (PatchSize - X) + (Y << 8);
|
|
for (u32 RotateCounter = 1; RotateCounter < 4 ; RotateCounter++)
|
|
{
|
|
s32 Swap;
|
|
Swap = Y2;
|
|
Y2 = X2;
|
|
X2 = PatchSize-Swap;
|
|
Ret->FernUsed[RotateCounter][Counter].Compar[CounterComp * 2 + 0] = X2 + (Y2 << 8);
|
|
Swap = Y;
|
|
Y = X;
|
|
X = PatchSize-Swap;
|
|
Ret->FernUsed[RotateCounter][Counter].Compar[CounterComp * 2 + 1] = X + (Y << 8);
|
|
}
|
|
for (u32 RotateCounter = 4; RotateCounter < 8 ; RotateCounter++)
|
|
{
|
|
#define COS_45 0.70710678118654752440084436210485f
|
|
X2 = (Ret->FernUsed[RotateCounter - 4][Counter].Compar[CounterComp * 2 + 0] & 0xff) - (PatchSize>>1);
|
|
Y2 =((Ret->FernUsed[RotateCounter - 4][Counter].Compar[CounterComp * 2 + 0] >> 8) & 0xff) - (PatchSize>>1);
|
|
X = (s32)(0.5f + ((float)X2 * COS_45) + ((float)Y2 * COS_45) + (float)(PatchSize>>1));
|
|
Y = (s32)(0.5f - ((float)X2 * COS_45) + ((float)Y2 * COS_45) + (float)(PatchSize>>1));
|
|
if (X < 0) X = 0;
|
|
if (Y < 0) Y = 0;
|
|
Ret->FernUsed[RotateCounter][Counter].Compar[CounterComp * 2 + 0] = X + (Y << 8);
|
|
X2 = (Ret->FernUsed[RotateCounter - 4][Counter].Compar[CounterComp * 2 + 1] & 0xff) - (PatchSize>>1);
|
|
Y2 =((Ret->FernUsed[RotateCounter - 4][Counter].Compar[CounterComp * 2 + 1] >> 8) & 0xff) - (PatchSize>>1);
|
|
X = (s32)(0.5f + ((float)X2 * COS_45) + ((float)Y2 * COS_45) + (float)(PatchSize>>1));
|
|
Y = (s32)(0.5f - ((float)X2 * COS_45) + ((float)Y2 * COS_45) + (float)(PatchSize>>1));
|
|
if (X < 0) X = 0;
|
|
if (Y < 0) Y = 0;
|
|
Ret->FernUsed[RotateCounter][Counter].Compar[CounterComp * 2 + 1] = X + (Y << 8);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/* ValidateFern : Called after load */
|
|
void ValidateFern(LearnBase *LB)
|
|
{
|
|
FERN_InitBase(LB);
|
|
LB->p_FernUsed = &LB->FernOptimsed[LB->ActiveFern][0];
|
|
LB->Pitch = 7;
|
|
}
|
|
|
|
|
|
u32 FERN_PatchKnowledgeSize(LearnBase*LB)
|
|
{
|
|
return ((LB->PatchNumber) * (1<<NUM_OF_BINTEST) * NUM_OF_FERNS) >> 3;
|
|
}
|
|
|
|
u32 FERN_LOAD(FILE *F,LearnBase**LB)
|
|
{
|
|
u32 LN;
|
|
fread((void*)&LN,1,4,F);
|
|
if (LN == 0xC1DE0001) // Good Version Number
|
|
{
|
|
*LB = (LearnBase*)malloc(sizeof(LearnBase));
|
|
fread((void*)*LB,1,sizeof(LearnBase),F);
|
|
(*LB)->PatchKnowledge = (LEARN_TYPE *)malloc(FERN_PatchKnowledgeSize(*LB));
|
|
fread((void*)(*LB)->PatchKnowledge,1,FERN_PatchKnowledgeSize(*LB),F);
|
|
fread((void*)&LN,1,4,F);
|
|
(*LB)->ActiveFern = 0;
|
|
(*LB)->p_FernUsed = &FernOptimsed[(*LB)->ActiveFern][0];
|
|
(*LB)->Pitch = 7;
|
|
if (LN == 0xC1DE0001) // Good Version Number
|
|
return 1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
void FERN_SAVE(FILE *F,LearnBase*LB)
|
|
{
|
|
u32 LN;
|
|
LN = 0xC1DE0001;
|
|
fwrite((void*)&LN,1,4,F);
|
|
fwrite((void*)LB,1,sizeof(LearnBase),F);
|
|
fwrite((void*)LB->PatchKnowledge,1,FERN_PatchKnowledgeSize(LB),F);
|
|
LN = 0xC1DE0001;
|
|
fwrite((void*)&LN,1,4,F);
|
|
}
|
|
|
|
|
|
u32 FERN_GetPatchBestResponse(LearnBase *LB, u32 *BWIm , u32 Optim )
|
|
{
|
|
u8 Results[MAX_NUM_OF_PATCH+8];
|
|
u32 *FernKnRes;
|
|
u32 FASTER;
|
|
|
|
LEARN_TYPE *FernKnParser;
|
|
Ferns *FernS,*FernL,*FernFaster;
|
|
FernS = LB->p_FernUsed;
|
|
FernKnParser = LB->PatchKnowledge;
|
|
FernL = FernS + NUM_OF_FERNS;
|
|
FernFaster = FernS + 8;
|
|
memset(Results,0,LB->PatchNumber+8);
|
|
FASTER = 0;
|
|
LastErrorDetected = 0;
|
|
while (FernS < FernL)
|
|
{
|
|
s32 *PatchStatB,*PatchStatL,Indx;
|
|
PatchStatB = FernS->Compar;
|
|
PatchStatL = PatchStatB + NUM_OF_BINTEST*2;
|
|
Indx = 0;
|
|
while (PatchStatB < PatchStatL)
|
|
{
|
|
u32 Compare;
|
|
Indx += Indx;
|
|
Compare = *(BWIm + *(PatchStatB++));
|
|
Compare -= *(BWIm + *(PatchStatB++));
|
|
Indx |= Compare>>31;
|
|
}
|
|
|
|
LEARN_TYPE *FernKnS,*FernKnE;
|
|
FernKnS = FernKnParser + ((Indx * LB->PatchNumber)>>5);
|
|
FernKnE = FernKnS + (LB->PatchNumber>>5);
|
|
FernKnRes = (u32*)Results;
|
|
while (FernKnS < FernKnE)
|
|
{
|
|
u32 MASK,*FernKnRes2;
|
|
MASK = *(FernKnS++);
|
|
FernKnRes2 = FernKnRes;
|
|
while (MASK)
|
|
{
|
|
*(FernKnRes2) += MASK & 0x01010101;
|
|
FASTER |= *(FernKnRes2++);
|
|
MASK>>=1;
|
|
MASK &= 0x7f7f7f7f;
|
|
}
|
|
FernKnRes+=8;
|
|
}
|
|
FernKnParser += ((1<<NUM_OF_BINTEST) * LB->PatchNumber)>>5;
|
|
FernS++;
|
|
if (FernS == FernFaster)
|
|
{
|
|
if ((FASTER & 0xfcfcfcfc) == 0)
|
|
return 0xffffffff;
|
|
}
|
|
}
|
|
|
|
u32 MAXV = 0;
|
|
u32 MAXI = 0;
|
|
|
|
for (u32 i = 0; i < LB->PatchNumber ; i++)
|
|
{
|
|
if (Results[i] > MAXV)
|
|
{
|
|
MAXI = i;
|
|
MAXV = Results[i];
|
|
}
|
|
}
|
|
|
|
LastErrorDetected = MAXV;
|
|
MAXI = ((MAXI & 3)<<3) | ((MAXI >>2 )& 7) | (MAXI & ~31);
|
|
return MAXI;
|
|
}
|
|
|
|
|
|
void FERN_SetPatchBestResponse(LearnBase *LB, u32 *BWIm , u32 PatchToSEt)
|
|
{
|
|
LEARN_TYPE *FernKnParser;
|
|
Ferns *FernS,*FernL;
|
|
FernS = LB->p_FernUsed;
|
|
u32 MASK;
|
|
FernKnParser = LB->PatchKnowledge+(PatchToSEt>>5);
|
|
MASK = 1<<(PatchToSEt & 31);
|
|
FernL = FernS + NUM_OF_FERNS;
|
|
while (FernS < FernL)
|
|
{
|
|
s32 *PatchStatB,*PatchStatL,Indx;
|
|
PatchStatB = FernS->Compar;
|
|
PatchStatL = PatchStatB + NUM_OF_BINTEST*2;
|
|
Indx = 0;
|
|
while (PatchStatB < PatchStatL)
|
|
{
|
|
u32 Compare;
|
|
Indx += Indx;
|
|
Compare = *(BWIm + *(PatchStatB++));
|
|
Compare -= *(BWIm + *(PatchStatB++));
|
|
Indx |= Compare>>31;
|
|
}
|
|
|
|
/* Learn Here */
|
|
*(FernKnParser + (Indx * LB->PatchNumber>>5)) |= MASK;
|
|
|
|
FernKnParser += ((1<<NUM_OF_BINTEST) * LB->PatchNumber)>>5;
|
|
FernS++;
|
|
}
|
|
}
|
|
|
|
|
|
void FERN_SetPitch(LearnBase *LB, u32 pitch )
|
|
{
|
|
/* Optimize Here */
|
|
for (u32 Counter3 = 0 ; Counter3 < 8 ; Counter3++)
|
|
{
|
|
for (u32 Counter = 0 ; Counter < NUM_OF_FERNS ; Counter++)
|
|
{
|
|
for (u32 Counter2 = 0 ; Counter2 < NUM_OF_BINTEST*2; Counter2++)
|
|
{
|
|
FernOptimsed[Counter3][Counter].Compar[Counter2] = ((s32)(FernUsed[Counter3][Counter].Compar[Counter2] & 0xff) - (PatchSize >> 1)) + ((s32)((FernUsed[Counter3][Counter].Compar[Counter2]>>8) & 0xff) - (PatchSize>>1)) * pitch;
|
|
}
|
|
}
|
|
}
|
|
LB->p_FernUsed = &FernOptimsed[LB->ActiveFern][0];
|
|
LB->Pitch = pitch;
|
|
}
|
|
|
|
|
|
void FERN_TrainAPatch(LearnBase *LB, u32 *BWIm , u32 pitch , u32 PatchToSEt)
|
|
{
|
|
if (pitch != LB->Pitch)
|
|
{
|
|
FERN_SetPitch(LB, pitch );
|
|
}
|
|
FERN_SetPatchBestResponse(LB, BWIm , PatchToSEt);
|
|
}
|
|
|
|
u32 FERN_MatchPatch2(LearnBase *LB, u32 *BWIm , u32 pitch )
|
|
{
|
|
if (pitch != LB->Pitch)
|
|
{
|
|
FERN_SetPitch(LB, pitch );
|
|
}
|
|
return FERN_GetPatchBestResponse(LB, BWIm );
|
|
}
|
|
|
|
u32 FERN_MatchPatch(LearnBase *LB, u32 *BWIm , u32 pitch )
|
|
{
|
|
u32 GetBob;
|
|
GetBob = FERN_MatchPatch2(LB, BWIm , pitch );
|
|
if (LastErrorDetected > ERROR_T)
|
|
return GetBob;
|
|
else
|
|
return 0xffffffff;
|
|
}
|
|
|
|
void FERN_ClearPatchBase(LearnBase *LB)
|
|
{
|
|
memset(LB->PatchKnowledge,0,FERN_PatchKnowledgeSize(LB));
|
|
LB->p_FernUsed = FernUsed[0];
|
|
LB->ActiveFern = 0;
|
|
}
|
|
|
|
void FERN_ClearAClass(LearnBase *LB,u32 ClassNum)
|
|
{
|
|
u32 Counter,*pBase,MASK;
|
|
Counter = NUM_OF_FERNS * (1<<NUM_OF_BINTEST);
|
|
pBase = LB->PatchKnowledge + (ClassNum>>5);
|
|
MASK = 1<<(ClassNum&31);
|
|
MASK ^= 0xffffffff;
|
|
while (Counter--)
|
|
{
|
|
*pBase &= MASK;
|
|
pBase += (LB->PatchNumber>>5);
|
|
}
|
|
}
|
|
|
|
|
|
LearnBase *FERN_CreatePatchBase(u32 ulNumberOfPatch)
|
|
{
|
|
LearnBase *Ret;
|
|
u32 Size;
|
|
static u32 IsInit = 1;
|
|
/* ALIGN NP with 32 */
|
|
ulNumberOfPatch += 31;
|
|
ulNumberOfPatch &= ~31;
|
|
Ret = (LearnBase *)malloc(sizeof(LearnBase));
|
|
memset(Ret,0,sizeof(LearnBase));
|
|
Ret->PatchNumber = ulNumberOfPatch;
|
|
Size = FERN_PatchKnowledgeSize(Ret);
|
|
*(void **)&Ret->PatchKnowledge = malloc(Size);
|
|
memset(Ret->PatchKnowledge,0,Size);
|
|
/* Init ferns */
|
|
Ret->p_FernUsed = FernUsed[0];
|
|
RandBase = 0;
|
|
if (IsInit)
|
|
for (u32 Counter = 0 ; Counter < NUM_OF_FERNS ; Counter++)
|
|
{
|
|
u32 CounterComp;
|
|
CounterComp = NUM_OF_BINTEST;
|
|
while(CounterComp--)
|
|
{
|
|
s32 X,Y,X2,Y2;
|
|
do{
|
|
X = ConstantRandom()%PatchSize;
|
|
Y = ConstantRandom()%PatchSize;
|
|
} while (((X - (PatchSize>>1))*(X - (PatchSize>>1)) + (Y - (PatchSize>>1)) * (Y - (PatchSize>>1)) > ((PatchSize * PatchSize) >> 2))) ;
|
|
FernUsed[0][Counter].Compar[CounterComp * 2 + 0] = X + (Y << 8);
|
|
X2 = X;
|
|
Y2 = Y;
|
|
do{
|
|
X = ConstantRandom()%PatchSize;
|
|
Y = ConstantRandom()%PatchSize;
|
|
} while (
|
|
((X - (PatchSize>>1))*(X - (PatchSize>>1)) + (Y - (PatchSize>>1)) * (Y - (PatchSize>>1)) > ((PatchSize * PatchSize) >> 2)) &&
|
|
((X - X2)*(X - X2) + (Y - Y2) * (Y - Y2) < (2*2)) &&
|
|
((X - X2)*(X - X2) + (Y - Y2) * (Y - Y2) > (7*7)) //*/
|
|
)//*/
|
|
;
|
|
FernUsed[0][Counter].Compar[CounterComp * 2 + 1] = X + (Y << 8);
|
|
for (u32 RotateCounter = 1; RotateCounter < 4 ; RotateCounter++)
|
|
{
|
|
s32 Swap;
|
|
Swap = Y2;
|
|
Y2 = X2;
|
|
X2 = PatchSize-Swap;
|
|
FernUsed[RotateCounter][Counter].Compar[CounterComp * 2 + 0] = X2 + (Y2 << 8);
|
|
Swap = Y;
|
|
Y = X;
|
|
X = PatchSize-Swap;
|
|
FernUsed[RotateCounter][Counter].Compar[CounterComp * 2 + 1] = X + (Y << 8);
|
|
}
|
|
for (u32 RotateCounter = 4; RotateCounter < 8 ; RotateCounter++)
|
|
{
|
|
#define COS_45 0.70710678118654752440084436210485f
|
|
X2 = (FernUsed[RotateCounter - 4][Counter].Compar[CounterComp * 2 + 0] & 0xff) - (PatchSize>>1);
|
|
Y2 =((FernUsed[RotateCounter - 4][Counter].Compar[CounterComp * 2 + 0] >> 8) & 0xff) - (PatchSize>>1);
|
|
X = (s32)(0.5f + ((float)X2 * COS_45) + ((float)Y2 * COS_45) + (float)(PatchSize>>1));
|
|
Y = (s32)(0.5f - ((float)X2 * COS_45) + ((float)Y2 * COS_45) + (float)(PatchSize>>1));
|
|
if (X < 0) X = 0;
|
|
if (Y < 0) Y = 0;
|
|
FernUsed[RotateCounter][Counter].Compar[CounterComp * 2 + 0] = X + (Y << 8);
|
|
X2 = (FernUsed[RotateCounter - 4][Counter].Compar[CounterComp * 2 + 1] & 0xff) - (PatchSize>>1);
|
|
Y2 =((FernUsed[RotateCounter - 4][Counter].Compar[CounterComp * 2 + 1] >> 8) & 0xff) - (PatchSize>>1);
|
|
X = (s32)(0.5f + ((float)X2 * COS_45) + ((float)Y2 * COS_45) + (float)(PatchSize>>1));
|
|
Y = (s32)(0.5f - ((float)X2 * COS_45) + ((float)Y2 * COS_45) + (float)(PatchSize>>1));
|
|
if (X < 0) X = 0;
|
|
if (Y < 0) Y = 0;
|
|
FernUsed[RotateCounter][Counter].Compar[CounterComp * 2 + 1] = X + (Y << 8);
|
|
}
|
|
}
|
|
}
|
|
IsInit = 0;
|
|
return Ret;
|
|
}
|
|
|
|
u32 FERN_GetClassNumber(LearnBase *LB)
|
|
{
|
|
return LB->PatchNumber;
|
|
}
|
|
|
|
|
|
/*********************************************************************************************************************/
|
|
/*********************************************************************************************************************/
|
|
/* FULL TRAINING *****************************************************************************************************/
|
|
/*********************************************************************************************************************/
|
|
/*********************************************************************************************************************/
|
|
|
|
static void COPY_PATCH_ScaleRotation(MAP *MapSRC,MAP *MapDST,s32 SX,s32 SY,s32 DX,s32 DY,u32 DSizeX,u32 DSizeY,u32 SizeX,u32 SizeY,float Rot128,float SCLAEV)
|
|
{
|
|
s32 *LAST,*DST,*DST2,*SRC,*BIGLAST;
|
|
s32 SYS,SYS2,SXS2,SXS3,SXI3,SYS3,SYI3,SXI,SYI,SYI2,SXI2;
|
|
s32 ScaleROTTable[1024],*p_ScaleROTTable;
|
|
s32 ScaleROTTableLenght[1024],*p_ScaleROTTableLenght;
|
|
float CosA,SinA;
|
|
|
|
CosA = cosf(Rot128);
|
|
SinA = sinf(Rot128);
|
|
|
|
//AAAA+= 1<<13;
|
|
SX -= (int)((CosA * (DSizeX>>1)) - (SinA * (DSizeY>>1))) ;
|
|
SY -= (int)((SinA * (DSizeX>>1)) + (CosA * (DSizeY>>1))) ;
|
|
SX <<= 8;
|
|
SY <<= 8;
|
|
|
|
SYS = 0;
|
|
SXI = (int)(65536.0f * ((float)DSizeX / (float)SizeX ));
|
|
SYI = (int)(65536.0f * ((float)DSizeY / (float)SizeY ));
|
|
|
|
/* Compute Scale X */
|
|
SXI3 = -(int)((float)SXI * SinA * SCLAEV);
|
|
SYI3 = (int)((float)SXI * CosA * SCLAEV);
|
|
SXS3 = SX;
|
|
SYS3 = SY;
|
|
|
|
/* Compute raster X */
|
|
|
|
SXI2 = (int)((float)SXI * CosA);
|
|
SYI2 = (int)((float)SXI * SinA);
|
|
SXS2 = 0;
|
|
SYS2 = 0;
|
|
|
|
/* Rasterize */
|
|
DX -= SizeX>>1;
|
|
DY -= SizeY>>1;
|
|
DX>>=8;DY>>=8;
|
|
if (DX < 0 ) DX = 0;
|
|
if (DY < 0 ) DY = 0;
|
|
|
|
p_ScaleROTTable = (s32 *)ScaleROTTable;
|
|
p_ScaleROTTableLenght = (s32*)ScaleROTTableLenght;
|
|
DST = MapDST->GetBase() + DY * MapDST->PITCH + DX;
|
|
BIGLAST = MapDST->GetBase() + MapDST->SY * MapDST->PITCH;
|
|
SizeX>>=8;SizeY>>=8;
|
|
while (SizeY--)
|
|
{
|
|
DST2 = DST;
|
|
SRC = MapSRC->GetBase();
|
|
LAST = DST + SizeX;
|
|
SXS2 = SXS3 + SXI2 * SizeX;
|
|
SYS2 = SYS3 + SYI2 * SizeX;
|
|
while (((SXS2>>16 > (s32)MapSRC->SX) || (SXS2>>16 < 0) ||
|
|
(SYS2>>16 > (s32)MapSRC->SY) || (SYS2>>16 < 0)) && (DST < LAST))
|
|
{
|
|
SXS2 -= SXI2;
|
|
SYS2 -= SYI2;
|
|
LAST--;
|
|
}
|
|
SXS2 = SXS3;
|
|
SYS2 = SYS3;
|
|
while (((SXS2>>16 > (s32)MapSRC->SX) || (SXS2>>16 < 0) ||
|
|
(SYS2>>16 > (s32)MapSRC->SY) || (SYS2>>16 < 0)) && (DST < LAST))
|
|
{
|
|
SXS2 += SXI2;
|
|
SYS2 += SYI2;
|
|
DST++;
|
|
}
|
|
|
|
while (DST < LAST)
|
|
{
|
|
//if ((DST > MapDST->GetBase()) && (DST < BIGLAST))
|
|
*(DST) = (*(SRC+(SXS2>>16) + (SYS2>>16)*MapSRC->PITCH)) & 0xfffffffe;
|
|
SXS2 += SXI2;
|
|
SYS2 += SYI2;
|
|
DST++;
|
|
}
|
|
SXS3 += SXI3;
|
|
SYS3 += SYI3;
|
|
DST = DST2 + MapDST->PITCH;
|
|
}
|
|
}
|
|
|
|
u32 SamplerMap_PIXELS[128 * 128];
|
|
MAP SamplerMap;
|
|
void FERN_SignalFail(struct LearnBase_ *LB)
|
|
{
|
|
//return;
|
|
/* Change BittestBase */
|
|
LB->ActiveFern ++;
|
|
LB->ActiveFern &= 0x7;
|
|
LB->p_FernUsed = &FernOptimsed[LB->ActiveFern][0];
|
|
}
|
|
|
|
void FERN_TrainAPatchOnFly(LearnBase *LB, u32 *BWIm , u32 pitch , u32 PatchToSEt , u32 StatisticalMode)
|
|
{
|
|
FERN_TrainAPatch(LB, BWIm, pitch, PatchToSEt);
|
|
}
|
|
|
|
void FERN_TrainAPatchComplete(LearnBase *LB, u32 *BWIm , u32 pitch , u32 PatchToSEt )
|
|
{
|
|
MAP SamplerMap2;
|
|
SamplerMap.SetBase((s32*)SamplerMap_PIXELS);
|
|
SamplerMap.SX = 64;
|
|
SamplerMap.SY = 64;
|
|
SamplerMap.PITCH = 64;
|
|
|
|
SamplerMap2.SetBase((s32*)(BWIm - 32 * pitch - 32));
|
|
SamplerMap2.SX = 64;
|
|
SamplerMap2.SY = 64;
|
|
SamplerMap2.PITCH = pitch;
|
|
|
|
FERN_ClearAClass(LB,PatchToSEt);
|
|
FERN_TrainAPatch(LB, BWIm, pitch, PatchToSEt);
|
|
FERN_TrainAPatch(LB, BWIm + 1, pitch, PatchToSEt);
|
|
FERN_TrainAPatch(LB, BWIm - 1, pitch, PatchToSEt);
|
|
FERN_TrainAPatch(LB, BWIm + pitch, pitch, PatchToSEt);
|
|
FERN_TrainAPatch(LB, BWIm - pitch, pitch, PatchToSEt);
|
|
|
|
u32 Trainer;
|
|
Trainer = 64;
|
|
while (Trainer--)
|
|
{
|
|
float ScaleNoise;
|
|
float AngleNoise;
|
|
ScaleNoise = (1.0f + 0.05f * ((float)(rand()&255) / 128.0f - 1.0f));
|
|
AngleNoise = 0.05f * ((float)(rand()&255) / 128.0f - 1.0f);
|
|
COPY_PATCH_ScaleRotation(&SamplerMap2,&SamplerMap,
|
|
SamplerMap2.SX<<7,
|
|
SamplerMap2.SY<<7,
|
|
SamplerMap.SX<<7,
|
|
SamplerMap.SY<<7,
|
|
(u32)(ScaleNoise * (float)(3*PatchSize))<<8,
|
|
(u32)(ScaleNoise * (float)(3*PatchSize))<<8,
|
|
(3*PatchSize)<<8,
|
|
(3*PatchSize)<<8,
|
|
AngleNoise,
|
|
1.0f);
|
|
//ADD_NOISE(&SamplerMap);
|
|
FERN_TrainAPatch(
|
|
LB,
|
|
(u32 *)(SamplerMap.GetBase() + (SamplerMap.SX>>1) + (SamplerMap.SY>>1) * SamplerMap.PITCH + ((rand()%3) - 1) + ((rand()%3) - 1) * SamplerMap.PITCH ),
|
|
SamplerMap.PITCH ,
|
|
PatchToSEt);
|
|
}
|
|
}
|
|
#if 0
|
|
#include "TRACK.h"
|
|
#include "Rrasters.h"
|
|
extern u32 ConstantRandom();
|
|
extern unsigned short RandBase;
|
|
#define ERROR_T (NUM_OF_FERNS - 4)//(NUM_OF_FERNS>>5))
|
|
u32 FERN_FastDetect(LearnBase *LB,u8 *Vector);
|
|
u32 FERN_MatchPatch_Error(LearnBase *LB, u32 *BWIm , u32 pitch , u32 Error);
|
|
|
|
/* PatchKnowledgeSize : compute the size */
|
|
u32 FERN_PatchKnowledgeSize(LearnBase*LB)
|
|
{
|
|
return ((LB->PatchNumber) * (1<<NUM_OF_BINTEST) * NUM_OF_FERNS) >> 3;
|
|
}
|
|
|
|
/* ValidateFern : Called after load */
|
|
void ValidateFern(LearnBase *LB)
|
|
{
|
|
FERN_InitBase(LB);
|
|
LB->p_FernUsed = &LB->FernOptimsed[LB->ActiveFern][0];
|
|
LB->Pitch = 7;
|
|
}
|
|
|
|
|
|
u32 FERN_GetPatchBestResponse_GI(LearnBase *LB, u32 *BWIm , u32 LearnMode , u8 *PrecomputeFlags)
|
|
{
|
|
u8 Results[MAX_NUM_OF_PATCH+8];
|
|
u32 *FernKnRes;
|
|
u32 FASTER;
|
|
|
|
START_RASTER(FRN);
|
|
|
|
LEARN_TYPE *FernKnParser;
|
|
Ferns *FernS,*FernL,*FernFaster;
|
|
FernS = LB->p_FernUsed;
|
|
FernKnParser = LB->PatchKnowledge;
|
|
FernL = FernS + NUM_OF_FERNS;
|
|
FernFaster = FernS + 8;
|
|
memset(Results,0,LB->PatchNumber+8);
|
|
if (LearnMode) LearnMode = 0xffffffff;
|
|
FASTER = LearnMode;
|
|
LB->LastErrorDetected = 0;
|
|
while (FernS < FernL)
|
|
{
|
|
s32 Indx;
|
|
if (PrecomputeFlags)
|
|
{
|
|
s32 *PatchStatB,*PatchStatL;
|
|
PatchStatB = FernS->Compar;
|
|
Indx = *(PrecomputeFlags++);
|
|
}
|
|
else
|
|
{
|
|
s32 *PatchStatB,*PatchStatL;
|
|
PatchStatB = FernS->Compar;
|
|
PatchStatL = PatchStatB + NUM_OF_BINTEST*2;
|
|
Indx = 0;
|
|
while (PatchStatB < PatchStatL)
|
|
{
|
|
u32 Compare;
|
|
Indx += Indx;
|
|
Compare = *(BWIm + *(PatchStatB++));
|
|
Compare -= *(BWIm + *(PatchStatB++));
|
|
Indx |= Compare>>31;
|
|
}
|
|
}
|
|
|
|
LEARN_TYPE *FernKnS,*FernKnE;
|
|
FernKnS = FernKnParser + ((Indx * LB->PatchNumber)>>5);
|
|
FernKnE = FernKnS + (LB->PatchNumber>>5);
|
|
FernKnRes = (u32*)Results;
|
|
while (FernKnS < FernKnE)
|
|
{
|
|
u32 MASK,*FernKnRes2;
|
|
MASK = *(FernKnS++);
|
|
FernKnRes2 = FernKnRes;
|
|
while (MASK)
|
|
{
|
|
*(FernKnRes2) += MASK & 0x01010101;
|
|
FASTER |= *(FernKnRes2++);
|
|
MASK>>=1;
|
|
MASK &= 0x7f7f7f7f;
|
|
}
|
|
FernKnRes+=8;
|
|
}
|
|
FernKnParser += ((1<<NUM_OF_BINTEST) * LB->PatchNumber)>>5;
|
|
FernS++;
|
|
if (FernS == FernFaster)
|
|
{
|
|
if ((FASTER & 0xfcfcfcfc) == 0)
|
|
{
|
|
STOP_RASTER(FRN);
|
|
return 0xffffffff;
|
|
}
|
|
}
|
|
}
|
|
|
|
u32 MAXV = 0;
|
|
u32 MAXI = 0;
|
|
|
|
u32 LEARN_MAXV = 1000000000;
|
|
u32 LEARN_MAXI = 0;
|
|
|
|
LB->LastErrorDetected = MAXV;
|
|
LB->LastNumberOfValids = 0;
|
|
|
|
for (u32 i = 0; i < LB->PatchNumber ; i++)
|
|
{
|
|
if (Results[i] > MAXV)
|
|
{
|
|
MAXI = i;
|
|
MAXV = Results[i];
|
|
LB->LastNumberOfValids = 0;
|
|
} else
|
|
if (Results[i] == MAXV)
|
|
{
|
|
LB->LastNumberOfValids++;
|
|
}
|
|
/* if (LearnMode)
|
|
{
|
|
u32 ReinDex;
|
|
ReinDex = ((i & 3)<<3) | ((i >>2 )& 7) | (i & ~31);
|
|
if ((NUM_OF_FERNS - Results[i])*LB->LearnCounter[ReinDex] <= LEARN_MAXV)
|
|
{
|
|
LEARN_MAXI = i;
|
|
LEARN_MAXV = (NUM_OF_FERNS - Results[i])*LB->LearnCounter[ReinDex];
|
|
}
|
|
}*/
|
|
|
|
}
|
|
|
|
LB->LastErrorDetected = MAXV;
|
|
/*if (LearnMode)
|
|
{
|
|
MAXI = LEARN_MAXI;
|
|
LB->LastErrorDetected = LEARN_MAXV;
|
|
} */
|
|
MAXI = ((MAXI & 3)<<3) | ((MAXI >>2 )& 7) | (MAXI & ~31);
|
|
STOP_RASTER(FRN);
|
|
|
|
return MAXI;
|
|
}
|
|
|
|
|
|
void FERN_SetPatchBestResponse_GI(LearnBase *LB, u32 *BWIm , u32 PatchToSEt , u8 *PrecomputeFlags)
|
|
{
|
|
LEARN_TYPE *FernKnParser;
|
|
Ferns *FernS,*FernL;
|
|
FernS = LB->p_FernUsed;
|
|
u32 MASK;
|
|
START_RASTER(FRN);
|
|
LB->LearnCounter[PatchToSEt] ++;
|
|
FernKnParser = LB->PatchKnowledge+(PatchToSEt>>5);
|
|
MASK = 1<<(PatchToSEt & 31);
|
|
FernL = FernS + NUM_OF_FERNS;
|
|
while (FernS < FernL)
|
|
{
|
|
s32 Indx;
|
|
if (PrecomputeFlags)
|
|
{
|
|
s32 *PatchStatB,*PatchStatL;
|
|
PatchStatB = FernS->Compar;
|
|
Indx = *(PrecomputeFlags++);
|
|
} else
|
|
{
|
|
s32 *PatchStatB,*PatchStatL;
|
|
PatchStatB = FernS->Compar;
|
|
PatchStatL = PatchStatB + NUM_OF_BINTEST*2;
|
|
Indx = 0;
|
|
while (PatchStatB < PatchStatL)
|
|
{
|
|
u32 Compare;
|
|
Indx += Indx;
|
|
Compare = *(BWIm + *(PatchStatB++));
|
|
Compare -= *(BWIm + *(PatchStatB++));
|
|
Indx |= Compare>>31;
|
|
}
|
|
}
|
|
|
|
/* Learn Here */
|
|
*(FernKnParser + (Indx * LB->PatchNumber>>5)) |= MASK;
|
|
|
|
FernKnParser += ((1<<NUM_OF_BINTEST) * LB->PatchNumber)>>5;
|
|
FernS++;
|
|
}
|
|
STOP_RASTER(FRN);
|
|
}
|
|
u32 FERN_GetPatchBestResponse(LearnBase *LB, u32 *BWIm , u32 Optim)
|
|
{
|
|
return FERN_GetPatchBestResponse_GI(LB, BWIm , Optim , 0);
|
|
}
|
|
void FERN_SetPatchBestResponse(LearnBase *LB, u32 *BWIm , u32 PatchToSEt)
|
|
{
|
|
FERN_SetPatchBestResponse_GI(LB, BWIm , PatchToSEt , 0);
|
|
}
|
|
|
|
|
|
|
|
void FERN_SetPitch(LearnBase *LB, u32 pitch )
|
|
{
|
|
/* Optimize Here */
|
|
START_RASTER(FRN);
|
|
for (u32 Counter3 = 0 ; Counter3 < 9 ; Counter3++)
|
|
{
|
|
for (u32 Counter = 0 ; Counter < NUM_OF_FERNS ; Counter++)
|
|
{
|
|
for (u32 Counter2 = 0 ; Counter2 < NUM_OF_BINTEST*2; Counter2++)
|
|
{
|
|
LB->FernOptimsed[Counter3][Counter].Compar[Counter2] = ((s32)(LB->FernUsed[Counter3][Counter].Compar[Counter2] & 0xff) - (PatchSize >> 1)) + ((s32)((LB->FernUsed[Counter3][Counter].Compar[Counter2]>>8) & 0xff) - (PatchSize>>1)) * pitch;
|
|
}
|
|
}
|
|
}
|
|
LB->p_FernUsed = &LB->FernOptimsed[LB->ActiveFern][0];
|
|
LB->Pitch = pitch;
|
|
STOP_RASTER(FRN);
|
|
}
|
|
|
|
|
|
void FERN_TrainAPatch(LearnBase *LB, u32 *BWIm , u32 pitch , u32 PatchToSEt)
|
|
{
|
|
START_RASTER(FRN);
|
|
if (pitch != LB->Pitch)
|
|
{
|
|
FERN_SetPitch(LB, pitch );
|
|
}
|
|
FERN_SetPatchBestResponse(LB, BWIm , PatchToSEt);
|
|
STOP_RASTER(FRN);
|
|
}
|
|
|
|
u32 FERN_MatchPatch2(LearnBase *LB, u32 *BWIm , u32 pitch )
|
|
{
|
|
if (pitch != LB->Pitch)
|
|
{
|
|
FERN_SetPitch(LB, pitch );
|
|
}
|
|
return FERN_GetPatchBestResponse(LB, BWIm );
|
|
}
|
|
|
|
u32 FERN_MatchPatch(LearnBase *LB, u32 *BWIm , u32 pitch )
|
|
{
|
|
u32 GetBob;
|
|
if (pitch != LB->Pitch) FERN_SetPitch(LB, pitch );
|
|
GetBob = FERN_GetPatchBestResponse_GI(LB, BWIm , 0,0);
|
|
if (LB->LastErrorDetected > ERROR_T)
|
|
return GetBob;
|
|
else
|
|
return 0xffffffff;
|
|
}
|
|
|
|
void FERN_ClearPatchBase(LearnBase *LB)
|
|
{
|
|
memset(LB->PatchKnowledge,0,FERN_PatchKnowledgeSize(LB));
|
|
LB->p_FernUsed = LB->FernUsed[0];
|
|
LB->ActiveFern = 0;
|
|
}
|
|
|
|
void FERN_ClearAClass(LearnBase *LB,u32 ClassNum)
|
|
{
|
|
u32 Counter,*pBase,MASK;
|
|
Counter = NUM_OF_FERNS * (1<<NUM_OF_BINTEST);
|
|
LB->LearnCounter[ClassNum] = 0;
|
|
pBase = LB->PatchKnowledge + (ClassNum>>5);
|
|
MASK = 1<<(ClassNum&31);
|
|
MASK ^= 0xffffffff;
|
|
while (Counter--)
|
|
{
|
|
*pBase &= MASK;
|
|
pBase += (LB->PatchNumber>>5);
|
|
}
|
|
}
|
|
|
|
u32 FERN_GetFullData(LearnBase *LB,u32 *Mask,u32 ClassNum)
|
|
{
|
|
u32 Counter,*pBase,MASK;
|
|
Counter = NUM_OF_FERNS * (1<<NUM_OF_BINTEST);
|
|
pBase = LB->PatchKnowledge + (ClassNum>>5);
|
|
MASK = 1<<(ClassNum&31);
|
|
u32 Bitnum = 0;
|
|
while (Counter--)
|
|
{
|
|
if (*pBase & MASK)
|
|
{
|
|
Mask[(Counter>>5)] |= 1<<(Counter&31);
|
|
Bitnum++;
|
|
}
|
|
else
|
|
Mask[(Counter>>5)] &= ~(1<<(Counter&31));
|
|
pBase += (LB->PatchNumber>>5);
|
|
}
|
|
return Bitnum;
|
|
}
|
|
void FERN_SetFullData(LearnBase *LB,u32 *Mask,u32 ClassNum)
|
|
{
|
|
u32 Counter,*pBase,MASK;
|
|
Counter = NUM_OF_FERNS * (1<<NUM_OF_BINTEST);
|
|
pBase = LB->PatchKnowledge + (ClassNum>>5);
|
|
MASK = 1<<(ClassNum&31);
|
|
while (Counter--)
|
|
{
|
|
if (Mask[(Counter>>5)] & (1<<(Counter&31)))
|
|
*pBase |= MASK;
|
|
else
|
|
*pBase &= ~MASK;
|
|
pBase += (LB->PatchNumber>>5);
|
|
}
|
|
}
|
|
|
|
void FERN_InitBase(LearnBase *Ret)
|
|
{
|
|
/* Init ferns */
|
|
Ret->p_FernUsed = Ret->FernUsed[0];
|
|
RandBase = 0;
|
|
for (u32 Counter = 0 ; Counter < NUM_OF_FERNS ; Counter++)
|
|
{
|
|
u32 CounterComp;
|
|
CounterComp = NUM_OF_BINTEST;
|
|
while(CounterComp--)
|
|
{
|
|
s32 X,Y,X2,Y2;
|
|
do{
|
|
X = ConstantRandom()%PatchSize;
|
|
Y = ConstantRandom()%PatchSize;
|
|
} while (((X - (PatchSize>>1))*(X - (PatchSize>>1)) + (Y - (PatchSize>>1)) * (Y - (PatchSize>>1)) > ((PatchSize * PatchSize) >> 2))) ;
|
|
Ret->FernUsed[0][Counter].Compar[CounterComp * 2 + 0] = X + (Y << 8);
|
|
Ret->FernUsed[8][Counter].Compar[CounterComp * 2 + 0] = (PatchSize - X) + (Y << 8);
|
|
X2 = X;
|
|
Y2 = Y;
|
|
do{
|
|
X = ConstantRandom()%PatchSize;
|
|
Y = ConstantRandom()%PatchSize;
|
|
} while (
|
|
((X - (PatchSize>>1))*(X - (PatchSize>>1)) + (Y - (PatchSize>>1)) * (Y - (PatchSize>>1)) > ((PatchSize * PatchSize) >> 2)) &&
|
|
((X - X2)*(X - X2) + (Y - Y2) * (Y - Y2) < (2*2)) &&
|
|
((X - X2)*(X - X2) + (Y - Y2) * (Y - Y2) > (7*7)) //*/
|
|
)//*/
|
|
;
|
|
Ret->FernUsed[0][Counter].Compar[CounterComp * 2 + 1] = X + (Y << 8);
|
|
Ret->FernUsed[8][Counter].Compar[CounterComp * 2 + 1] = (PatchSize - X) + (Y << 8);
|
|
for (u32 RotateCounter = 1; RotateCounter < 4 ; RotateCounter++)
|
|
{
|
|
s32 Swap;
|
|
Swap = Y2;
|
|
Y2 = X2;
|
|
X2 = PatchSize-Swap;
|
|
Ret->FernUsed[RotateCounter][Counter].Compar[CounterComp * 2 + 0] = X2 + (Y2 << 8);
|
|
Swap = Y;
|
|
Y = X;
|
|
X = PatchSize-Swap;
|
|
Ret->FernUsed[RotateCounter][Counter].Compar[CounterComp * 2 + 1] = X + (Y << 8);
|
|
}
|
|
for (u32 RotateCounter = 4; RotateCounter < 8 ; RotateCounter++)
|
|
{
|
|
#define COS_45 0.70710678118654752440084436210485f
|
|
X2 = (Ret->FernUsed[RotateCounter - 4][Counter].Compar[CounterComp * 2 + 0] & 0xff) - (PatchSize>>1);
|
|
Y2 =((Ret->FernUsed[RotateCounter - 4][Counter].Compar[CounterComp * 2 + 0] >> 8) & 0xff) - (PatchSize>>1);
|
|
X = (s32)(0.5f + ((float)X2 * COS_45) + ((float)Y2 * COS_45) + (float)(PatchSize>>1));
|
|
Y = (s32)(0.5f - ((float)X2 * COS_45) + ((float)Y2 * COS_45) + (float)(PatchSize>>1));
|
|
if (X < 0) X = 0;
|
|
if (Y < 0) Y = 0;
|
|
Ret->FernUsed[RotateCounter][Counter].Compar[CounterComp * 2 + 0] = X + (Y << 8);
|
|
X2 = (Ret->FernUsed[RotateCounter - 4][Counter].Compar[CounterComp * 2 + 1] & 0xff) - (PatchSize>>1);
|
|
Y2 =((Ret->FernUsed[RotateCounter - 4][Counter].Compar[CounterComp * 2 + 1] >> 8) & 0xff) - (PatchSize>>1);
|
|
X = (s32)(0.5f + ((float)X2 * COS_45) + ((float)Y2 * COS_45) + (float)(PatchSize>>1));
|
|
Y = (s32)(0.5f - ((float)X2 * COS_45) + ((float)Y2 * COS_45) + (float)(PatchSize>>1));
|
|
if (X < 0) X = 0;
|
|
if (Y < 0) Y = 0;
|
|
Ret->FernUsed[RotateCounter][Counter].Compar[CounterComp * 2 + 1] = X + (Y << 8);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
LearnBase *FERN_CreatePatchBase(u32 ulNumberOfPatch)
|
|
{
|
|
LearnBase *Ret;
|
|
u32 Size;
|
|
/* ALIGN NP with 32 */
|
|
ulNumberOfPatch += 31;
|
|
ulNumberOfPatch &= ~31;
|
|
Ret = (LearnBase *)malloc(sizeof(LearnBase));
|
|
memset(Ret,0,sizeof(LearnBase));
|
|
Ret->PatchNumber = ulNumberOfPatch;
|
|
Size = FERN_PatchKnowledgeSize(Ret);
|
|
*(void **)&Ret->PatchKnowledge = malloc(Size);
|
|
memset(Ret->PatchKnowledge,0,Size);
|
|
FERN_InitBase(Ret);
|
|
return Ret;
|
|
}
|
|
|
|
u32 FERN_GetClassNumber(LearnBase *LB)
|
|
{
|
|
return LB->PatchNumber;
|
|
}
|
|
|
|
|
|
/*********************************************************************************************************************/
|
|
/*********************************************************************************************************************/
|
|
/* FULL TRAINING *****************************************************************************************************/
|
|
/*********************************************************************************************************************/
|
|
/*********************************************************************************************************************/
|
|
|
|
static void COPY_PATCH_ScaleRotation(MAP *MapSRC,MAP *MapDST,s32 SX,s32 SY,s32 DX,s32 DY,u32 DSizeX,u32 DSizeY,u32 SizeX,u32 SizeY,float Rot128,float SCLAEV)
|
|
{
|
|
s32 *LAST,*DST,*DST2,*SRC,*BIGLAST,*BIGSRCLAST;
|
|
s32 SYS,SYS2,SXS2,SXS3,SXI3,SYS3,SYI3,SXI,SYI,SYI2,SXI2;
|
|
s32 ScaleROTTable[1024],*p_ScaleROTTable;
|
|
s32 ScaleROTTableLenght[1024],*p_ScaleROTTableLenght;
|
|
float CosA,SinA;
|
|
|
|
CosA = cosf(Rot128);
|
|
SinA = sinf(Rot128);
|
|
|
|
//AAAA+= 1<<13;
|
|
SX -= (int)((CosA * (DSizeX>>1)) - (SinA * (DSizeY>>1))) ;
|
|
SY -= (int)((SinA * (DSizeX>>1)) + (CosA * (DSizeY>>1))) ;
|
|
SX <<= 8;
|
|
SY <<= 8;
|
|
|
|
SYS = 0;
|
|
SXI = (int)(65536.0f * ((float)DSizeX / (float)SizeX ));
|
|
SYI = (int)(65536.0f * ((float)DSizeY / (float)SizeY ));
|
|
|
|
/* Compute Scale X */
|
|
SXI3 = -(int)((float)SXI * SinA * SCLAEV);
|
|
SYI3 = (int)((float)SXI * CosA * SCLAEV);
|
|
SXS3 = SX;
|
|
SYS3 = SY;
|
|
|
|
/* Compute raster X */
|
|
|
|
SXI2 = (int)((float)SXI * CosA);
|
|
SYI2 = (int)((float)SXI * SinA);
|
|
SXS2 = 0;
|
|
SYS2 = 0;
|
|
|
|
/* Rasterize */
|
|
DX -= SizeX>>1;
|
|
DY -= SizeY>>1;
|
|
DX>>=8;DY>>=8;
|
|
if (DX < 0 ) DX = 0;
|
|
if (DY < 0 ) DY = 0;
|
|
|
|
p_ScaleROTTable = (s32 *)ScaleROTTable;
|
|
p_ScaleROTTableLenght = (s32*)ScaleROTTableLenght;
|
|
DST = MapDST->GetBase() + DY * MapDST->PITCH + DX;
|
|
BIGLAST = MapDST->GetBase() + MapDST->SX + MapDST->SY * MapDST->PITCH;
|
|
BIGSRCLAST = MapSRC->GetBase() + MapSRC->SX + MapSRC->SY * MapSRC->PITCH;
|
|
SizeX>>=8;SizeY>>=8;
|
|
while (SizeY--)
|
|
{
|
|
DST2 = DST;
|
|
SRC = MapSRC->GetBase();
|
|
LAST = DST + SizeX;
|
|
SXS2 = SXS3 + SXI2 * SizeX;
|
|
SYS2 = SYS3 + SYI2 * SizeX;
|
|
while (((SXS2>>16 >= (s32)MapSRC->SX) || (SXS2>>16 < 0) ||
|
|
(SYS2>>16 >= (s32)MapSRC->SY) || (SYS2>>16 < 0)) && (DST < LAST))
|
|
{
|
|
SXS2 -= SXI2;
|
|
SYS2 -= SYI2;
|
|
LAST--;
|
|
}
|
|
SXS2 = SXS3;
|
|
SYS2 = SYS3;
|
|
while (((SXS2>>16 >= (s32)MapSRC->SX) || (SXS2>>16 < 0) ||
|
|
(SYS2>>16 >= (s32)MapSRC->SY) || (SYS2>>16 < 0)) && (DST < LAST))
|
|
{
|
|
SXS2 += SXI2;
|
|
SYS2 += SYI2;
|
|
DST++;
|
|
}
|
|
|
|
while (DST < LAST)
|
|
{
|
|
if ((DST > MapDST->GetBase()) && (DST < BIGLAST) && (SRC > MapSRC->GetBase()) && (SRC < BIGSRCLAST) )
|
|
*(DST) = (*(SRC+(SXS2>>16) + (SYS2>>16)*MapSRC->PITCH)) & 0xfffffffe;
|
|
SXS2 += SXI2;
|
|
SYS2 += SYI2;
|
|
DST++;
|
|
}
|
|
SXS3 += SXI3;
|
|
SYS3 += SYI3;
|
|
DST = DST2 + MapDST->PITCH;
|
|
}
|
|
}
|
|
|
|
u32 SamplerMap_PIXELS[256 * 256];
|
|
u32 Random_T[65536];
|
|
MAP SamplerMap;
|
|
void ADD_NOISE(MAP *MapDST)
|
|
{
|
|
s32 *LAST,*DST;
|
|
u32 K,KA;
|
|
static u32 Init = 1;
|
|
if (Init)
|
|
{
|
|
Init = 65536;
|
|
while (Init--)
|
|
{
|
|
Random_T[Init] = rand()&255;
|
|
Random_T[Init] *= Random_T[Init];
|
|
Random_T[Init] >>= 8;//*/
|
|
Random_T[Init] >>= 2;
|
|
}
|
|
Init = 0;
|
|
}
|
|
|
|
DST = MapDST->GetBase();
|
|
K = rand()&65535;
|
|
KA = rand()&127;
|
|
for (s32 SizeY = 0; SizeY < (s32)MapDST->SY;SizeY ++)
|
|
{
|
|
LAST = DST + MapDST->SX;
|
|
while (DST < LAST)
|
|
{
|
|
*(DST++) += Random_T[K&65535];
|
|
K+=KA;
|
|
}
|
|
DST+=MapDST->PITCH-MapDST->SX;
|
|
}
|
|
}
|
|
|
|
void FERN_SignalFail(struct LearnBase_ *LB)
|
|
{
|
|
//return;
|
|
/* Change BittestBase */
|
|
LB->ActiveFern ++;
|
|
LB->ActiveFern &= 0x7;
|
|
LB->p_FernUsed = &LB->FernOptimsed[LB->ActiveFern][0];
|
|
}
|
|
|
|
void FERN_TrainAPatchOnFly(LearnBase *LB, u32 *BWIm , u32 pitch , u32 PatchToSEt , u32 StatisticalMode)
|
|
{
|
|
FERN_TrainAPatch(LB, BWIm, pitch, PatchToSEt);
|
|
}
|
|
|
|
void FERN_TrainAPatchComplete_P(LearnBase *LB, u32 *BWIm , u32 pitch , u32 PatchToSEt , u32 SampleNum , u32 Clear , u32 Noise , float Scale , float angle , u32 Disp)
|
|
{
|
|
MAP SamplerMap2;
|
|
SamplerMap.BASE = (s32*)SamplerMap_PIXELS;
|
|
SamplerMap.SX = 128;
|
|
SamplerMap.SY = 128;
|
|
SamplerMap.PITCH = 128;
|
|
|
|
SamplerMap2.BASE = (s32*)(BWIm - 64 * pitch - 64);
|
|
SamplerMap2.SX = 128;
|
|
SamplerMap2.SY = 128;
|
|
SamplerMap2.PITCH = pitch;
|
|
|
|
if (Clear) FERN_ClearAClass(LB,PatchToSEt);
|
|
FERN_TrainAPatch(LB, BWIm, pitch, PatchToSEt);
|
|
if (Disp)
|
|
{
|
|
FERN_TrainAPatch(LB, BWIm + 1, pitch, PatchToSEt);
|
|
FERN_TrainAPatch(LB, BWIm - 1, pitch, PatchToSEt);
|
|
FERN_TrainAPatch(LB, BWIm + pitch, pitch, PatchToSEt);
|
|
FERN_TrainAPatch(LB, BWIm - pitch, pitch, PatchToSEt);
|
|
}
|
|
|
|
u32 Trainer;
|
|
Trainer = SampleNum;
|
|
while (Trainer--)
|
|
{
|
|
float ScaleNoise;
|
|
float AngleNoise;
|
|
ScaleNoise = (1.0f + Scale * 0.05f * ((float)(rand()&255) / 128.0f - 1.0f));
|
|
AngleNoise = angle * 0.05f * ((float)(rand()&255) / 128.0f - 1.0f);
|
|
COPY_PATCH_ScaleRotation(&SamplerMap2,&SamplerMap,
|
|
SamplerMap2.SX<<7,
|
|
SamplerMap2.SY<<7,
|
|
SamplerMap.SX<<7,
|
|
SamplerMap.SY<<7,
|
|
(u32)(ScaleNoise * (float)(3*PatchSize))<<8,
|
|
(u32)(ScaleNoise * (float)(3*PatchSize))<<8,
|
|
(3*PatchSize)<<8,
|
|
(3*PatchSize)<<8,
|
|
AngleNoise,
|
|
1.0f);
|
|
if (Noise) ADD_NOISE(&SamplerMap);
|
|
FERN_TrainAPatch(
|
|
LB,
|
|
(u32 *)(SamplerMap.BASE + (SamplerMap.SX>>1) + (SamplerMap.SY>>1) * SamplerMap.PITCH + ((rand()%3) - 1) + ((rand()%3) - 1) * SamplerMap.PITCH ),
|
|
SamplerMap.PITCH ,
|
|
PatchToSEt);
|
|
FERN_TrainAPatch(
|
|
LB,
|
|
(u32 *)(SamplerMap.BASE + 1+(SamplerMap.SX>>1) + (SamplerMap.SY>>1) * SamplerMap.PITCH + ((rand()%3) - 1) + ((rand()%3) - 1) * SamplerMap.PITCH ),
|
|
SamplerMap.PITCH ,
|
|
PatchToSEt);
|
|
FERN_TrainAPatch(
|
|
LB,
|
|
(u32 *)(SamplerMap.BASE -SamplerMap.PITCH+ (SamplerMap.SX>>1) + (SamplerMap.SY>>1) * SamplerMap.PITCH + ((rand()%3) - 1) + ((rand()%3) - 1) * SamplerMap.PITCH ),
|
|
SamplerMap.PITCH ,
|
|
PatchToSEt);
|
|
FERN_TrainAPatch(
|
|
LB,
|
|
(u32 *)(SamplerMap.BASE +SamplerMap.PITCH + (SamplerMap.SX>>1) + (SamplerMap.SY>>1) * SamplerMap.PITCH + ((rand()%3) - 1) + ((rand()%3) - 1) * SamplerMap.PITCH ),
|
|
SamplerMap.PITCH ,
|
|
PatchToSEt);
|
|
|
|
}
|
|
}
|
|
|
|
void FERN_TrainAPatchComplete(LearnBase *LB, u32 *BWIm , u32 pitch , u32 PatchToSEt )
|
|
{
|
|
START_RASTER(FRN);
|
|
FERN_TrainAPatchComplete_P(LB, BWIm , pitch , PatchToSEt , 0, 1, 1 , 0.5f , 0.5f ,0);
|
|
STOP_RASTER(FRN);
|
|
}
|
|
|
|
/*********************************************************************************************************************/
|
|
/*********************************************************************************************************************/
|
|
/* Features functions ***********************************************************************************************/
|
|
/*********************************************************************************************************************/
|
|
/*********************************************************************************************************************/
|
|
|
|
void FERN_FillFull(LearnBase *LB)
|
|
{
|
|
}
|
|
/////////////////////////////////////////////////////
|
|
// Feature learning, merging the two nearest vectors
|
|
|
|
u32 FERN_MergeNearest(LearnBase *LB,u32 SuggestedClass, u32 ErrorSugested = -1)
|
|
{
|
|
u32 Counter,*pBase,MASK,MASKXOR,MASKXORMIN,FI,FJ,MASKNUMMIN;
|
|
u32 Mask1[(32+NUM_OF_FERNS * (1<<NUM_OF_BINTEST)) >> 5];
|
|
u32 Mask2[(32+NUM_OF_FERNS * (1<<NUM_OF_BINTEST)) >> 5];
|
|
u32 MergedMask[(32+NUM_OF_FERNS * (1<<NUM_OF_BINTEST)) >> 5];
|
|
memset(Mask1,0,sizeof(Mask1));
|
|
memset(Mask2,0,sizeof(Mask2));
|
|
memset(MergedMask,0,sizeof(MergedMask));
|
|
u32 RealPatchNumber = LB->PatchNumber;
|
|
RealPatchNumber = 40;
|
|
if (RealPatchNumber > LB->PatchNumber) RealPatchNumber = LB->PatchNumber;
|
|
if (ErrorSugested != -1)
|
|
{
|
|
for (u32 i = 0 ; i < RealPatchNumber ; i++)
|
|
{
|
|
FERN_GetFullData(LB,Mask1,i);
|
|
Counter = (32+NUM_OF_FERNS * (1<<NUM_OF_BINTEST)) >> 5;
|
|
MASK = 0;
|
|
while (Counter--)
|
|
{
|
|
MASK += GetBitNumber(Mask1[Counter]);
|
|
}
|
|
if (SuggestedClass == i) ErrorSugested += MASK;
|
|
if (MASK == 0)
|
|
return i;
|
|
}
|
|
}
|
|
//return SuggestedClass;
|
|
|
|
// u32 CounterMM = RealPatchNumber >> 2;
|
|
// while (CounterMM--)
|
|
{
|
|
MASKNUMMIN = 100000000;
|
|
FJ = FI = 0;
|
|
for (u32 i = 0 ; i < RealPatchNumber - 1 ; i++)
|
|
{
|
|
if (FERN_GetFullData(LB,Mask1,i) )
|
|
{
|
|
for (u32 j = i+1 ; j < RealPatchNumber ; j++)
|
|
{
|
|
if (FERN_GetFullData(LB,Mask2,j))
|
|
{
|
|
/* Compute distance */
|
|
Counter = (32+NUM_OF_FERNS * (1<<NUM_OF_BINTEST)) >> 5;
|
|
MASK = MASKXOR = 0;
|
|
while (Counter--)
|
|
{
|
|
MASK += GetBitNumber(Mask1[Counter]|Mask2[Counter]);
|
|
MASKXOR += GetBitNumber(Mask1[Counter]&Mask2[Counter]);
|
|
}
|
|
if (MASK <= MASKNUMMIN)
|
|
{
|
|
FI = i;
|
|
FJ = j;
|
|
MASKXORMIN = MASK;
|
|
Counter = (32+NUM_OF_FERNS * (1<<NUM_OF_BINTEST)) >> 5;
|
|
while (Counter--)
|
|
{
|
|
MergedMask[Counter] = Mask1[Counter]|Mask2[Counter];
|
|
}
|
|
MASKNUMMIN = MASK;
|
|
}
|
|
if (MASKNUMMIN == 0) i = j = 1000000;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (FJ != FI)
|
|
{
|
|
if (MASKXORMIN >= ErrorSugested)
|
|
return SuggestedClass;//*/
|
|
FERN_SetFullData(LB,MergedMask,FI);
|
|
memset(MergedMask,0,sizeof(MergedMask));
|
|
FERN_SetFullData(LB,MergedMask,FJ);
|
|
LB->LearnCounter[FI] += LB->LearnCounter[FJ];
|
|
LB->LearnCounter[FJ] = 0;
|
|
FERN_GetFullData(LB,Mask1,FI);
|
|
FERN_GetFullData(LB,Mask2,FJ);
|
|
return FJ;
|
|
} else
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
|
|
///////////////////////////////////////////////
|
|
// Feature learning --- Special function
|
|
|
|
void FERN_PrecomputeFlags(LearnBase *LB, u32 *BWIm , u8 *Flags)
|
|
{
|
|
u32 Counter = NUM_OF_FERNS;
|
|
while (Counter--)
|
|
{
|
|
u32 V;
|
|
if (Counter > 15)
|
|
V = 0;
|
|
else
|
|
V = *(BWIm + LB->p_FernUsed[Counter].Compar[0]);
|
|
/* V |= *(BWIm +1+ LB->p_FernUsed[Counter].Compar[0]);
|
|
V |= *(BWIm -1+ LB->p_FernUsed[Counter].Compar[0]);
|
|
BWIm+=LB->Pitch;
|
|
V = *(BWIm + LB->p_FernUsed[Counter].Compar[0]);
|
|
V |= *(BWIm +1+ LB->p_FernUsed[Counter].Compar[0]);
|
|
V |= *(BWIm -1+ LB->p_FernUsed[Counter].Compar[0]);
|
|
BWIm-=LB->Pitch;
|
|
BWIm-=LB->Pitch;
|
|
V = *(BWIm + LB->p_FernUsed[Counter].Compar[0]);
|
|
V |= *(BWIm +1+ LB->p_FernUsed[Counter].Compar[0]);
|
|
V |= *(BWIm -1+ LB->p_FernUsed[Counter].Compar[0]);
|
|
// V |= (*(BWIm + LB->p_FernUsed[Counter].Compar[1]) & 0xaa)>>1;//*/
|
|
V &= 0xaa;
|
|
V |= V >> 5;
|
|
V &= 0xf;//*/
|
|
*(Flags++) = V;
|
|
}
|
|
}
|
|
|
|
|
|
//////////////////////////////////////////
|
|
// Feature learning --- Match function
|
|
#define Learn_Error (NUM_OF_FERNS - 1)
|
|
|
|
u32 FERN_MatchPatch_Error(LearnBase *LB, u32 *BWIm , u32 pitch , u32 Error)
|
|
{
|
|
u32 GetBob;
|
|
if (pitch != LB->Pitch) FERN_SetPitch(LB, pitch );
|
|
|
|
u8 Flags[NUM_OF_FERNS];
|
|
FERN_PrecomputeFlags(LB, BWIm , Flags);
|
|
if (FERN_FastDetect(LB,Flags))
|
|
{
|
|
GetBob = FERN_GetPatchBestResponse_GI(LB, BWIm , 0,Flags);
|
|
if ((LB->LastErrorDetected > Learn_Error) && (LB->LastNumberOfValids >= 0 ))
|
|
return GetBob;
|
|
}
|
|
return 0xffffffff;
|
|
}
|
|
|
|
//////////////////////////////////////////
|
|
// Feature learning --- Train function
|
|
// LearnMode = 0, nothing
|
|
// LearnMode = 1, Add Positive samples
|
|
// LearnMode = 2, Add Negative samples
|
|
|
|
void FERN_TrainBestPatch(LearnBase *LB, u32 *BWIm , u32 pitch , u32 LearnMode )
|
|
{
|
|
u32 BestClass;
|
|
if (pitch != LB->Pitch) FERN_SetPitch(LB, pitch );
|
|
LB->p_FernUsed = &LB->FernOptimsed[0][0];
|
|
|
|
u8 Flags[NUM_OF_FERNS];
|
|
FERN_PrecomputeFlags(LB, BWIm , Flags);
|
|
|
|
#define LearGrnul_Alloc (1<<18)
|
|
if (LearnMode == 1) // Positiv sample is added
|
|
{
|
|
if ((LB->ulNumberOfPositivesSamples & (LearGrnul_Alloc-1)) == 0)
|
|
{
|
|
if (LB->PositiveSamples == NULL)
|
|
LB->PositiveSamples = (u8*)malloc(LearGrnul_Alloc * NUM_OF_FERNS);
|
|
else
|
|
LB->PositiveSamples = (u8*)realloc(LB->PositiveSamples,(LB->ulNumberOfPositivesSamples + LearGrnul_Alloc + 1) * NUM_OF_FERNS);
|
|
}
|
|
memcpy(&LB->PositiveSamples[LB->ulNumberOfPositivesSamples * NUM_OF_FERNS],Flags,NUM_OF_FERNS);
|
|
LB->ulNumberOfPositivesSamples++;
|
|
}
|
|
if (LearnMode == 2) // Negativ sample is added
|
|
{
|
|
if (LB->ulNumberOfNegativesSamples > 10000000) return;
|
|
if (LB->LearnCounter[0])
|
|
{
|
|
// If this is already learned, then add only false positiv
|
|
if (!FERN_FastDetect(LB,Flags))
|
|
{
|
|
return;
|
|
}
|
|
}
|
|
if ((LB->ulNumberOfNegativesSamples & (LearGrnul_Alloc-1)) == 0)
|
|
{
|
|
if (LB->NegativeSamples == NULL)
|
|
LB->NegativeSamples = (u8**)malloc(4*(LearGrnul_Alloc+1));
|
|
else
|
|
LB->NegativeSamples = (u8**)realloc(LB->NegativeSamples,4*(LB->ulNumberOfNegativesSamples + LearGrnul_Alloc + 1));
|
|
}
|
|
LB->NegativeSamples[LB->ulNumberOfNegativesSamples] = (u8*)malloc(NUM_OF_FERNS);
|
|
memcpy(LB->NegativeSamples[LB->ulNumberOfNegativesSamples],Flags,NUM_OF_FERNS);
|
|
LB->ulNumberOfNegativesSamples++;
|
|
}//*/
|
|
}
|
|
|
|
/////////////////////////////////////////////
|
|
// Feature learning --- Compute Vectors
|
|
void FERN_GetVectorData(LearnBase *LB,u32 *Mask,u8 *Vector)
|
|
{
|
|
LEARN_TYPE *FernKnParser,*FernKnParserL;
|
|
u32 Counter,p32C;
|
|
FernKnParser = LB->PatchKnowledge;
|
|
Counter = NUM_OF_FERNS;
|
|
while (Counter--)
|
|
{
|
|
s32 Indx;
|
|
Indx = *(Vector++);
|
|
p32C = ((LB->PatchNumber)>>5);
|
|
FernKnParserL = FernKnParser + (Indx * LB->PatchNumber>>5);
|
|
while (p32C--) *(Mask++) = *(FernKnParserL++);
|
|
FernKnParser += ((1<<NUM_OF_BINTEST) * LB->PatchNumber)>>5;
|
|
}
|
|
}
|
|
void FERN_SetVectorData(LearnBase *LB,u32 *Mask,u8 *Vector)
|
|
{
|
|
LEARN_TYPE *FernKnParser,*FernKnParserL;
|
|
u32 Counter,p32C;
|
|
FernKnParser = LB->PatchKnowledge;
|
|
Counter = NUM_OF_FERNS;
|
|
while (Counter--)
|
|
{
|
|
s32 Indx;
|
|
Indx = *(Vector++);
|
|
p32C = ((LB->PatchNumber)>>5);
|
|
FernKnParserL = FernKnParser + (Indx * LB->PatchNumber>>5);
|
|
while (p32C--) *(FernKnParserL++) = *(Mask++);
|
|
FernKnParser += ((1<<NUM_OF_BINTEST) * LB->PatchNumber)>>5;
|
|
}
|
|
}
|
|
|
|
u32 FERN_FastDetect_64(LearnBase *LB,u8 *Vector)
|
|
{
|
|
LEARN_TYPE *FernKnParser;
|
|
u32 MASK0,MASK1;
|
|
FernKnParser = LB->PatchKnowledge;
|
|
MASK0 = MASK1 = 0xffffffff;
|
|
for (int Counter = 0 ; Counter < NUM_OF_FERNS ; Counter++)
|
|
{
|
|
s32 Indx;
|
|
Indx = *(Vector++);
|
|
Indx <<= 1;
|
|
MASK0 &= *(FernKnParser + Indx);
|
|
MASK1 &= *(FernKnParser + Indx + 1);
|
|
FernKnParser += (((1<<NUM_OF_BINTEST) * LB->PatchNumber)>>5);
|
|
if ((MASK0 == 0) && (MASK1 == 0))
|
|
return 0;
|
|
}
|
|
return 1;
|
|
}
|
|
u32 FERN_FastDetect(LearnBase *LB,u8 *Vector)
|
|
{
|
|
LEARN_TYPE *FernKnParser;
|
|
u32 MASK0;
|
|
if (LB->PatchNumber > 32) return FERN_FastDetect_64(LB,Vector);
|
|
FernKnParser = LB->PatchKnowledge;
|
|
MASK0 = 0xffffffff;
|
|
for (int Counter = 0 ; Counter < NUM_OF_FERNS ; Counter++)
|
|
{
|
|
s32 Indx;
|
|
Indx = *(Vector++);
|
|
MASK0 &= *(FernKnParser + Indx);
|
|
FernKnParser += (((1<<NUM_OF_BINTEST) * LB->PatchNumber)>>5);
|
|
if (MASK0 == 0)
|
|
return 0;
|
|
}
|
|
// return MASK0;
|
|
// if ((MASK0 & 0xf) && (MASK0 & (0xf<<4)) && (MASK0 & (0xf<<8)) && (MASK0 & (0xf<<12)))
|
|
// if ((MASK0 & 0x7) && (MASK0 & (0x7<<3)) && (MASK0 & (0x7<<6)))
|
|
if ((MASK0 & 0x7) && (MASK0 & (0x7<<3)) && (MASK0 & (0x7<<6)) /*&& (MASK0 & (0x7<<9))*/)
|
|
// if ((MASK0 & 0x7) && (MASK0 & (0x7<<3)) && (MASK0 & (0x7<<6)) && (MASK0 & (0x7<<9)) && (MASK0 & (0x7<<12)))
|
|
return 1;
|
|
else
|
|
return 0;
|
|
}
|
|
|
|
typedef struct Statbase_
|
|
{
|
|
double StatResult;
|
|
double StatResultIntersect[32];
|
|
} Statbase;
|
|
|
|
double FERN_ComputeStat(LearnBase *LB,Statbase *SB)
|
|
{
|
|
u32 Mask18[(64+NUM_OF_FERNS * (1<<NUM_OF_BINTEST)) >> 5];
|
|
u32 Mask18_BC[NUM_OF_FERNS+4];
|
|
u32 *M18;
|
|
double StatMax;
|
|
u32 RealPatchN;
|
|
RealPatchN = 12;
|
|
StatMax = 0;
|
|
memset(Mask18,0,sizeof(Mask18));
|
|
memset(SB,0,LB->PatchNumber * sizeof(Statbase));
|
|
FERN_GetFullData(LB,Mask18,18);
|
|
M18 = Mask18;
|
|
for (u32 j = 0 ; j < NUM_OF_FERNS ; j++)
|
|
{
|
|
u32 BC = 0;
|
|
for (u32 k = 0 ; k < (1<<NUM_OF_BINTEST) >> 5 ; k++)
|
|
{
|
|
BC += GetBitNumber(*M18);
|
|
M18++;
|
|
}
|
|
Mask18_BC[j] = BC;
|
|
}
|
|
|
|
for (u32 i=0;i<RealPatchN;i++)
|
|
{
|
|
u32 Mask[(64+NUM_OF_FERNS * (1<<NUM_OF_BINTEST)) >> 5];
|
|
u32 *M0;
|
|
memset(Mask,0,sizeof(Mask));
|
|
SB[i].StatResult = 1.0;
|
|
FERN_GetFullData(LB,Mask,i);
|
|
M0 = Mask;
|
|
for (u32 j = 0 ; j < NUM_OF_FERNS ; j++)
|
|
{
|
|
u32 BC = 0;
|
|
for (u32 k = 0 ; k < (1<<NUM_OF_BINTEST) >> 5 ; k++)
|
|
{
|
|
BC += GetBitNumber(*M0);
|
|
M0++;
|
|
}
|
|
double RES = (double)(BC)/(double)(Mask18_BC[j]);
|
|
SB[i].StatResult *= RES;
|
|
}
|
|
if (SB[i].StatResult > StatMax)
|
|
StatMax = SB[i].StatResult;//*/
|
|
}
|
|
for (u32 i=0;i<RealPatchN;i++)
|
|
{
|
|
SB[i].StatResult = 0.0;
|
|
for (u32 j=0;j<RealPatchN;j++)
|
|
{
|
|
SB[i].StatResultIntersect[j] = 1.0;
|
|
//if (i != j)
|
|
{
|
|
u32 MaskI[(64+NUM_OF_FERNS * (1<<NUM_OF_BINTEST)) >> 5];
|
|
u32 MaskJ[(64+NUM_OF_FERNS * (1<<NUM_OF_BINTEST)) >> 5];
|
|
u32 *M0,*M1;
|
|
memset(MaskI,0,sizeof(MaskI));
|
|
memset(MaskJ,0,sizeof(MaskJ));
|
|
FERN_GetFullData(LB,MaskI,i);
|
|
FERN_GetFullData(LB,MaskJ,j);
|
|
M0 = MaskI;
|
|
M1 = MaskJ;
|
|
for (u32 f = 0 ; f < NUM_OF_FERNS ; f++)
|
|
{
|
|
u32 BC = 0;
|
|
for (u32 k = 0 ; k < (1<<NUM_OF_BINTEST) >> 5 ; k++)
|
|
{
|
|
BC += GetBitNumber(*M0 & *M1);
|
|
M0++;
|
|
M1++;
|
|
}
|
|
double RES = (double)(BC)/(double)(Mask18_BC[f]);
|
|
SB[i].StatResultIntersect[j] *= RES;
|
|
}
|
|
//if (i != j)
|
|
SB[i].StatResult += SB[i].StatResultIntersect[j];
|
|
if (SB[i].StatResult > StatMax)
|
|
StatMax = SB[i].StatResult;
|
|
}
|
|
}
|
|
}//*/
|
|
|
|
return StatMax;
|
|
}
|
|
|
|
static float volatile AVERAGE_LEARN = 1.0f;
|
|
static float volatile LAST_AVERAGE_LEARN = 1.0f;
|
|
static float volatile AVERAGE_LEARND = 1.0f;
|
|
static float volatile GMAX = 0;
|
|
void FERN_SmearPositiv(LearnBase *LB)
|
|
{
|
|
/* Smear datas */
|
|
for (int i = 0 ; i < LB->ulNumberOfPositivesSamples ; i++)
|
|
{
|
|
u8 SI[NUM_OF_FERNS];
|
|
u8 SJ[NUM_OF_FERNS];
|
|
int j = rand()%LB->ulNumberOfPositivesSamples;
|
|
memcpy(SI,LB->PositiveSamples + i * NUM_OF_FERNS,NUM_OF_FERNS);
|
|
memcpy(SJ,LB->PositiveSamples + j * NUM_OF_FERNS,NUM_OF_FERNS);
|
|
memcpy(LB->PositiveSamples + i * NUM_OF_FERNS,SJ,NUM_OF_FERNS);
|
|
memcpy(LB->PositiveSamples + j * NUM_OF_FERNS,SI,NUM_OF_FERNS);
|
|
}
|
|
}
|
|
#define FAST_C 0
|
|
void FERN_SetPatchBestResponse_Closest(LearnBase *LB,u32 Good_I,u8 *Flags)
|
|
{
|
|
u8 LocalGLG[NUM_OF_FERNS];
|
|
FERN_SetPatchBestResponse_GI(LB, NULL , Good_I,Flags);
|
|
for (int R = 0 ; R < NUM_OF_FERNS ; R++)
|
|
LocalGLG[R] = (Flags[R]>>1) | (Flags[R]<<7);
|
|
FERN_SetPatchBestResponse_GI(LB, NULL , Good_I,LocalGLG);
|
|
for (int R = 0 ; R < NUM_OF_FERNS ; R++)
|
|
LocalGLG[R] = (Flags[R]>>7) | (Flags[R]<<1);
|
|
FERN_SetPatchBestResponse_GI(LB, NULL , Good_I,LocalGLG);
|
|
}
|
|
|
|
|
|
void FERN_Finishlearn(LearnBase *LB)
|
|
{
|
|
u8 *Flags,**FlagsNEG;
|
|
if (!LB) return;
|
|
u32 SaveSign[NUM_OF_FERNS<<1];
|
|
u32 SetSign[NUM_OF_FERNS<<1];
|
|
u32 BADMIN_I,BADMIN_V;
|
|
u32 BAD_LOWEST = 0;
|
|
u32 BAD_LOWEST_I = -1;
|
|
FERN_SmearPositiv(LB);
|
|
FERN_SmearPositiv(LB);
|
|
FERN_SmearPositiv(LB);
|
|
static int volatile i;
|
|
|
|
for (int j = 0 ; j < LB->PatchNumber ; j++)
|
|
FERN_ClearAClass(LB,j);
|
|
|
|
Flags = LB->PositiveSamples;
|
|
for (i = 0 ; i < LB->ulNumberOfPositivesSamples; i++)
|
|
{
|
|
FERN_SetPatchBestResponse_GI(LB, NULL , 18,Flags);
|
|
Flags += NUM_OF_FERNS;
|
|
}
|
|
|
|
for (i = 0 ; i < 17; i++)
|
|
{
|
|
FERN_SetPatchBestResponse_GI(LB, NULL , 18,Flags);
|
|
}
|
|
|
|
// if (LB->ulNumberOfNegativesSamples > 2048) LB->ulNumberOfNegativesSamples = 2048;
|
|
|
|
#if 1
|
|
u32 ToCreate = 0;
|
|
for (int M = 0 ; M < 1 ; M ++)
|
|
{
|
|
Flags = LB->PositiveSamples;
|
|
FlagsNEG = LB->NegativeSamples;
|
|
|
|
|
|
//FERN_ClearAClass(LB,0);
|
|
|
|
u32 Limit;
|
|
i = 0;
|
|
Limit = LB->ulNumberOfPositivesSamples;
|
|
/* for (i = 0 ; i < 8 ; i++)
|
|
{
|
|
FERN_SetPatchBestResponse_GI(LB, NULL , i,Flags);
|
|
Flags += NUM_OF_FERNS<<FAST_C;
|
|
}//*/
|
|
|
|
for (; i < Limit ; i++)
|
|
{
|
|
//////////////////////////////////////
|
|
// Method 1 (VQ)
|
|
/*
|
|
u32 BestClass = FERN_GetPatchBestResponse_GI(LB, NULL , 1,Flags);
|
|
if (LB->LastErrorDetected <= Learn_Error)
|
|
{
|
|
BestClass = FERN_MergeNearest(LB,BestClass,NUM_OF_FERNS - LB->LastErrorDetected);
|
|
FERN_SetPatchBestResponse_GI(LB, NULL , BestClass,Flags);
|
|
// Check on positive base
|
|
}
|
|
Flags += NUM_OF_FERNS<<FAST_C;
|
|
///**/
|
|
/*
|
|
//////////////////////////////////////
|
|
// Method 2 (VQ + test over ALL negativs)
|
|
BADMIN_I = -1;
|
|
BADMIN_V = 0;
|
|
// u32 GetBob = FERN_GetPatchBestResponse_GI(LB, NULL , 0,Flags);
|
|
// if (LB->LastErrorDetected <= Learn_Error)
|
|
if (!FERN_FastDetect(LB,Flags))
|
|
{
|
|
u32 PRED = FERN_GetPatchBestResponse_GI(LB, NULL , 0,Flags);
|
|
if (PRED == -1) PRED = 0;
|
|
FERN_GetVectorData(LB,SaveSign,Flags);
|
|
BADMIN_V = LB->ulNumberOfNegativesSamples;
|
|
for (int j0 = -1 ; (j0 < LB->PatchNumber) || (j0 < 0) ; j0++)
|
|
{
|
|
int j = (j0 == -1) ? PRED : j0;
|
|
u32 BAD = 0;
|
|
u32 BaseSet = j>>5;
|
|
u32 BaseJump = (LB->PatchNumber>>5);
|
|
|
|
memcpy(SetSign,SaveSign,sizeof(SetSign));
|
|
for (int l = 0 ; l < NUM_OF_FERNS ; l++,BaseSet += BaseJump) SetSign[BaseSet] |= (1<<(j&31));
|
|
FERN_SetVectorData(LB,SetSign,Flags);
|
|
FlagsNEG = LB->NegativeSamples;
|
|
for (int k = 0 ; k < LB->ulNumberOfNegativesSamples >> FAST_C; k++)
|
|
{
|
|
|
|
if (FERN_FastDetect(LB,*FlagsNEG))
|
|
BAD++;
|
|
FlagsNEG += 1 << FAST_C;
|
|
if (BAD >= BADMIN_V) k = LB->ulNumberOfNegativesSamples;
|
|
}
|
|
if (BAD < BADMIN_V)
|
|
{
|
|
BADMIN_I = j;
|
|
BADMIN_V = BAD;
|
|
}
|
|
FERN_SetVectorData(LB,SaveSign,Flags);
|
|
if (BAD == BAD_LOWEST) j = LB->PatchNumber;
|
|
}
|
|
BAD_LOWEST = BADMIN_V;
|
|
|
|
if ((BAD_LOWEST_I == -1) && (BAD_LOWEST))
|
|
BAD_LOWEST_I = i;
|
|
}
|
|
if (BADMIN_I != -1)
|
|
{
|
|
FERN_SetPatchBestResponse_GI(LB, NULL , BADMIN_I , Flags);
|
|
}
|
|
if ((i & 127) == 127)
|
|
{
|
|
AVERAGE_LEARN = 0.0f;
|
|
for (int g = 0; g < LB->PatchNumber ; g++)
|
|
{
|
|
AVERAGE_LEARN += LB->LearnCounter[g];
|
|
if (LB->LearnCounter[g]) GMAX = g;
|
|
}
|
|
AVERAGE_LEARND = (AVERAGE_LEARN - LAST_AVERAGE_LEARN) / (float)128.0f ;
|
|
LAST_AVERAGE_LEARN = AVERAGE_LEARN;
|
|
AVERAGE_LEARN = AVERAGE_LEARN / (float)(i+1) ;
|
|
}
|
|
|
|
Flags += NUM_OF_FERNS<<FAST_C;
|
|
//*/
|
|
//////////////////////////////////////
|
|
// Method 3 (ULTRA LOW STATS)
|
|
//FlagsNEG = LB->NegativeSamples;
|
|
/*Flags = *FlagsNEG;
|
|
FlagsNEG++;*/
|
|
u32 K = FERN_FastDetect(LB,Flags);
|
|
|
|
if (!K)
|
|
{
|
|
Statbase SBo[128];
|
|
Statbase SB[128];
|
|
double StatMin;
|
|
u32 SaveSign[NUM_OF_FERNS<<1];
|
|
u32 SetSign[NUM_OF_FERNS<<1];
|
|
u32 Good_I;
|
|
int ovrN = rand()%3;
|
|
for (int ovr = 0; ovr < 3; ovr++)
|
|
{
|
|
if (ovr != ovrN)
|
|
{
|
|
Good_I = 0;
|
|
StatMin = 1000000000000000000.0;
|
|
FERN_GetVectorData(LB,SaveSign,Flags);
|
|
FERN_ComputeStat(LB,SBo);
|
|
for (int j = ovr*3; j < ovr*3+3; j++)
|
|
{
|
|
memcpy(SetSign,SaveSign,sizeof(SetSign));
|
|
u32 BaseSet = j>>5;
|
|
u32 BaseJump = (LB->PatchNumber>>5);
|
|
for (int l = 0 ; l < NUM_OF_FERNS ; l++,BaseSet += BaseJump) SetSign[BaseSet] |= (1<<(j&31));
|
|
FERN_SetVectorData(LB,SetSign,Flags);
|
|
double L ;
|
|
FERN_ComputeStat(LB,SB);
|
|
L = SB[j].StatResult - SBo[j].StatResult;
|
|
if (L < StatMin)
|
|
{
|
|
Good_I = j;
|
|
StatMin = L;
|
|
}
|
|
FERN_SetVectorData(LB,SaveSign,Flags);
|
|
}
|
|
FERN_SetPatchBestResponse_GI(LB, NULL , Good_I,Flags);
|
|
}
|
|
}
|
|
|
|
}
|
|
Flags += NUM_OF_FERNS<<FAST_C;
|
|
//////////////////////////////////////
|
|
// Method 4 (Short)
|
|
/* if (!FERN_FastDetect(LB,Flags))
|
|
{
|
|
if (ToCreate < 10)
|
|
FERN_SetPatchBestResponse_GI(LB, NULL , ToCreate++ , Flags);
|
|
else
|
|
{
|
|
u32 GetBob = FERN_GetPatchBestResponse_GI(LB, NULL , 1,Flags);
|
|
FERN_SetPatchBestResponse_GI(LB, NULL , GetBob , Flags);
|
|
}
|
|
}
|
|
Flags += NUM_OF_FERNS<<FAST_C;
|
|
*/
|
|
|
|
}
|
|
}
|
|
#endif
|
|
/* for (u32 HH = 0 ; HH < 31-8 ; HH ++)
|
|
FERN_MergeNearest(LB,0);*/
|
|
u32 LearnCounter[MAX_NUM_OF_PATCH];
|
|
memset(LearnCounter,0,sizeof(LearnCounter));
|
|
FERN_ClearAClass(LB,18);
|
|
|
|
FlagsNEG = LB->NegativeSamples;
|
|
for (int i = 0 ; i < LB->ulNumberOfNegativesSamples>>FAST_C ; i++)
|
|
{
|
|
Flags = *FlagsNEG;
|
|
if (FERN_FastDetect(LB,Flags))
|
|
LearnCounter[FERN_GetPatchBestResponse_GI(LB, NULL , 0,Flags)]++;
|
|
FlagsNEG++;
|
|
}
|
|
|
|
|
|
|
|
/* if (LB->NegativeSamples) free(LB->NegativeSamples);
|
|
if (LB->PositiveSamples) free(LB->PositiveSamples);
|
|
LB->NegativeSamples = LB->PositiveSamples = NULL;
|
|
LB->ulNumberOfPositivesSamples = LB->ulNumberOfNegativesSamples = 0;*/
|
|
}
|
|
|
|
|
|
|
|
#endif
|