JD2022-TU1/main/extern/Camcam/LIBS/Trackeur/BackgroundExtractionEnergy.cpp

932 lines
26 KiB
C++

#include "SCENE.h"
//#define BACK_DEBUG_INFO_TEXT
void SET_BORDER(MAP *MapSRC,s32 Size,s32 Value);
void OR(MAP *MapSRC,MAP *MapDST);
void MAP16_Neg(MAP16 *MapSRC);
u32 MAP_2_MAP16_RGBA(MAP *MapSRC,MAP16 *MapDST,u32 RGBA );
//#pragma optimize("",off)
typedef struct SolverS_
{
union {
struct {
s16 InitValue;
s16 SolvedValue;
};
u32 RGBA;
};
} SolverS;
#define VIBE_THRESH 3500
static s32 BLUADDDENOISE = 1;
static s32 BLUADDDENOISE_SUMM = -32;
u32 SOLVE_Thresj = 8;
static Vector BigGain = Vector(1,1,1);
static float AlphaGain = 1;
static float NoiseMesure = 1;
void TRK_AE_ComputeBackgroundParrams(s32 FactorBlur, s32 FactorBlurSumm)
{
BLUADDDENOISE = FactorBlur;
BLUADDDENOISE_SUMM = FactorBlurSumm;
}
/* This function will back-compute the camera gain. */
void BACK_ComputeGain(MAP *pFIX,MAP *pCUR,MAP16 *pALpha)
{
s32 *pFIXBASE = pFIX->GetBase();
s32 *pCURBASE = pCUR->GetBase();
s16 *pALphaBASE = pALpha->GetBase();
Vector BigCoefB = Vector(0,0,0);
Vector BigCoefF = Vector(0,0,0);
u32 Number;
Number = 0;
for (int X = 4 ; X < pFIX->SX - 4; X++)
for (int Y = 4 ; Y < pFIX->SY - 4; Y++)
{
{
if (pALphaBASE[X + Y * pALpha->PITCH] < 16)
{
BigCoefB.x += (float)((u8 *)&pFIXBASE[(X) + (Y) * pFIX->PITCH])[0];
BigCoefB.y += (float)((u8 *)&pFIXBASE[(X) + (Y) * pFIX->PITCH])[1];
BigCoefB.z += (float)((u8 *)&pFIXBASE[(X) + (Y) * pFIX->PITCH])[2];
BigCoefF.x += (float)((u8 *)&pCURBASE[(X) + (Y) * pCUR->PITCH])[0];
BigCoefF.y += (float)((u8 *)&pCURBASE[(X) + (Y) * pCUR->PITCH])[1];
BigCoefF.z += (float)((u8 *)&pCURBASE[(X) + (Y) * pCUR->PITCH])[2];
Number++;
}
}
}
AlphaGain = 1;
if (Number > 4000)
{
BigGain = Vector(BigCoefF.x / BigCoefB.x ,BigCoefF.y / BigCoefB.y ,BigCoefF.z / BigCoefB.z );
AlphaGain = (BigGain.y * 2 + BigGain.x + BigGain.z)/4.0f;
} else
BigGain = Vector(1,1,1);
}
/* This test function will*/
#define SILHOUETE_THRESHOLD 240
//#define SILHOUETE_THRESHOLD_BORDER 220
void BACK_ComputeBack(MAP *pFIX,MAP *pCUR,MAP16 *pALphaFronteer,MAP16 *pALpha)
{
s32 *pFIXBASE = pFIX->GetBase();
s32 *pCURBASE = pCUR->GetBase();
s16 *pALphaBASE = pALpha->GetBase();
s16 *pALphaFronteerBASE = pALphaFronteer->GetBase();
for (int X = 4 ; X < pFIX->SX - 4; X++)
for (int Y = 4 ; Y < pFIX->SY - 4; Y++)
{
if ((pALphaFronteerBASE[X + Y * pALpha->PITCH] & (8))
)
{
float R = ((u8 *)&pCURBASE[(X) + (Y) * pCUR->PITCH])[0] / BigGain.x;
float G = ((u8 *)&pCURBASE[(X) + (Y) * pCUR->PITCH])[1] / BigGain.y;
float B = ((u8 *)&pCURBASE[(X) + (Y) * pCUR->PITCH])[2] / BigGain.z;
float A = (((u8 *)&pCURBASE[(X) + (Y) * pCUR->PITCH])[3]) / (AlphaGain * AlphaGain);
if (R > 255 ) R = 255;
if (G > 255 ) G = 255;
if (B > 255 ) B = 255;
if (A > 255 ) A = 255;
((u8 *)&pFIXBASE[(X) + (Y) * pFIX->PITCH])[0] = R;
((u8 *)&pFIXBASE[(X) + (Y) * pFIX->PITCH])[1] = G;
((u8 *)&pFIXBASE[(X) + (Y) * pFIX->PITCH])[2] = B;
((u8 *)&pFIXBASE[(X) + (Y) * pFIX->PITCH])[3] = A;
} else
{
/* float R = ((u8 *)&pFIXBASE[(X) + (Y) * pFIX->PITCH])[0] * BigGain.x;
float G = ((u8 *)&pFIXBASE[(X) + (Y) * pFIX->PITCH])[1] * BigGain.y;
float B = ((u8 *)&pFIXBASE[(X) + (Y) * pFIX->PITCH])[2] * BigGain.z;
float A = ((u8 *)&pFIXBASE[(X) + (Y) * pFIX->PITCH])[3] * AlphaGain;
if (R > 255 ) R = 255;
if (G > 255 ) G = 255;
if (B > 255 ) B = 255;
if (A > 255 ) A = 255;
((u8 *)&pFIXBASE[(X) + (Y) * pFIX->PITCH])[0] = 0.25f * R + 0.75f * (float)((u8 *)&pFIXBASE[(X) + (Y) * pFIX->PITCH])[0];
((u8 *)&pFIXBASE[(X) + (Y) * pFIX->PITCH])[1] = 0.25f * G + 0.75f * (float)((u8 *)&pFIXBASE[(X) + (Y) * pFIX->PITCH])[1];
((u8 *)&pFIXBASE[(X) + (Y) * pFIX->PITCH])[2] = 0.25f * B + 0.75f * (float)((u8 *)&pFIXBASE[(X) + (Y) * pFIX->PITCH])[2];
((u8 *)&pFIXBASE[(X) + (Y) * pFIX->PITCH])[3] = 0.25f * A + 0.75f * (float)((u8 *)&pFIXBASE[(X) + (Y) * pFIX->PITCH])[3];*/
}
}
}
/* */
void COPY_O2_RGBA_ENERGY(MAP *MapSRC,MAP *MapDST)
{
s32 *LAST,*DST,*SRC,*SRC2;
SET(MapDST,0);
DST = MapDST->GetBase() + MapDST->PITCH;
SRC = MapSRC->GetBase() + MapSRC->PITCH;
for (u32 SizeY = 1; SizeY < MapDST->SY ;SizeY ++)
{
LAST = DST + MapDST->SX;
SRC2 = SRC + MapSRC->PITCH;
while (DST < LAST)
{
u32 A,B;
A = ((*(SRC) & 0xfefefefe)>>1) + ((*(SRC + 1) & 0xfefefefe)>>1);
B = ((*(SRC2) & 0xfefefefe)>>1) + ((*(SRC2 + 1) & 0xfefefefe)>>1);
A &= 0xffffff;
B &= 0xffffff;
float R1,R2,R3,R4,AvSqr,SqrAv,EQ;
R1 = (*(SRC) & 0xff00)>>8;
R2 = (*(SRC2) & 0xff00)>>8;
R3 = (*(SRC+1) & 0xff00)>>8;
R4 = (*(SRC2+1) & 0xff00)>>8;
AvSqr = (R1*R1 + R2*R2 + R3*R3 + R4*R4) / 4.0f;
SqrAv = (R1 + R2 + R3 + R4)/4.0f;
SqrAv *= SqrAv;
EQ = sqrtf(AvSqr - SqrAv) * 2;
R1 = (*(SRC) & 0xff0000)>>16;
R2 = (*(SRC2) & 0xff0000)>>16;
R3 = (*(SRC+1) & 0xff0000)>>16;
R4 = (*(SRC2+1) & 0xff0000)>>16;
AvSqr = (R1*R1 + R2*R2 + R3*R3 + R4*R4) / 4.0f;
SqrAv = (R1 + R2 + R3 + R4)/4.0f;
SqrAv *= SqrAv;
EQ += sqrtf(AvSqr - SqrAv);
R1 = (*(SRC) & 0xff)>>0;
R2 = (*(SRC2) & 0xff)>>0;
R3 = (*(SRC+1) & 0xff)>>0;
R4 = (*(SRC2+1) & 0xff)>>0;
AvSqr = (R1*R1 + R2*R2 + R3*R3 + R4*R4) / 4.0f;
SqrAv = (R1 + R2 + R3 + R4)/4.0f;
SqrAv *= SqrAv;
EQ += sqrtf(AvSqr - SqrAv);
EQ /= 4;
if (EQ > 255) EQ = 255;
*(DST) = ((A & 0xfefefe)>>1) + ((B & 0xfefefe)>>1);;
//EQ = 0;
*DST |= (s32)(((u32)EQ)<<24);
DST++;
SRC += 2;
SRC2 += 2;
}
SRC+=(MapSRC->PITCH-MapSRC->SX);
SRC+= MapSRC->PITCH;
DST+=MapDST->PITCH-MapDST->SX;
}
}
s32 SolverRGBDistance(s32 *A,s32 *B)
{
//return 0;
float Re = (float)(((u8*)A)[0]) - (float)(((u8*)B)[0]);
float Gr = (float)(((u8*)A)[1]) - (float)(((u8*)B)[1]);
float Bl = (float)(((u8*)A)[2]) - (float)(((u8*)B)[2]);
float Del = (Re*Re+ Gr*Gr + Bl*Bl) - 16;
if (Del < 0) Del = 0;
Del *= 4;
float Res = (1<<SOLVE_Thresj) - Del;
if (Res < 0) return 0;
return Res;
}
#define PARSE_SOLVE(a,b) \
{\
/* Reevaluate Neibourhood Value (due to continuyty)*/\
float T1,T2;\
SolverDX += a ; SolverDY += b;\
{\
T2 = T1 = 0;\
if (SolverMode & 1) T1 =DistanceFactor* (float)((Pixel[a + b * Pitch].InitValue * Pixel->SolvedValue)>>SOLVE_Thresj) ; \
if (SolverMode & 2) {\
T2 = ((SolverRGBDistance((int*)&BaseRGB,&PixelRGB[a + b * Pitch]) * Pixel->SolvedValue)>>SOLVE_Thresj) * DistanceFactor;\
if (T2 > T1) T1 = T2;\
}\
if (T1 > 1 << SOLVE_Thresj) T1 = 1 << SOLVE_Thresj;\
if (T1 < 0) T1 = 0;\
if (T1 > Pixel[a + b * Pitch].SolvedValue)\
{\
Pixel[a + b * Pitch].SolvedValue = T1;\
StackPos++;\
RecurseBackgroundSolver(&Pixel[a + b * Pitch],&PixelRGB[a + b * Pitch],*PixelRGB,Pitch);\
StackPos--;\
}\
}\
SolverDX -= a ; SolverDY -= b;\
}
static u32 SolverMode = 1;
static u32 StackPos = 0;
static int SolverDX = 0;
static int SolverDY = 0;
void RecurseBackgroundSolver(SolverS *Pixel,s32 *PixelRGB,u32 BaseRGB,s32 Pitch)
{
//if (StackPos > 20) return;
float DistanceLL = (SolverDX * SolverDX + SolverDY * SolverDY);
float DistanceFactor = (5.0f - sqrtf(DistanceLL)) / 2.0f;
if (DistanceFactor > 1.0f) DistanceFactor = 1.0f;
if (DistanceFactor < 0.0f) return;
if (*PixelRGB)
{
PARSE_SOLVE(0,-1);
PARSE_SOLVE(1,0);
PARSE_SOLVE(-1,0);
PARSE_SOLVE(0,1);
/* PARSE_SOLVE(1,+Pitch);
PARSE_SOLVE(1,-Pitch);
PARSE_SOLVE(-1,+Pitch);
PARSE_SOLVE(-1,-Pitch);*/
}
}
s32 L_Limit;
s32 AverageV = 0;
s32 AverageN = 0;
u32 gRED = 0;
#define DEPMAX 20
void RecurseEdgesSolver(s32 *Pixel,s32 Pitch)
{
if (gRED > DEPMAX) return;
AverageV += *Pixel>>2;
AverageN ++;
if (*Pixel & 3) return;
gRED++;
*Pixel |= 1;
#define EDGE_PARSE_SOLVE(a,b) \
if (Pixel[a + b * Pitch] > L_Limit)\
{\
RecurseEdgesSolver(&Pixel[a + b * Pitch],Pitch);\
}
EDGE_PARSE_SOLVE(0,-1);
EDGE_PARSE_SOLVE(1,0);
EDGE_PARSE_SOLVE(-1,0);
EDGE_PARSE_SOLVE(0,1);
gRED--;
}
void RecurseEdgesSolverClose(s32 *Pixel,s32 Pitch)
{
if (gRED > DEPMAX) return;
*Pixel &= ~1;
if (*Pixel & 2) return;
gRED++;
*Pixel |= 2;
#define EDGE_PARSE_CLOSE(a,b) \
if (Pixel[a + b * Pitch] & 1)\
{\
RecurseEdgesSolverClose(&Pixel[a + b * Pitch],Pitch);\
}
EDGE_PARSE_CLOSE(0,-1);
EDGE_PARSE_CLOSE(1,0);
EDGE_PARSE_CLOSE(-1,0);
EDGE_PARSE_CLOSE(0,1);
gRED--;
}
s32 PitchUsed;
s32 StackSize = 0;
u32 ReturnValueHoleSolver = 0;
SolverS *CurrentPixel;
void RecurseBackgroundHoleSolver()
{
//if (StackSize > 4000) return;
StackSize++;
{
#define PARSE_SOLVE_HOLE(a,b) \
CurrentPixel += a + b * PitchUsed;\
if (SolverMode == 1) {\
if (CurrentPixel->SolvedValue == 1) \
{\
CurrentPixel->SolvedValue = 2; \
RecurseBackgroundHoleSolver(); \
}\
}\
if (SolverMode == 2) {\
if (CurrentPixel->SolvedValue == 2) \
{\
CurrentPixel->SolvedValue = 3; \
RecurseBackgroundHoleSolver(); \
}\
}\
CurrentPixel -= a + b * PitchUsed;
PARSE_SOLVE_HOLE(0,-1);
PARSE_SOLVE_HOLE(1,0);
PARSE_SOLVE_HOLE(-1,0);
PARSE_SOLVE_HOLE(0,1);
}
StackSize--;
ReturnValueHoleSolver ++;
}
u32 RecurseConstantSilhouettteSolver(s16 *Pixel,s32 Pitch,u32 ANDValue,u32 OrValue,u32 TEST)
{
u32 Ret = 0;
if (*Pixel & TEST)
{
*Pixel &= ~TEST;
#define PARSE_SOLVE_SILHOUETTE(a,b) \
if (Pixel[a + b * Pitch] & 2) Ret ++; \
if ((Pixel[a + b * Pitch] & TEST)) \
{\
Ret += RecurseConstantSilhouettteSolver(&Pixel[a + b * Pitch],Pitch,ANDValue,OrValue,TEST); \
}
PARSE_SOLVE_SILHOUETTE(0,-1);
PARSE_SOLVE_SILHOUETTE(1,0);
PARSE_SOLVE_SILHOUETTE(-1,0);
PARSE_SOLVE_SILHOUETTE(0,1);
*Pixel &= ANDValue;
*Pixel |= OrValue;
}
return Ret;
}
u32 CompuSetBackGroundErnergy(MAP *CurrentMap,MAP *ZMap,s32 Mode)
{
static MAP16 WorkingMap;
static u32 WorkingBufSize = 0;
static u32 LearningTime = 0;
//return 0;
u32 REs = 0;
u8 TransTable[256];
u8 TransTable2[256];
//return;
MAP16 M1,M2,LEARNINGFRONTEER,M7,M8,NoiseMap;
MAP RGBCUR,RGBFIX,RGBLOCAL;
if (CurrentMap->SX * CurrentMap->SY == 0) return 0;
/**************** Init working maps **************/
if (WorkingBufSize < CurrentMap->SX * CurrentMap->SY)
{
WorkingMap.SetSize(CurrentMap->SX*2, CurrentMap->SY*3, 1);
}
if (Mode == 0)
memset(WorkingMap.GetBase(),0,WorkingBufSize * 6 * 2);
M1.SX = CurrentMap->SX;
M1.SY = CurrentMap->SY;
M1.PITCH = CurrentMap->SX;
NoiseMap = M7= M8 = M2 = LEARNINGFRONTEER = M1;
M1.SetBase(WorkingMap.GetBase());
M2.SetBase(WorkingMap.GetBase() + CurrentMap->SX * CurrentMap->SY);
LEARNINGFRONTEER.SetBase(WorkingMap.GetBase() + CurrentMap->SX * CurrentMap->SY * 2);
M7.SetBase(WorkingMap.GetBase() + CurrentMap->SX * CurrentMap->SY * 3);
M8.SetBase(WorkingMap.GetBase() + CurrentMap->SX * CurrentMap->SY * 4);
NoiseMap.SetBase(WorkingMap.GetBase() + CurrentMap->SX * CurrentMap->SY * 5);
RGBFIX = *CurrentMap; RGBFIX.staticBase = 1;
RGBFIX.SX >>= 1;
RGBFIX.PITCH >>= 1;
RGBFIX.SY >>= 1;
RGBCUR = RGBFIX;
RGBFIX.SetBase((s32*)M7.GetBase());
RGBCUR.SetBase((s32*)M8.GetBase());
MAP O2;
O2 = *CurrentMap; O2.staticBase = 1;
O2.SX >>= 1;
O2.SY >>= 1;
O2.PITCH = RGBCUR.PITCH;
O2.SetBase(RGBCUR.GetBase());
COPY_O2_RGBA(CurrentMap,&O2);
BACK_ComputeGain(&RGBFIX,&O2,&M2);
COPY(&O2,&RGBCUR);
RGBLOCAL = RGBCUR;
RGBLOCAL.SetBase((s32*)M1.GetBase());
LEARNINGFRONTEER.SX >>= 1;
LEARNINGFRONTEER.SY >>= 1;
//MAP16_BLUR_Inplace(&M1,1,1);
// MAP16_Denoise_FAST(&M2,&M1);
//MAP16_Copy(&M2,&M1);
s32 *RGBLOCALBASE = RGBLOCAL.GetBase();
s32 *RGBFIXBASE = RGBFIX.GetBase();
s32 *RGBCURBASE = RGBCUR.GetBase();
s16 *M1BASE = M1.GetBase();
s16 *M2BASE = M2.GetBase();
s32 *O2BASE = O2.GetBase();
s16 *LFBASE = LEARNINGFRONTEER.GetBase();
s16 *NoiseBASE = NoiseMap.GetBase();
s32 *ZMapBASE = NULL;
if (ZMap)
ZMapBASE = ZMap->GetBase();
if (Mode < 15)
{
MAP16_Set(&NoiseMap,0);
MAP16_Set(&LEARNINGFRONTEER,0);
/* Learning mode */
SOLVE_Thresj = 9;
LearningTime = 0;
COPY(&RGBCUR,&RGBFIX);
BigGain = Vector(1,1,1);
} else
{
SET_BORDER(&RGBFIX,4,0);
M2.SX = RGBCUR.SX;
M2.SY = RGBCUR.SY;
Vector BigGainF = BigGain;
Vector BigGainB = Vector(1.0f / BigGain.x,1.0f / BigGain.y,1.0f / BigGain.z);
Vector MAXVec = Vector(1,1,1);
float AlphaGainF = AlphaGain;
float AlphaGainB = 1.0f / AlphaGain;
BigGainB.Max(MAXVec);
BigGainF.Max(MAXVec);
if (AlphaGainF < 1.0f) AlphaGainF = 1.0f;
if (AlphaGainB < 1.0f) AlphaGainB = 1.0f;
for (int Y = 1 ; Y < RGBCUR.SY -1; Y++)
for (int X = 1 ; X < RGBCUR.SX -1; X++)
{
/* RGBDISTANCE */
float RF = (float)((u8 *)&RGBFIXBASE[(X) + (Y) * RGBFIX.PITCH])[0] * BigGainF.x;
float GF = (float)((u8 *)&RGBFIXBASE[(X) + (Y) * RGBFIX.PITCH])[1] * BigGainF.y;
float BF = (float)((u8 *)&RGBFIXBASE[(X) + (Y) * RGBFIX.PITCH])[2] * BigGainF.z;
float AF = (float)((u8 *)&RGBFIXBASE[(X) + (Y) * RGBFIX.PITCH])[3] * AlphaGainF;
float RC = (float)((u8 *)&RGBCURBASE[(X) + (Y) * RGBCUR.PITCH])[0] * BigGainB.x;
float GC = (float)((u8 *)&RGBCURBASE[(X) + (Y) * RGBCUR.PITCH])[1] * BigGainB.y;
float BC = (float)((u8 *)&RGBCURBASE[(X) + (Y) * RGBCUR.PITCH])[2] * BigGainB.z;
float AC = (float)((u8 *)&RGBCURBASE[(X) + (Y) * RGBCUR.PITCH])[3] * AlphaGainB;
if (RF > 255.0f) {RF = 255.f;AF /= 2.f;AC /= 2.0f;};
if (GF > 255.0f) {GF = 255.f;AF /= 2.f;AC /= 2.0f;};
if (BF > 255.0f) {BF = 255.f;AF /= 2.f;AC /= 2.0f;};
if (AF > 255.0f) AF = 255.f;
if (RC > 255.0f) {RC = 255.f;AF /= 2.f;AC /= 2.0f;};
if (GC > 255.0f) {GC = 255.f;AF /= 2.f;AC /= 2.0f;};
if (BC > 255.0f) {BC = 255.f;AF /= 2.f;AC /= 2.0f;};
if (AC > 255.0f) AC = 255.f;
float Distance = 3.0/4.0f*0.925f * ((RF - RC) * (RF - RC) + (GF - GC) * (GF - GC) + (GF - GC) * (GF - GC) + (BF - BC) * (BF - BC) ) + (AF - AC) * (AF - AC) * 1;
float GL = (RF + GF + GF + BF) * 0.25f;
//Distance = ((Distance * GL / 255.0f)*3 + Distance)/4.f;
//float Distance = (AF - AC) * (AF - AC) * 8 ;
if (ZMap)
{
if (((u32 *)ZMapBASE)[X*2 + Y*2 * ZMap->PITCH] == 1)
Distance = 1;
else
if (ZMapBASE[X*2 + Y*2 * ZMap->PITCH])
Distance = 1000000000.0f;
}
/* if ((X == 80) && (Y==60))
Distance = 1000000000.0f;
else
Distance = 0.0f;*/
((SolverS*)&RGBLOCALBASE[X + Y * RGBLOCAL.PITCH])->InitValue = M2BASE[X + Y * M2.PITCH] = 0;
if (Distance > 0)
{
Distance = ((Distance - 1) /1.5f);
if (Distance > 1<<SOLVE_Thresj) Distance = 1<<SOLVE_Thresj;
((SolverS*)&RGBLOCALBASE[X + Y * RGBLOCAL.PITCH])->InitValue = M2BASE[X + Y * M2.PITCH] = Distance;
}
}
if (BLUADDDENOISE)
{
SET_BORDER16(&M2 ,4,0);
MAP16_Add(&M2,BLUADDDENOISE_SUMM);
MAP16_OnlyAbs(&M2);
MAP16_BLUR_Inplace(&M2 , 1, BLUADDDENOISE);
}
/*M1.SX >>= 1;
M1.SY >>= 1;
M1.PITCH >>= 1;
MAP16_Denoise_FAST(&M2,&M1);
MAP16_Copy(&M1,&M2);
M1.SX <<= 1;
M1.SY <<= 1;
M1.PITCH <<= 1;
/*MAP16_Add(&M2,-128);
MAP16_Shift(&M2,1);//*/
//MAP16_BLUR_Inplace(&M2 , 1 , 1);
SET_BORDER16(&M2 ,4,0);
for (int Y = 1 ; Y < RGBLOCAL.SY -1; Y++)
for (int X = 1 ; X < RGBLOCAL.SX -1; X++)
{
if (M2BASE[X + Y * M2.PITCH] > ((SolverS*)&RGBLOCALBASE[X + Y * RGBLOCAL.PITCH])->InitValue)
((SolverS*)&RGBLOCALBASE[X + Y * RGBLOCAL.PITCH])->InitValue = M2BASE[X + Y * M2.PITCH];
((SolverS*)&RGBLOCALBASE[X + Y * RGBLOCAL.PITCH])->SolvedValue = 0;
}
/* Then Recurse Parse */
//COPY(&RGBLOCAL,&RGBCUR);
SET_BORDER(&RGBLOCAL,4,0);
SET_BORDER(&RGBCUR,4,0);
//for (int zK = 0 ; zK < 80 ; zK++)
for (int Y = 2 ; Y < RGBCUR.SY -2; Y++)
for (int X = 2 ; X < RGBCUR.SX -2; X++)
{
if (((SolverS*)&RGBLOCALBASE[X + Y * RGBLOCAL.PITCH])->InitValue >= (1<<(SOLVE_Thresj)) - (1<<(SOLVE_Thresj>>2)))
{
((SolverS*)&RGBLOCALBASE[X + Y * RGBLOCAL.PITCH])->SolvedValue = ((SolverS*)&RGBLOCALBASE[X + Y * RGBLOCAL.PITCH])->InitValue;
}
}
for (int Y = 2 ; Y < RGBCUR.SY -2; Y++)
for (int X = 2 ; X < RGBCUR.SX -2; X++)
{
if (((SolverS*)&RGBLOCALBASE[X + Y * RGBLOCAL.PITCH])->SolvedValue)
{
u32 BaseRGB = RGBCURBASE[X + Y * RGBLOCAL.PITCH];
SolverMode = 1;
RecurseBackgroundSolver(
(SolverS*)&RGBLOCALBASE[X + Y * RGBLOCAL.PITCH],
(s32*)&RGBCURBASE[X + Y * RGBCUR.PITCH],
BaseRGB,RGBLOCAL.PITCH);
}
}
for (int Y = 2 ; Y < RGBCUR.SY -2; Y++)
for (int X = 2 ; X < RGBCUR.SX -2; X++)
{
((SolverS*)&RGBLOCALBASE[X + Y * RGBLOCAL.PITCH])->InitValue = ((SolverS*)&RGBLOCALBASE[X + Y * RGBLOCAL.PITCH])->SolvedValue;
((SolverS*)&RGBLOCALBASE[X + Y * RGBLOCAL.PITCH])->SolvedValue = 0;
M2BASE[X + Y * M2.PITCH] = ((SolverS*)&RGBLOCALBASE[X + Y * RGBLOCAL.PITCH])->InitValue;
}
/*************************************************************************************/
/* Color continuity SOLVER */
/*************************************************************************************/
if (1)
{
// color similarity detection
MAP16_BLUR_Inplace(&M2 , 1 , 3);
for (int Y = 2 ; Y < RGBCUR.SY -2; Y++)
for (int X = 2 ; X < RGBCUR.SX -2; X++)
{
if (M2BASE[X + Y * M2.PITCH] >= (1<<(SOLVE_Thresj))/* - (1<<(SOLVE_Thresj-4))*/)
{
// Recurse Call Solver
((SolverS*)&RGBLOCALBASE[X + Y * RGBLOCAL.PITCH])->SolvedValue = ((SolverS*)&RGBLOCALBASE[X + Y * RGBLOCAL.PITCH])->InitValue;
}
}
for (int Y = 2 ; Y < RGBCUR.SY -2; Y++)
for (int X = 2 ; X < RGBCUR.SX -2; X++)
{
if (M2BASE[X + Y * M2.PITCH] >= (1<<(SOLVE_Thresj)) - (1<<(SOLVE_Thresj-4)))
{
// Recurse Call Solver
((SolverS*)&RGBLOCALBASE[X + Y * RGBLOCAL.PITCH])->SolvedValue = ((SolverS*)&RGBLOCALBASE[X + Y * RGBLOCAL.PITCH])->InitValue;
u32 BaseRGB = RGBCURBASE[X + Y * RGBLOCAL.PITCH];
SolverMode = 2;
RecurseBackgroundSolver(
(SolverS*)&RGBLOCALBASE[X + Y * RGBLOCAL.PITCH],
(s32*)&RGBCURBASE[X + Y * RGBCUR.PITCH],
BaseRGB,RGBLOCAL.PITCH);
}
}
}
COPY(&RGBLOCAL,&RGBCUR);
/*************************************************************************************/
/* HOLES SOLVER */
/*************************************************************************************/
if (1)
{
/* recurse Destroy small Holes (front and back)*/
for(u32 HoleMode = 0 ; HoleMode < 2 ; HoleMode++ )
{
// HoleMode == 0 -> Erase Front,
// HoleMode == 1 -> Erase Back,
SET_BORDER(&RGBCUR,4,0);
for (int Y = 0 ; Y < RGBCUR.SY ; Y++)
for (int X = 0 ; X < RGBCUR.SX ; X++)
((SolverS*)&RGBCURBASE[X + Y * RGBCUR.PITCH])->SolvedValue = 0;
for (int Y = 2 ; Y < RGBCUR.SY - 2 ; Y++)
for (int X = 2 ; X < RGBCUR.SX - 2 ; X++)
if (HoleMode == 1)
{
if (((SolverS*)&RGBCURBASE[X + Y * RGBCUR.PITCH])->InitValue > 32)
(( SolverS*)&RGBCURBASE[X + Y * RGBCUR.PITCH])->SolvedValue = 1;
}
else
{
if ((((SolverS*)&RGBCURBASE[X + Y * RGBCUR.PITCH])->InitValue >= 0) &&
((SolverS*)&RGBCURBASE[X + Y * RGBCUR.PITCH])->InitValue < (1<<(SOLVE_Thresj-1)))
(( SolverS*)&RGBCURBASE[X + Y * RGBCUR.PITCH])->SolvedValue = 1;
}
SET_BORDER(&RGBCUR,4,0);
PitchUsed = RGBCUR.PITCH;
for (int Y = 2 ; Y < RGBCUR.SY -2; Y++)
for (int X = 2 ; X < RGBCUR.SX -2; X++)
{
/* Recurse compute pixel size */
SolverMode = 1;
if (((SolverS*)&RGBCURBASE[X + Y * RGBCUR.PITCH])->SolvedValue == 1)
{
ReturnValueHoleSolver = 0;
CurrentPixel = (SolverS*)&RGBCURBASE[X + Y * RGBCUR.PITCH];
RecurseBackgroundHoleSolver();
if (ReturnValueHoleSolver < 128)
{
SolverMode = 2;
CurrentPixel = (SolverS*)&RGBCURBASE[X + Y * RGBCUR.PITCH];
RecurseBackgroundHoleSolver();
}
}
}
for (int Y = 0 ; Y < RGBCUR.SY ; Y++)
for (int X = 0 ; X < RGBCUR.SX ; X++)
{
if (((SolverS*)&RGBCURBASE[X + Y * RGBCUR.PITCH])->SolvedValue == 3)
{
if (HoleMode == 0)
((SolverS*)&RGBCURBASE[X + Y * RGBCUR.PITCH])->InitValue = 255;
else
((SolverS*)&RGBCURBASE[X + Y * RGBCUR.PITCH])->InitValue = 0;
}
((SolverS*)&RGBCURBASE[X + Y * RGBCUR.PITCH])->SolvedValue = ((SolverS*)&RGBCURBASE[X + Y * RGBCUR.PITCH])->InitValue;
if (((SolverS*)&RGBCURBASE[X + Y * RGBCUR.PITCH])->SolvedValue > 256)
((SolverS*)&RGBCURBASE[X + Y * RGBCUR.PITCH])->SolvedValue = 256;
if (((SolverS*)&RGBCURBASE[X + Y * RGBCUR.PITCH])->SolvedValue < 0)
((SolverS*)&RGBCURBASE[X + Y * RGBCUR.PITCH])->SolvedValue = 0;
M2BASE[X + Y * M2.PITCH] = RGBCURBASE[X + Y * RGBCUR.PITCH] = ((SolverS*)&RGBCURBASE[X + Y * RGBCUR.PITCH])->SolvedValue;
}
}
}
/* Testing Mode */
/*************************************************************************************/
/* BORDER SOLVER */
/*************************************************************************************/
if (1)
{
/* Detect fronteers */
for (int Y = 0 ; Y < RGBCUR.SY ; Y++)
for (int X = 0 ; X < RGBCUR.SX ; X++)
{
if ((RGBCURBASE[X + Y * RGBCUR.PITCH] < 128))
{
M2BASE[X + Y * M2.PITCH] = 256;
} else
M2BASE[X + Y * M2.PITCH] = 0;
}
MAP16_BLUR_Inplace(&M2,1,1);
for (int Y = 0 ; Y < RGBCUR.SY ; Y++)
for (int X = 0 ; X < RGBCUR.SX ; X++)
{
LFBASE[X + Y * LEARNINGFRONTEER.PITCH] >>= 5;
LFBASE[X + Y * LEARNINGFRONTEER.PITCH]-=LFBASE[X + Y * LEARNINGFRONTEER.PITCH]>>6;
if ((M2BASE[X + Y * M2.PITCH] < 256 - 0) && (M2BASE[X + Y * M2.PITCH] > 0))
LFBASE[X + Y * LEARNINGFRONTEER.PITCH]+=256>>6;
else
LFBASE[X + Y * LEARNINGFRONTEER.PITCH]-=LFBASE[X + Y * LEARNINGFRONTEER.PITCH]>>0;
LFBASE[X + Y * LEARNINGFRONTEER.PITCH] <<= 5;
if (LFBASE[X + Y * LEARNINGFRONTEER.PITCH]>>5 >= SILHOUETE_THRESHOLD)
LFBASE[X + Y * LEARNINGFRONTEER.PITCH] |= 16;
else
{
if (M2BASE[X + Y * M2.PITCH] < 128)
LFBASE[X + Y * LEARNINGFRONTEER.PITCH] |= 1;
else
LFBASE[X + Y * LEARNINGFRONTEER.PITCH] |= 2;
}
if (M2BASE[X + Y * M2.PITCH] & 0xff)
{
RGBCURBASE[X + Y * RGBCUR.PITCH]-=M2BASE[X + Y * M2.PITCH];
}
M2BASE[X + Y * M2.PITCH] = RGBCURBASE[X + Y * RGBCUR.PITCH] ;
}
/* Recursive "filling" of shapes wiht constant contour */
SET_BORDER16(&LEARNINGFRONTEER , 2 , 0);
for (int Y = 1 ; Y < LEARNINGFRONTEER.SY-1 ; Y++)
for (int X = 1 ; X < LEARNINGFRONTEER.SX-1 ; X++)
{
if (LFBASE[X + Y * LEARNINGFRONTEER.PITCH] & 1)
{
if (RecurseConstantSilhouettteSolver(&LFBASE[X + Y * LEARNINGFRONTEER.PITCH],LEARNINGFRONTEER.PITCH,0xffffffff,4,1) == 0)
RecurseConstantSilhouettteSolver(&LFBASE[X + Y * LEARNINGFRONTEER.PITCH],LEARNINGFRONTEER.PITCH,0xffffffff,8,4+16);
}
}
/* for (int Y = 0 ; Y < LEARNINGFRONTEER.SY ; Y++)
for (int X = 0 ; X < LEARNINGFRONTEER.SX ; X++)
{
if (LFBASE[X + Y * LEARNINGFRONTEER.PITCH] & 8)
{
LFBASE[X + Y * LEARNINGFRONTEER.PITCH] = SILHOUETE_THRESHOLD<<4;
}
}*/
}
/* Kill Noise; */
static u32 RRR = 1;
if (RRR)
for (int Y = 2 ; Y < NoiseMap.SY-2 ; Y++)
for (int X = 2 ; X < NoiseMap.SX-2 ; X++)
{
u32 LastWas1 = NoiseBASE[X + Y * NoiseMap.PITCH]&1;
NoiseBASE[X + Y * NoiseMap.PITCH] -= NoiseBASE[X + Y * NoiseMap.PITCH]>>3;
NoiseBASE[X + Y * NoiseMap.PITCH] &= ~1;
if (M2BASE[X + Y * M2.PITCH] > 128)
{
if (!LastWas1) NoiseBASE[X + Y * NoiseMap.PITCH] += 1024;
{
NoiseBASE[X + Y * NoiseMap.PITCH] += 1;
}
}
else
{
if (LastWas1)
{
NoiseBASE[X + Y * NoiseMap.PITCH] += 1024;
}
}
if (NoiseBASE[X + Y * NoiseMap.PITCH] > VIBE_THRESH)
{
REs++;
M2BASE[X + Y * M2.PITCH] = 0;
}
}
/* finishing */
#define _PITCH M1.PITCH
for (int Y = 0 ; Y < M1.SY ; Y++)
for (int X = 0 ; X < M1.SX ; X++)
{
/* RGBDISTANCE */
if (X & 1)
{
M1BASE[X + Y * M1.PITCH] = (
M2BASE[(X>>1) + (Y>>1) * M2.PITCH] +
M2BASE[(X>>1) + 1 + (Y>>1) * M2.PITCH])>>1;
} else
M1BASE[X + Y * M1.PITCH] = M2BASE[(X>>1) + (Y>>1) * M2.PITCH];
if (Y & 1)
{
if (X & 1)
{
M1BASE[X + Y * M1.PITCH] += (
M2BASE[(X>>1) + ((Y>>1)+1) * M2.PITCH] +
M2BASE[(X>>1) + 1 + ((Y>>1)+1) * M2.PITCH])>>1;
} else
M1BASE[X + Y * M1.PITCH] += M2BASE[(X>>1) + ((Y>>1)+1) * M2.PITCH];
M1BASE[X + Y * M1.PITCH]>>=1;
}
/*if (M1BASE[X + Y * M1.PITCH] < 128) M1BASE[X + Y * M1.PITCH] = 0;
else M1BASE[X + Y * M1.PITCH] = 255;*/
if (M1BASE[X + Y * M1.PITCH] < 0) M1BASE[X + Y * M1.PITCH] = 0;
if (M1BASE[X + Y * M1.PITCH] > 255)
{
M1BASE[X + Y * M1.PITCH] = 255;
}
}
}
/* Compute Noise Mesure NoiseMesure*/
MAP16_2_MAP(&M1,CurrentMap,24);
/* *********************************************************************************************** */
/* LEARNING BACKGROUND */
/* *********************************************************************************************** */
if (0)
{
COPY_O2_RGBA_ENERGY(CurrentMap,&O2);
BACK_ComputeBack(&RGBFIX,&O2,&LEARNINGFRONTEER,&M2);
/* DEBUG RESULT SHOW*/
#ifdef BACK_DEBUG_INFO
COPY(&RGBFIX,&O2);
for (int X = 4 ; X < O2.SX - 4; X++)
for (int Y = 4 ; Y < O2.SY - 4; Y++)
{
if (LFBASE[X + Y * LEARNINGFRONTEER.PITCH] & 8)
{
O2BASE[X + Y * O2.PITCH] = 0xff0000;
}
/* if (LFBASE[X + Y * LEARNINGFRONTEER.PITCH] & 2)
{
O2BASE[X + Y * O2.PITCH] = 0xff00;
}*/
if (LFBASE[X + Y * LEARNINGFRONTEER.PITCH]>>5 > SILHOUETE_THRESHOLD>>1)
O2BASE[X + Y * O2.PITCH] = 0xff00;
else
if (LFBASE[X + Y * LEARNINGFRONTEER.PITCH]>>5)
{
O2BASE[X + Y * O2.PITCH] = 0xff;
//LFBASE[X + Y * LEARNINGFRONTEER.PITCH] = 0;
}//*/
O2BASE[X + Y * O2.PITCH] |= 0xff000000;
}
COPY(&O2,CurrentMap);
#endif
}
/*
COPY(&RGBFIX,&O2);
for (int X = 4 ; X < O2.SX - 4; X++)
for (int Y = 4 ; Y < O2.SY - 4; Y++)
{
s16 Value = M2BASE[X + Y * M2.PITCH];
if (Value > 255) Value = 255;
O2BASE[X + Y * O2.PITCH] = 0;
if (Value > 128)
{
Value -= 128;
Value <<= 1;
O2BASE[X + Y * O2.PITCH] += Value<<8;
O2BASE[X + Y * O2.PITCH] += Value<<16;
O2BASE[X + Y * O2.PITCH] ^= 0xff00;
} else
{
Value <<= 1;
O2BASE[X + Y * O2.PITCH] += Value<<8;
O2BASE[X + Y * O2.PITCH] += Value<<0;
O2BASE[X + Y * O2.PITCH] ^= 0xff;
}
O2BASE[X + Y * O2.PITCH] |= 0xff000000;
}
COPY(&O2,CurrentMap);
//*/
#ifdef BACK_DEBUG_INFO_TEXT
char DEDEDE[1024];
sprintf(DEDEDE,"%d",REs);
DRawTEXT_Soft_B((u8*)DEDEDE,(u32*)CurrentMap->GetBase(),16, 32, CurrentMap->PITCH, CurrentMap->SY, 0xff00f0f0);
#endif
LearningTime++;
if (LearningTime < 30)
{
if ((LearningTime > 15) && ((LearningTime & 3) == 0)&& (REs > 80) && (SOLVE_Thresj < 12))
{
SOLVE_Thresj++;
}
return 512;
} else
return 0;
}