JD2022-TU1/main/extern/Camcam/Tools/Feature.cpp

694 lines
No EOL
14 KiB
C++

#include "SCENE.h"
#define NumberOfSign 8
#define NumberOfSignU32 ((NumberOfSign+31)>>5)
#define MAXAREARADIUS 4
#define BitcRadius 5
static u32 NumberOfCleanLoop = 1;
static u32 PostBlur = 0x203;
static u32 treshnoi = 40;
s32 BitSignOffsets_BASE[NumberOfSign * 4];
s32 BitSignOffsets_PITCHED[NumberOfSign * 2];
void BITEXAND(MAP *MapDST)
{
u32 *LAST,*DST;
DST = (u32*)MapDST->GetBase();
for (u32 SizeY = 0; SizeY < MapDST->SY;SizeY ++)
{
u32 Current;
LAST = DST + MapDST->SX;
Current = 0;
while (DST < LAST)
{
*(DST) &= 0xff;
*(DST) |= (*DST & 0xcc)<<6;
*(DST) |= (*DST & 0x2222)<<15;
*(DST) &= 0x11111111;
DST++;
}
DST+=MapDST->PITCH-MapDST->SX;
}
}
void BITCONTRACT(MAP *MapDST)
{
u32 *LAST,*DST;
DST = (u32*)MapDST->GetBase();
for (u32 SizeY = 0; SizeY < MapDST->SY;SizeY ++)
{
u32 Current;
LAST = DST + MapDST->SX;
Current = 0;
while (DST < LAST)
{
//*(DST) |= (*(DST) & 0x44444444)<<1;
*(DST) >>= 3;
*(DST) &= 0x11111111;
*(DST) |= (*DST & 0x11110000)>>15;
*(DST) |= (*DST & 0x3300)>>6;
*(DST) &= 0xff;
DST++;
}
DST+=MapDST->PITCH-MapDST->SX;
}
}
void OR(MAP *MapSRC,MAP *MapDST)
{
u32 *LAST,*DST,*SRC;
DST = (u32*)MapDST->GetBase();
SRC = (u32*)MapSRC->GetBase();
for (u32 SizeY = 0; SizeY < MapDST->SY;SizeY ++)
{
LAST = DST + MapDST->SX;
while (DST < LAST)
{
*(DST) |= *(SRC);
DST++;
SRC++;
}
DST+=MapDST->PITCH-MapDST->SX;
SRC+=MapSRC->PITCH-MapSRC->SX;
}
}
void MINIMUM(MAP *MapSRC,MAP *MapDST)
{
s32 *LAST,*DST,*SRC;
DST = (s32*)MapDST->GetBase();
SRC = (s32*)MapSRC->GetBase();
for (u32 SizeY = 0; SizeY < MapDST->SY;SizeY ++)
{
LAST = DST + MapDST->SX;
while (DST < LAST)
{
if (*(DST) > *(SRC)) *(DST) = *(SRC);
DST++;
SRC++;
}
DST+=MapDST->PITCH-MapDST->SX;
SRC+=MapSRC->PITCH-MapSRC->SX;
}
}
void MAXIMUM(MAP *MapSRC,MAP *MapDST)
{
s32 *LAST,*DST,*SRC;
DST = (s32*)MapDST->GetBase();
SRC = (s32*)MapSRC->GetBase();
for (u32 SizeY = 0; SizeY < MapDST->SY;SizeY ++)
{
LAST = DST + MapDST->SX;
while (DST < LAST)
{
if (*(DST) < *(SRC)) *(DST) = *(SRC);
DST++;
SRC++;
}
DST+=MapDST->PITCH-MapDST->SX;
SRC+=MapSRC->PITCH-MapSRC->SX;
}
}
void AFFECT(MAP *MapSRC,MAP *MapDST,u32 Thresh)
{
s32 *LAST,*DST,*SRC;
DST = MapDST->GetBase();
SRC = MapSRC->GetBase();
for (u32 SizeY = 0; SizeY < MapDST->SY;SizeY ++)
{
u32 Current;
LAST = DST + MapDST->SX - 2;
Current = 0;
while (DST < LAST)
{
if (*(DST)==0) *(DST) = *(SRC);
DST++;
SRC++;
}
DST+=MapDST->PITCH-MapDST->SX;
SRC+=MapSRC->PITCH-MapSRC->SX;
}
}
void DENOISE(MAP *MapDST,s32 TT)
{
s32 *LAST,*DST,*SRC;
DST = (s32*)MapDST->GetBase();
for (u32 SizeY = 0; SizeY < MapDST->SY;SizeY ++)
{
LAST = DST + MapDST->SX;
while (DST < LAST)
{
u32 K;
if (*DST > 0)
*DST = (2<<16)+*DST;//-*DST;
else
*DST = (1<<16)-*DST;//*/
DST++;
}
DST+=MapDST->PITCH-MapDST->SX;
}
}
typedef struct _BitSign
{
u32 Bitfiled[NumberOfSignU32];
} BitSign;
void GetBitSignature(s32 *Base,BitSign *BF)
{
u32 NOSU32 = 0;
u32 *BitF = BF->Bitfiled;
s32 *BSOP = BitSignOffsets_PITCHED,*BSOPLAST;
BSOPLAST = BSOP+NumberOfSign*2;
memset(BF,0,sizeof(BitSign));
while(BSOP < BSOPLAST)
{
*BitF = (*BitF<<1) + ((((u32)(*(Base + BSOP[0]) + treshnoi - *(Base + BSOP[1])))>>31));
BSOP += 2;
NOSU32 ++;
BitF += NOSU32>>5;
NOSU32 &= 31;
}
if (NumberOfSign & 31)
*BitF &= ((1<<(NumberOfSign&31)) - 1);
}
u32 GetBitCP(s32 *Base1,s32 *Base2,s32 Pitch)
{
u32 NOSU32 = 0;
s32 FX,FY;
/* Normalize */
float Average1,Average2;
Average1 = Average2 = 0.0f;
for (FX = -BitcRadius;FX < BitcRadius ; FX++)
for (FY = -BitcRadius;FY < BitcRadius ; FY++)
{
s32 LCP;
s32 DLT;
DLT = FX + FY * Pitch;
Average1 = (float)*(Base1 + DLT);
Average2 = (float)*(Base2 + DLT);
}
float Norm1,Norm2;
Average1 /= (float)(BitcRadius*BitcRadius*4);
Average2 /= (float)(BitcRadius*BitcRadius*4);
Norm1 = Norm2 = 0.0f;
for (FX = -BitcRadius;FX < BitcRadius ; FX++)
for (FY = -BitcRadius;FY < BitcRadius ; FY++)
{
s32 LCP;
s32 DLT;
DLT = FX + FY * Pitch;
Norm1 += abs(((float)*(Base1 + DLT) - Average1));
Norm2 += abs(((float)*(Base2 + DLT) - Average2));;
}
Norm1 /= (float)(BitcRadius*BitcRadius*4);
Norm2 /= (float)(BitcRadius*BitcRadius*4);
Norm1 = 256.0f / (Norm1+0.0000001f);
Norm2 = 256.0f / (Norm2+0.0000001f);
/* Compare */
for (FX = -BitcRadius;FX < BitcRadius ; FX++)
for (FY = -BitcRadius;FY < BitcRadius ; FY++)
{
s32 LCP;
s32 DLT;
DLT = FX + FY * Pitch;
LCP = (s32)(Norm1 * ((float)*(Base1 + DLT)-Average1) - Norm2 * ((float)*(Base2 + DLT)-Average2));
NOSU32 += abs(LCP);
}
return NOSU32 / (BitcRadius*BitcRadius*4);
}
u32 GetBitDotProduct(BitSign *BF1,BitSign *BF2)
{
u32 *BSDP1 = BF1->Bitfiled;
u32 *BSDP2 = BF2->Bitfiled;
u32 *BSOP1LAST = BSDP1 + NumberOfSignU32;
u32 Result = 0;
while(BSDP1 < BSOP1LAST)
{
Result += GetBitNumber(*BSDP1 ^ *BSDP2);
BSDP1++;
BSDP2++;
}
return Result;
}
//u32 Correspondance1Error[1<<NumberOfSign];
//static u32 Histograme[1<<NumberOfSign];
static u32 DOit = 1;
void ALIAS(MAP *MapSRC,MAP *MapDST)
{
s32 *LAST,*DST,*SRC;
#define AFFECTMiMa(a) if (Min > a) Min = a;if (Max < a) Max = a;
#define R0 2
#define R1 4
for (u32 SizeY = R1; SizeY < MapDST->SY-R1;SizeY ++)
{
DST = MapDST->GetBase() + MapDST->PITCH * SizeY + R1;
SRC = MapSRC->GetBase() + MapSRC->PITCH * SizeY + R1;
LAST = DST + (MapDST->SX) - R1*2;
while (DST < LAST)
{
s32 Min,Max,Val;
Max = Min = *(SRC);
AFFECTMiMa(*(SRC - MapSRC->PITCH * R0));
AFFECTMiMa(*(SRC - MapSRC->PITCH * R0+ R0));
AFFECTMiMa(*(SRC - MapSRC->PITCH * R0- R0));
AFFECTMiMa(*(SRC + MapSRC->PITCH * R0- R0));
AFFECTMiMa(*(SRC - R0));//*/
AFFECTMiMa(*(SRC + R0));
AFFECTMiMa(*(SRC + MapSRC->PITCH * R0));
AFFECTMiMa(*(SRC + MapSRC->PITCH * R0+ R0));
if ((Max - Min)<15)
*DST = 0;
else
{
Max = Min = *(SRC);
AFFECTMiMa(*(SRC - MapSRC->PITCH * R1));
AFFECTMiMa(*(SRC - MapSRC->PITCH * R1+ R1));
AFFECTMiMa(*(SRC - MapSRC->PITCH * R1- R1));
AFFECTMiMa(*(SRC + MapSRC->PITCH * R1- R1));
AFFECTMiMa(*(SRC - R1));//*/
AFFECTMiMa(*(SRC + R1));
AFFECTMiMa(*(SRC + MapSRC->PITCH * R1));
AFFECTMiMa(*(SRC + MapSRC->PITCH * R1+ R1));
if (*SRC>(Max + Min)>>1)
*DST = (2<<16)+(Max - Min);
else
*DST = (1<<16)+(Max - Min);
}
//*DST = Val;
DST++;
SRC++;
}
}
}
#define RADAND 3
void SPECIALAND(u32 *T,u32 Pitch, u32 And)
{
T -= RADAND + RADAND * Pitch;
u32 Cx,Cy;
Cy = RADAND * 2 + 1;
while (Cy--)
{
Cx = RADAND * 2 + 1;
while (Cx--)
{
*T &= And;
T++;
}
T -= RADAND * 2 + 1;
T += Pitch;
}
}
void FIND_SQUELETTON(MAP *MapDST,MAP *MapTMP)
{
s32 *LAST,*DST,*TMP;
s32 X,Y;
SET(MapTMP,0);
for (Y = 1; Y < MapDST->SY-1;Y ++)
{
DST = MapDST->GetBase() + MapDST->PITCH * Y + 1;
TMP = MapTMP->GetBase() + MapTMP->PITCH * Y + 1;
LAST = DST + MapDST->SX - 2;
X = 1;
while (DST < LAST)
{
s32 A,B;
if ((!(*DST & (4<<16))) /*|| ((*DST&0xffff)<25)*/)
{
//#define DOTMODE
#ifdef DOTMODE
s16 *P1,*P2;
P1 = (s16 *)(TMP-1);
P2 = (s16 *)(TMP-MapTMP->PITCH);
/* if (((s32)(X-P1[0])*(s32)(X-P1[0]) + (s32)(Y-P1[1])*(s32)(Y-P1[1])) <
((s32)(X-P2[0])*(s32)(X-P2[0]) + (s32)(Y-P2[1])*(s32)(Y-P2[1])))*/
if ((abs(X-P1[0]) + abs(Y-P1[1])) <
(abs(X-P2[0]) + abs(Y-P2[1])))
*TMP = *(TMP-1);
else
*TMP = *(TMP-MapTMP->PITCH);
#else
s32 KO,KL,KOO,KOL;
KO = *(TMP-1) + 100;
KL = *(TMP-MapTMP->PITCH) + 100;
KOO = *(TMP-MapTMP->PITCH+1) + 141;
KOL = *(TMP-MapTMP->PITCH-1) + 141;
if (KOO > KOL)
KOO = KOL;
if (KO > KOO)
KO = KOO;
if (KO > KL)
*TMP = KL;
else
*TMP = KO;
#endif
} else
{
#ifdef DOTMODE
s16 *P;
P = (s16 *)TMP;
P[0] = X;
P[1] = Y;
#else
*TMP = 0;
#endif
}
TMP++;
DST++;
X++;
}
}
for (Y = MapDST->SY-1; Y > 1;Y --)
{
LAST = MapDST->GetBase() + MapDST->PITCH * Y + 1;
TMP = MapTMP->GetBase() + MapTMP->PITCH * Y + MapDST->SX - 1;
DST = LAST + MapDST->SX - 2;
X = MapDST->SX - 1;
while (DST > LAST)
{
s32 A,B;
if ((!(*DST & (4<<16))) /*|| ((*DST&0xffff)<25)*/)
{
#ifdef DOTMODE
s16 *P0,*P1,*P2;
s32 D0,D1,D2;
P0 = (s16 *)(TMP);
P1 = (s16 *)(TMP+1);
P2 = (s16 *)(TMP+MapTMP->PITCH);
D0 = abs(X-P0[0]) + abs(Y-P0[1]);
D1 = abs(X-P1[0]) + abs(Y-P1[1]);
D2 = abs(X-P2[0]) + abs(Y-P2[1]);
if ((D0 > D1) || (D0 > D2))
{
if (D1 < D2)
*TMP = *(TMP+1);
else
*TMP = *(TMP+MapTMP->PITCH);
}
#else
s32 KO,KL,KOO,KOL;
KO = *(TMP+1) + 100;
KL = *(TMP+MapTMP->PITCH) + 100;
if (KO > KL)
KO = KL;
KOO = *(TMP+MapTMP->PITCH+1) + 141;
KOL = *(TMP+MapTMP->PITCH-1) + 141;
if (KOO > KOL)
KOO = KOL;
if (KO > KOO)
KO = KOO;
if (*TMP > KO)
*TMP = KO;
#endif
} else
{
#ifdef DOTMODE
s16 *P;
P = (s16 *)TMP;
P[0] = X;
P[1] = Y;
#else
*TMP = 0;
#endif
}
TMP--;
DST--;
X--;
}
}//*/
for (Y = 4; Y < MapDST->SY-4;Y ++)
{
DST = MapDST->GetBase() + MapDST->PITCH * Y + 4;
TMP = MapTMP->GetBase() + MapTMP->PITCH * Y + 4;
LAST = DST + MapDST->SX - 8;
X = 1;
while (DST < LAST)
{
s32 A,B;
#define MINITSQUE 540*8
#define MINITSQUERAD 1
#ifdef DOTMODE
s16 *P1,*P2;
P1 = (s16 *)(TMP);
P2 = (s16 *)(TMP+1);
/*if (//(((s32)(X-P1[0])*(s32)(X-P1[0]) + ((s32)(Y-P1[1])*(s32)(Y-P1[1]))) < 5*5) &&
(((s32)(X-P1[0])*(s32)(X-P1[0]) + ((s32)(Y-P1[1])*(s32)(Y-P1[1]))) > 1*1))//*/
{
if (((s32)(X-P1[0])*(s32)(X-P2[0]) + ((s32)(Y-P1[1])*(s32)(Y-P2[1]))) < -1)
*DST |= 8<<16;
P2 = (s16 *)(TMP+MapTMP->PITCH);
if (((s32)(X-P1[0])*(s32)(X-P2[0]) + ((s32)(Y-P1[1])*(s32)(Y-P2[1]))) < -1)
*DST |= 8<<16;//*/
}
#else
s32 D0,D1,DM;
DM = *(TMP+1);
D1 = *(TMP-1);
if (D1 > DM) DM = D1;
D1 = *(TMP+MapTMP->PITCH);
if (D1 > DM) DM = D1;
D1 = *(TMP-MapTMP->PITCH);
if (D1 > DM) DM = D1;
D1 = *(TMP-1-MapTMP->PITCH);
if (D1 > DM) DM = D1;
D1 = *(TMP+1-MapTMP->PITCH);
if (D1 > DM) DM = D1;
D1 = *(TMP-1+MapTMP->PITCH);
if (D1 > DM) DM = D1;
D1 = *(TMP+1+MapTMP->PITCH);
if (D1 > DM) DM = D1;
if ((DM - *(TMP) < 80))
{
if (*(TMP) <= 300)
{
*DST |= 8<<16;
SPECIALAND((u32*)DST,MapDST->PITCH, ~(4<<16));
}//*/
/*else
*DST |= 16<<16;*/
}
#endif
X++;
TMP++;
DST++;
}
}
}
void COPY_SHOW(MAP *MapSRC,MAP *MapDST)
{
s32 *LAST,*DST,*SRC;
DST = MapDST->GetBase();
SRC = MapSRC->GetBase();
for (u32 SizeY = 0; SizeY < MapSRC->SY;SizeY ++)
{
LAST = DST + MapDST->SX;
while (DST < LAST)
{
s32 A;
A = *(SRC);/*
if (A & (2<<16))
*(DST) = 0x8000;
if (A & (1<<16))
*(DST) = 0x80;//*/
if (A & (4<<16))
*(DST) = 0x1F0000;//*/
else
if (A & (8<<16))
*(DST) = 0x1F00;
/*else
if (A & (256<<16))
*(DST) = 0x1F00;//*/
/* else
if (A & (16<<16))
*(DST) = 0x1F;*/
else
{
//*(DST) = (*(DST) & 0xfefefefe)>>1;//*/
//*(DST) += 0xfefefefe>>1;//*/
}
DST++;
SRC++;
}
SRC+=MapSRC->PITCH-MapSRC->SX;
DST+=MapDST->PITCH-MapDST->SX;
}
}
void COMPLEXSPACE(MAP *CurrentMap)
{
static MAP WorkingMap;
static u32 WorkingBufSize = 0;
MAP M1,M2,M3,M4,M5;
if (CurrentMap->SX * CurrentMap->SY == 0) return;
/**************** Init working maps **************/
if (WorkingBufSize < 512 + (CurrentMap->SX + 16)* CurrentMap->SY)
{
WorkingMap.SetSize(CurrentMap->SX, CurrentMap->SY, 1);
}
M1 = M2 = M3 = M4 = M5 = *CurrentMap;
M3.PITCH = M2.PITCH = M1.PITCH = CurrentMap->SX;
M1.SetBase(WorkingMap.GetBase());
M2.SetBase(WorkingMap.GetBase() + CurrentMap->SX * CurrentMap->SY);
M3.SetBase(WorkingMap.GetBase() + CurrentMap->SX * CurrentMap->SY * 2);
M4.SetBase(WorkingMap.GetBase() + CurrentMap->SX * CurrentMap->SY * 3);
M5.SetBase(WorkingMap.GetBase() + CurrentMap->SX * CurrentMap->SY * 4);
/* DENOISE TEST */
#if 1
COPY(CurrentMap,&M1);
COPY_BW(CurrentMap,CurrentMap);
SHIFT(CurrentMap,2);
/*
COPY(CurrentMap,&M2);
LF_GaussianFilter(CurrentMap,&M4,&M3,2,10);
//LF_GaussianFilter(&M4,CurrentMap,&M3,2,3);
// LF_GaussianFilter(CurrentMap,&M4,&M3,2,3);
SUB(&M4,CurrentMap);
//NEG(CurrentMap);
ADD_VALUE(CurrentMap,128);
COPY_RGBA(CurrentMap,&M1);*/
ALIAS(CurrentMap,&M2);
COPY(&M2,CurrentMap);
DARKER(&M1);
NON_ZERO(CurrentMap,&M2);
COPY(&M2,CurrentMap);
FIND_SQUELETTON(CurrentMap,&M2);
COPY_SHOW(CurrentMap,&M1);
COPY(&M1,CurrentMap);
return;//*/
#else
//*/
COPY(CurrentMap,&M1);
COPY_BW(CurrentMap,CurrentMap);
//LF_GaussianFilter(CurrentMap,CurrentMap,&M3,0,2);
SHIFT(CurrentMap,2);
COPY_O2(CurrentMap,CurrentMap);
COPY_O2(CurrentMap,CurrentMap);//*/
//MAX(&M4,&M3);//*/
//MIN(&M3,&M4);//*/
//COPY(&M3,&M4);
MAX(CurrentMap,&M2);
MIN(CurrentMap,&M4);
SUB(&M2,&M4);//*/
/* COPY_GRADIENT(CurrentMap,&M2);
MAX(&M2,&M4);//*/
/* Gaussan method */
/*LF_GaussianFilter(CurrentMap,&M2,&M3,0,3);
LF_GaussianFilter(&M2,&M2,&M3,0,3);
SUB(&M2,CurrentMap);//*/
/* Maxmin Method */
MAX(CurrentMap,&M2);
MAX(&M2,&M5);
MAX(&M5,&M2);//*/
MIN(CurrentMap,&M3);
MIN(&M3,&M5);
MIN(&M5,&M3);//*/
ADD(&M2,&M3);
SHIFT(&M3,1);
SUB(&M3,CurrentMap);//*/
//return;
{
s32 *LAST,*DST,*GRAD,*NOISE;
DST = CurrentMap->GetBase();
GRAD = M4.GetBase();
for (u32 SizeY = 0; SizeY < CurrentMap->SY;SizeY ++)
{
LAST = DST + CurrentMap->SX;
while (DST < LAST)
{
u32 K;
if (*DST > 0)
*DST = (2<<16)+*GRAD;//-*DST;
else
*DST = (1<<16)+*GRAD;//*/
DST++;
GRAD++;
}
DST+=CurrentMap->PITCH-CurrentMap->SX;
GRAD+=M4.PITCH-M4.SX;
}
}
#endif
DARKER(&M1);
DARKER(&M1);
/* DARKER(&M1);
DARKER(&M1);*/
//SET(&M1,0);
NON_ZERO(CurrentMap,&M2);
COPY(&M2,CurrentMap);//*/
extern void VECTORIZE_MAP(MAP *MapSRC,MAP *MapDST);
//AFFECT(&M1,CurrentMap,0);
COPY(&M1,CurrentMap);
VECTORIZE_MAP(&M2,CurrentMap);
// COPY(&M2,CurrentMap);
AFFECT(&M2,CurrentMap,0);
//OR(&M2,CurrentMap);
}
void DETECT_FEATURES(MAP *CurrentMap)
{
extern void Viola2(MAP *CurrentMap,u32 Color);
Viola2(CurrentMap,0);
return;
}