JD2022-TU1/main/extern/Camcam/HeadTracker/INTERP.cpp

435 lines
No EOL
14 KiB
C++

#include "memory.h"
#include "HeadTracker.h"
#include "stdlib.h"
#include "math.h"
#define DRAW_DEBUG
#define MAX_POINTS_INTERP 2000
#define SEARCHWINDOW1 10
#define SEARCHWINDOW2 20
#define BLUR_RADIUS 1
#define NUMBER_OF_TEST 128
#define COMPARATOR_PATCHSIZE 19
#define SMALLEST_DISTANCE (NUMBER_OF_TEST * 0.25f)
#define DENOISE_DISTANCE 2
#define DENOISE_FACTOR 0.7
u32 IMAGESIZEX = -1;
u32 IMAGESIZEY = 480;
#define H_TABLE_SIZEX 40
#define H_TABLE_SIZEY 30
u32 H_TABLE_P[H_TABLE_SIZEX*H_TABLE_SIZEY*2];
u32 H_TABLE_C[H_TABLE_SIZEX*H_TABLE_SIZEY*2];
#ifdef DRAW_DEBUG
#define MAX_LINE (4096)
u32 LINE_TABLE[MAX_LINE*5];
u32 LINE_TABLE_i = 0;
#endif
static char COMP_BitTable[256];
static void COMP_BitTableInit()
{
u32 RTet;
if (COMP_BitTable[128] == 1) return;
if (COMP_BitTable[65] == 2) return;
RTet = 256;
while (RTet--)
{
u32 Local;
COMP_BitTable[RTet] = 0 ;
Local = RTet;
while (Local)
{
COMP_BitTable[RTet] += Local & 1;
Local >>= 1;
}
}
}
static u32 COMP_BitNum(u32 K)
{
u32 RTet;
RTet = COMP_BitTable[K & 0xff];
RTet += COMP_BitTable[(K>>8) & 0xff];
RTet += COMP_BitTable[(K>>16) & 0xff];
RTet += COMP_BitTable[(K>>24) & 0xff];
return RTet ;
}
s32 Comparator[1024];
void Init_Comparator(MAP16 *PithcMap)
{
static u32 Counter = 0;
if (Counter == PithcMap->PITCH) return;
for (Counter = 0;Counter<1024;Counter+=2)
{
s32 XC,YC;
float Alpha;
XC = (rand()%COMPARATOR_PATCHSIZE) - (COMPARATOR_PATCHSIZE>>1);
YC = (rand()%COMPARATOR_PATCHSIZE) - (COMPARATOR_PATCHSIZE>>1);
Comparator[Counter] = YC * PithcMap->PITCH + XC;
Alpha = (float)(rand()&65535) * 3.1415927f * 2.0f / 65536.0f;
XC += (s32)(cos(Alpha) * 5.0f);
YC += (s32)(sin(Alpha) * 5.0f);
/* XC = (rand()%COMPARATOR_PATCHSIZE) - (COMPARATOR_PATCHSIZE>>1);
YC = (rand()%COMPARATOR_PATCHSIZE) - (COMPARATOR_PATCHSIZE>>1);//*/
Comparator[Counter+1] = YC * PithcMap->PITCH + XC;
}
Counter = PithcMap->PITCH;
}
static float GET_AverageColor(s16 *BaseIT,u32 Pitch)
{
float Ret;
Ret = (float)*BaseIT;
return Ret * 1.0f / ((BLUR_RADIUS * 2 + 1)*(BLUR_RADIUS * 2 + 1));
}
void GetBitM(s16 *BaseIT,TRACKEDPOINT *P1,MAP16 *CI)
{
u32 Counter ;
s32 *ComparatorPtr;
ComparatorPtr = Comparator;
P1->AreaMask[0] = P1->AreaMask[1] = P1->AreaMask[2] = P1->AreaMask[3] /*=
P1->AreaMask[4] = P1->AreaMask[5] = P1->AreaMask[6] = P1->AreaMask[7] */= 0;
Counter = NUMBER_OF_TEST;
while (Counter--)
{
u32 test;
if (BaseIT[*ComparatorPtr]>BaseIT[*(ComparatorPtr+1)])
test = 1;
else
test = 0;
P1->AreaMask[Counter>>5] |= test<<(Counter&31);
ComparatorPtr+=2;
}
}
u32 Match2P(TRACKEDPOINT *P1,TRACKEDPOINT *P2)
{
return COMP_BitNum(P1->AreaMask[0] ^ P2->AreaMask[0]) +
COMP_BitNum(P1->AreaMask[1] ^ P2->AreaMask[1]) +
COMP_BitNum(P1->AreaMask[2] ^ P2->AreaMask[2]) +
COMP_BitNum(P1->AreaMask[3] ^ P2->AreaMask[3])/* +
COMP_BitNum(P1->AreaMask[4] ^ P2->AreaMask[4]) +
COMP_BitNum(P1->AreaMask[5] ^ P2->AreaMask[5]) +
COMP_BitNum(P1->AreaMask[6] ^ P2->AreaMask[6]) +
COMP_BitNum(P1->AreaMask[7] ^ P2->AreaMask[7])*/;
}
void GET_LISTE_FROM_BOX(u32 *LisBox, s32 XMIN,s32 YMIN,s32 XMAX,s32 YMAX,TRACKEDPOINT *Points,u32 *H_TABLE)
{
u32 XMi,XMa,YMi,X,YMa;
if (XMIN < 0) XMIN = 0;
if (YMIN < 0) YMIN = 0;
if (XMAX < 0) XMAX = 0;
if (YMAX < 0) YMAX = 0;
XMi = (XMIN * H_TABLE_SIZEX) / IMAGESIZEX;
YMi = (YMIN * H_TABLE_SIZEY) / IMAGESIZEY;
XMa = (XMAX * H_TABLE_SIZEX) / IMAGESIZEX + 1;
YMa = (YMAX * H_TABLE_SIZEY) / IMAGESIZEY + 1;
if (XMi) XMi--;
if (YMi) YMi--;
if (XMa > H_TABLE_SIZEX) XMa = H_TABLE_SIZEX;
if (YMa > H_TABLE_SIZEY) YMa = H_TABLE_SIZEY;
if (XMi > H_TABLE_SIZEX) XMi = H_TABLE_SIZEX;
if (YMi > H_TABLE_SIZEY) YMi = H_TABLE_SIZEY;
*(LisBox) = -1;
for (;YMi < YMa;YMi++)
{
for (X = XMi;X < XMa;X++)
{
u32 iN;
iN = H_TABLE[YMi*H_TABLE_SIZEX + X];
while (iN != -1)
{
*(LisBox++) = iN;
iN = Points[iN].NextIndex;
}
}
}
*(LisBox++) = -1;
}
u32 LisBox[MAX_POINTS_INTERP];
u32 LisBox2[MAX_POINTS_INTERP];
u32 GetMatchFromList(u32 *LisBox,TRACKEDPOINT *ToMatch,TRACKEDPOINT *BigList)
{
s32 SmallDistance,Distance;
s32 Matched = -1;
SmallDistance = SMALLEST_DISTANCE;
while (*LisBox != -1)
{
{
Distance = Match2P(ToMatch,BigList + *LisBox);
if (Distance < SmallDistance)
{
Matched = *LisBox;
SmallDistance = Distance;
}
}
LisBox++;
}
return Matched;
}
u32 ImProbTable[1024];
void MATCH_2_FRAMES(
u32 CurrentNUMBER,
TRACKEDPOINT *CURRENT_ALLXYW,
u32 PreviousNUMBER,
TRACKEDPOINT *PREVIOUS_ALLXYW,
MAP16 *CURRENTIMAGE,
MAP *DRAWINFOIMAGE,
u32 DrawDebug,
float *MatchingPercent)
{
COMP_BitTableInit();
Init_Comparator(CURRENTIMAGE);
memset(ImProbTable,0,sizeof(ImProbTable));
#ifdef DRAW_DEBUG
float FDX,FDY;
FDX = (float)DRAWINFOIMAGE->SX / (float)CURRENTIMAGE->SX;
FDY = (float)DRAWINFOIMAGE->SY / (float)CURRENTIMAGE->SY;
#endif
for (u32 i = 0 ; i < CurrentNUMBER ; i ++)
{
CURRENT_ALLXYW[i].PreviousIndex = 0xffffffff;
CURRENT_ALLXYW[i].NextIndex = 0xffffffff;
s16 *BaseIT = CURRENTIMAGE->GetBase() + (((u32)CURRENT_ALLXYW[i].X)) + (((u32)CURRENT_ALLXYW[i].Y)) * CURRENTIMAGE->PITCH;
CURRENT_ALLXYW[i].TrackingTime = 0;
}
if (CurrentNUMBER > MAX_POINTS_INTERP) CurrentNUMBER = MAX_POINTS_INTERP;
for (u32 i = 0 ; i < H_TABLE_SIZEX*H_TABLE_SIZEY ; i ++)
{
H_TABLE_C[i] = -1;
}
for (u32 i = 0 ; i < H_TABLE_SIZEX*H_TABLE_SIZEY ; i ++)
{
H_TABLE_P[i] = -1;
}
for (u32 i = 0 ; i < CurrentNUMBER ; i ++)
{
u32 x,y;
x = (u32)((H_TABLE_SIZEX * CURRENT_ALLXYW[i].X) / CURRENTIMAGE->SX);
y = (u32)((H_TABLE_SIZEY * CURRENT_ALLXYW[i].Y) / CURRENTIMAGE->SY);
CURRENT_ALLXYW[i].NextIndex = H_TABLE_C[x + (y*H_TABLE_SIZEX)];
H_TABLE_C[x + (y*H_TABLE_SIZEX)] = i;
s16 *BaseIT = CURRENTIMAGE->GetBase() + (((u32)CURRENT_ALLXYW[i].X)) + (((u32)CURRENT_ALLXYW[i].Y)) * CURRENTIMAGE->PITCH;
GetBitM(BaseIT,&CURRENT_ALLXYW[i],CURRENTIMAGE);
}
u32 SpeedKillNum = 0;
for (u32 i = 0 ; i < PreviousNUMBER ; i ++)
{
u32 x,y;
x = (u32)((H_TABLE_SIZEX * PREVIOUS_ALLXYW[i].X) / CURRENTIMAGE->SX);
y = (u32)((H_TABLE_SIZEY * PREVIOUS_ALLXYW[i].Y) / CURRENTIMAGE->SY);
PREVIOUS_ALLXYW[i].NextIndex = H_TABLE_P[x + (y*H_TABLE_SIZEX)];
H_TABLE_P[x + (y*H_TABLE_SIZEX)] = i;
}
if (IMAGESIZEX != -1)
{
for (u32 CurrentParser = 0 ; CurrentParser < CurrentNUMBER ; CurrentParser ++)
{
u32 i,j,Matched,Matched2;
s32 SmallDistance,Distance;
s32 SmallDistance2,Distance2;
s32 XSmallDistance,XDistance;
s32 XSmallDistance2,XDistance2;
Matched = -1;
SmallDistance = SMALLEST_DISTANCE;
XSmallDistance = SMALLEST_DISTANCE;
if (CURRENT_ALLXYW[CurrentParser].PreviousIndex != 0xffffffff) continue;
GET_LISTE_FROM_BOX(LisBox, (s32)(CURRENT_ALLXYW[CurrentParser].X - SEARCHWINDOW1 ), (s32)(CURRENT_ALLXYW[CurrentParser].Y - SEARCHWINDOW1),(s32)(CURRENT_ALLXYW[CurrentParser].X + SEARCHWINDOW1 ), (s32)(CURRENT_ALLXYW[CurrentParser].Y + SEARCHWINDOW1),PREVIOUS_ALLXYW,H_TABLE_P);
Matched = GetMatchFromList(LisBox,CURRENT_ALLXYW + CurrentParser,PREVIOUS_ALLXYW);
if (Matched != -1)
{
GET_LISTE_FROM_BOX(LisBox2, (s32)(PREVIOUS_ALLXYW[Matched].X - SEARCHWINDOW1 ), (s32)(PREVIOUS_ALLXYW[Matched].Y - SEARCHWINDOW1),(s32)(PREVIOUS_ALLXYW[Matched].X + SEARCHWINDOW1 ), (s32)(PREVIOUS_ALLXYW[Matched].Y + SEARCHWINDOW1),CURRENT_ALLXYW,H_TABLE_C);
Matched2 = GetMatchFromList(LisBox2,PREVIOUS_ALLXYW + Matched,CURRENT_ALLXYW);
if (Matched2 != CurrentParser) Matched = -1;
}
if (Matched == -1)
{
GET_LISTE_FROM_BOX(LisBox, (s32)(CURRENT_ALLXYW[CurrentParser].X - SEARCHWINDOW2 ), (s32)(CURRENT_ALLXYW[CurrentParser].Y - SEARCHWINDOW2),(s32)(CURRENT_ALLXYW[CurrentParser].X + SEARCHWINDOW2 ), (s32)(CURRENT_ALLXYW[CurrentParser].Y + SEARCHWINDOW2),PREVIOUS_ALLXYW,H_TABLE_P);
Matched = GetMatchFromList(LisBox,CURRENT_ALLXYW + CurrentParser,PREVIOUS_ALLXYW);
if (Matched != -1)
{
GET_LISTE_FROM_BOX(LisBox2, (s32)(PREVIOUS_ALLXYW[Matched].X - SEARCHWINDOW2 ), (s32)(PREVIOUS_ALLXYW[Matched].Y - SEARCHWINDOW2),(s32)(PREVIOUS_ALLXYW[Matched].X + SEARCHWINDOW2 ), (s32)(PREVIOUS_ALLXYW[Matched].Y + SEARCHWINDOW2),CURRENT_ALLXYW,H_TABLE_C);
Matched2 = GetMatchFromList(LisBox2,PREVIOUS_ALLXYW + Matched,CURRENT_ALLXYW);
if (Matched2 != CurrentParser) Matched = -1;
}
}
if (Matched != -1)
{
CURRENT_ALLXYW[CurrentParser].TrackingTime = PREVIOUS_ALLXYW[Matched].TrackingTime + 1;
if (CURRENT_ALLXYW[CurrentParser].TrackingTime > 4)
{
CURRENT_ALLXYW[CurrentParser].PreviousIndex = Matched;
CURRENT_ALLXYW[CurrentParser].TrackedDistance =
sqrtf(
(CURRENT_ALLXYW[CurrentParser].X - PREVIOUS_ALLXYW[Matched].X) * (CURRENT_ALLXYW[CurrentParser].X - PREVIOUS_ALLXYW[Matched].X) +
(CURRENT_ALLXYW[CurrentParser].Y - PREVIOUS_ALLXYW[Matched].Y) * (CURRENT_ALLXYW[CurrentParser].Y - PREVIOUS_ALLXYW[Matched].Y)
);
if (CURRENT_ALLXYW[CurrentParser].TrackedDistance < 1024.0f*1.0f)
{
u32 Index;
Index = (u32)(CURRENT_ALLXYW[CurrentParser].TrackedDistance /1.0f);
ImProbTable[Index] ++;
ImProbTable[Index + 1] ++;
if (Index)
ImProbTable[Index - 1] ++;
}
}
else
{
// if (CURRENT_ALLXYW[CurrentParser].TrackingTime > 2)
SpeedKillNum ++;
#ifdef DRAW_DEBUG
if (DrawDebug)
DrawQuadFull(DRAWINFOIMAGE,(CURRENT_ALLXYW[CurrentParser].X*FDX-1) , (CURRENT_ALLXYW[CurrentParser].Y*FDY-1),(CURRENT_ALLXYW[CurrentParser].X*FDX+1) , (CURRENT_ALLXYW[CurrentParser].Y*FDY+1),0xff0000);//*/
#endif
}
}
#ifdef DRAW_DEBUG
else
{
if (DrawDebug)
DrawQuadFull(DRAWINFOIMAGE,(CURRENT_ALLXYW[CurrentParser].X*FDX-1) , (CURRENT_ALLXYW[CurrentParser].Y*FDY-1),(CURRENT_ALLXYW[CurrentParser].X*FDX+1) , (CURRENT_ALLXYW[CurrentParser].Y*FDY+1),0xff00);//*/
}
#endif
}
}
IMAGESIZEX = CURRENTIMAGE->SX;
IMAGESIZEY = CURRENTIMAGE->SY;
if (CurrentNUMBER > 200)
for (u32 CurrentParser = 0 ; CurrentParser < CurrentNUMBER ; CurrentParser ++)
{
if (CURRENT_ALLXYW[CurrentParser].PreviousIndex != 0xffffffff)
{
if (CURRENT_ALLXYW[CurrentParser].TrackedDistance < 1024.0f*1.0f)
if (ImProbTable[(u32)(CURRENT_ALLXYW[CurrentParser].TrackedDistance /1.0f)] <= 10)
{
CURRENT_ALLXYW[CurrentParser].PreviousIndex = -1;
SpeedKillNum++;
if (DrawDebug)
DrawQuadFull(DRAWINFOIMAGE,(CURRENT_ALLXYW[CurrentParser].X*FDX-2) , (CURRENT_ALLXYW[CurrentParser].Y*FDY-2),(CURRENT_ALLXYW[CurrentParser].X*FDX+2) , (CURRENT_ALLXYW[CurrentParser].Y*FDY+2),0xff00ff);
}
}
}
//*/
memcpy(H_TABLE_P,H_TABLE_C,sizeof(H_TABLE_P));
for (u32 i = 0 ; i < PreviousNUMBER ; i ++)
{
PREVIOUS_ALLXYW[i].NextIndex = 0xffffffff;
}
u32 MatchNumber = 0;
for (u32 i = 0 ; i < CurrentNUMBER ; i ++)
{
if (CURRENT_ALLXYW[i].PreviousIndex != 0xffffffff)
{
PREVIOUS_ALLXYW[CURRENT_ALLXYW[i].PreviousIndex].NextIndex = i;
float DX = (CURRENT_ALLXYW[i].X - PREVIOUS_ALLXYW[CURRENT_ALLXYW[i].PreviousIndex].X);
float DY = (CURRENT_ALLXYW[i].Y - PREVIOUS_ALLXYW[CURRENT_ALLXYW[i].PreviousIndex].Y);
if (DX * DX + DY * DY < DENOISE_DISTANCE * DENOISE_DISTANCE)
{
CURRENT_ALLXYW[i].X = CURRENT_ALLXYW[i].X * (1-DENOISE_FACTOR) + PREVIOUS_ALLXYW[CURRENT_ALLXYW[i].PreviousIndex].X * (DENOISE_FACTOR);
CURRENT_ALLXYW[i].Y = CURRENT_ALLXYW[i].Y * (1-DENOISE_FACTOR) + PREVIOUS_ALLXYW[CURRENT_ALLXYW[i].PreviousIndex].Y * (DENOISE_FACTOR);
}//*/
MatchNumber++;
}
}
#ifdef DRAW_DEBUG
if (DrawDebug)
{
for (u32 CurrentParser = 0 ; CurrentParser < CurrentNUMBER ; CurrentParser ++)
{
u32 Matched = CURRENT_ALLXYW[CurrentParser].PreviousIndex;
if (Matched != -1)
{
LINE_TABLE[LINE_TABLE_i++] = PREVIOUS_ALLXYW[Matched].X;
LINE_TABLE[LINE_TABLE_i++] = PREVIOUS_ALLXYW[Matched].Y;
LINE_TABLE[LINE_TABLE_i++] = CURRENT_ALLXYW[CurrentParser].X;
LINE_TABLE[LINE_TABLE_i++] = CURRENT_ALLXYW[CurrentParser].Y;
LINE_TABLE[LINE_TABLE_i++] = 0;
if (LINE_TABLE_i == MAX_LINE*5)
LINE_TABLE_i = 0;
DrawQuadFull(DRAWINFOIMAGE,(CURRENT_ALLXYW[CurrentParser].X*FDX-1),(CURRENT_ALLXYW[CurrentParser].Y*FDY-1),(CURRENT_ALLXYW[CurrentParser].X*FDX +2), (CURRENT_ALLXYW[CurrentParser].Y*FDY+2),0xff);
}
}
for (u32 i = 0 ; i < MAX_LINE ; i ++)
{
if (LINE_TABLE[i*5+4] < 15)
DrawLine(DRAWINFOIMAGE,
(LINE_TABLE[i*5+0])*FDX,(LINE_TABLE[i*5+1])*FDY,(LINE_TABLE[i*5+2])*FDX,(LINE_TABLE[i*5+3])*FDY,0xff0000);
LINE_TABLE[i*5+4]++;
}
}
#endif
*MatchingPercent = 100.0f;
if (CurrentNUMBER)
*MatchingPercent = 100.0f*(float)(MatchNumber+SpeedKillNum) / (float)CurrentNUMBER;
}
void MATCH_2_FRAMES_WSPC(WORKINGSPACE *WSPC)
{
MAP16 BlurredMazp;
MAP32_COPY(WSPC->Current_WSP->SRC_BW,WSPC->WORK[0]);
BlurredMazp.SetBase((s16*)WSPC->WORK[0]->GetBase());
BlurredMazp.PITCH = BlurredMazp.SX = WSPC->WORK[0]->SX;
BlurredMazp.SY = WSPC->WORK[0]->SY;
/* Copy */
u32 Counter = BlurredMazp.SY*BlurredMazp.SX;
s16 *Mdst = BlurredMazp.GetBase();
s32 *MSrc = WSPC->Current_WSP->SRC_BW->GetBase();
while(Counter--) *(Mdst++) = (s16)*(MSrc++);
MAP16_BLUR_Inplace(&BlurredMazp, BLUR_RADIUS +1, 1);
//LF_GaussianFilter(WSPC->Current_WSP->SRC_BW,WSPC->WORK[0],WSPC->WORK[1],BLUR_RADIUS,1);
MATCH_2_FRAMES( WSPC->Current_WSP->nTps,
WSPC->Current_WSP->TPS,
WSPC->Previous_WSP->nTps,
WSPC->Previous_WSP->TPS,
&BlurredMazp,//WSPC->WORK[0],//WSPC->Current_WSP->SRC_BW,
WSPC->RENDERMAP,
WSPC->DrawDebug,
&WSPC->INTERP_MatchingPercent);//*/
/*Mdst = BlurredMazp.BASE + BlurredMazp.SX * BlurredMazp.SY;MSrc = WSPC->Current_WSP->SRC_BW->GetBase() + WSPC->Current_WSP->SRC_BW->SX * WSPC->Current_WSP->SRC_BW->SY;
Counter = BlurredMazp.SY*BlurredMazp.SX;
while(Counter--) *(--MSrc) = (s32)*(--Mdst);
//memset(WSPC->WORK[0]->GetBase() , 0 , WSPC->WORK[0]->SY * WSPC->WORK[0]->PITCH * 4 );
//*/
MAP32_COPY(WSPC->Current_WSP->SRC_BW,WSPC->WORK[0]);
}