#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< 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; }