730 lines
15 KiB
C++
730 lines
15 KiB
C++
#include "SCENE.h"
|
||
#include "HOUGH.H"
|
||
|
||
#define BACKFILTERING
|
||
#define POWERACC_SHIFT 8
|
||
#ifdef BACKFILTERING
|
||
#define POWERACC() CurrentV += ((s32)*SRC) << POWERACC_SHIFT;
|
||
#define POWERDEC() {CurrentV /= 3;/*(CurrentV >> 2) + (CurrentV >> 4) ;CurrentV += (CurrentV >> 4);*/};
|
||
#define POWERAFFECT() {*SRC = (s16)((((s32)*SRC)<<0) - (*DST>>POWERACC_SHIFT-0));}
|
||
#else
|
||
#define POWERACC() CurrentV += ((s32)*SRC) << POWERACC_SHIFT;
|
||
#define POWERDEC() {CurrentV /= 3;};
|
||
#define POWERAFFECT() {*SRC -= (s16)(*DST>>POWERACC_SHIFT);*SRC <<= 0;}
|
||
#endif
|
||
|
||
s32 MAP16_Threshold(MAP16 *MapDST,u32 Value)
|
||
{
|
||
s16 *LAST,*DST;
|
||
s32 Max = 0;
|
||
if (!Value) return 0;
|
||
/* MM H */
|
||
DST = MapDST->GetBase();
|
||
for (u32 SizeY = 0; SizeY < MapDST->SY;SizeY ++)
|
||
{
|
||
s32 CX = 0;
|
||
LAST = DST + MapDST->SX;
|
||
while (DST < LAST)
|
||
{
|
||
if (abs(*DST) > Value)
|
||
{
|
||
Max++;
|
||
/*if (*DST > 0)
|
||
*DST = 500;
|
||
else
|
||
*DST = -500;//*/
|
||
} else
|
||
*DST = 0;//*/
|
||
CX++;
|
||
DST++;
|
||
}
|
||
DST += MapDST->PITCH - MapDST->SX;
|
||
}
|
||
Max = (float)Max * 100.0f / ((float)MapDST->SX * (float)MapDST->SY);
|
||
return Max;
|
||
}
|
||
|
||
|
||
void MAP16_FastHoughQuadran_V(MAP16 *MapSRC,MAP16 *MapDST,u32 Po2,u32 InverseMode)
|
||
{
|
||
s16 *SRC,*SRC2,*DST,*LAST,*LASTY;
|
||
DST = MapDST->GetBase() ;
|
||
s32 Max = (s32)MapDST->SY & ~((1<<Po2)-1);
|
||
for (s32 SizeY = 0; SizeY < Max;SizeY += 2)
|
||
{
|
||
u32 Index2;
|
||
u32 ILocal,LBase;
|
||
s16 *DSTSave;
|
||
LAST = DST + MapDST->SX;
|
||
DSTSave = DST;
|
||
LBase = SizeY & ~(((2<<Po2))-1);
|
||
ILocal = SizeY - LBase;
|
||
SRC = MapSRC->GetBase() + (LBase + (ILocal>>1)) * MapSRC->PITCH;
|
||
SRC2 = MapSRC->GetBase() + (LBase + (ILocal>>1) + (1<<Po2)) * MapSRC->PITCH;
|
||
Index2 = ILocal>>1;
|
||
while (DST < LAST)
|
||
{
|
||
if (InverseMode)
|
||
{
|
||
*DST = (*SRC + SRC2[Index2])>>0;
|
||
Index2 ++;
|
||
Index2 &= MapSRC->SX-1;
|
||
*(DST + MapDST->PITCH) = (*SRC + SRC2[Index2])>>0;
|
||
} else
|
||
{
|
||
*DST = (*SRC + SRC2[Index2])>>1;
|
||
Index2 ++;
|
||
Index2 &= MapSRC->SX-1;
|
||
*(DST + MapDST->PITCH) = (*SRC + SRC2[Index2])>>1;
|
||
}
|
||
DST++;
|
||
SRC++;
|
||
}
|
||
|
||
DST+=MapDST->PITCH-MapDST->SX;
|
||
DST+=MapDST->PITCH;
|
||
}
|
||
}
|
||
|
||
|
||
void MAP16_SwapLines(s16 *pSrc,s16 *pDst,s32 Lenght)
|
||
{
|
||
while (Lenght--)
|
||
{
|
||
s16 Swp;
|
||
Swp = *pSrc;
|
||
*(pSrc++) = *pDst;
|
||
*(pDst++) = Swp;
|
||
}
|
||
}
|
||
void MAP16_RotateLine(s16 *pSrc,s32 Rot,s32 Lenght,u32 CyclicMode)
|
||
{
|
||
s16 CpyL[2048];
|
||
// In place shift 16 bits horizontaly
|
||
memcpy(CpyL,pSrc,Lenght*2);
|
||
memcpy(pSrc,CpyL+Rot,(Lenght-Rot)*2);
|
||
if (CyclicMode)
|
||
memcpy(pSrc+(Lenght-Rot),CpyL,Rot*2);
|
||
else
|
||
{
|
||
s16 Value = 0;
|
||
s32 Counter = Rot;
|
||
pSrc+=(Lenght-Rot);
|
||
//Value = *pSrc;
|
||
while (Counter--) *(pSrc++) = Value;
|
||
}
|
||
}
|
||
|
||
|
||
|
||
void MAP16_FastHoughQuadran_Inplace(MAP16 *MapDST,u32 Po2,u32 Cyclemode,u32 Invert)
|
||
{
|
||
s16 *DST,*DST2,*LAST;
|
||
s32 Max = (s32)MapDST->SY & ~((1<<Po2)-1);
|
||
/* 1 Shift Lines ***************************************************************************/
|
||
s32 VPos = 2<<Po2;
|
||
if (VPos>2)
|
||
{
|
||
DST = MapDST->GetBase() ;
|
||
for (s32 SizeY = 0; SizeY < MapDST->SY;SizeY++)
|
||
{
|
||
s32 LocalPos = SizeY & (VPos-1);
|
||
LocalPos ^= (VPos-1);
|
||
if (LocalPos > (VPos>>1))
|
||
{
|
||
LocalPos-=VPos>>1;
|
||
MAP16_RotateLine(DST,LocalPos,MapDST->SX,Cyclemode);
|
||
}
|
||
DST += MapDST->PITCH;
|
||
}
|
||
}
|
||
/* 2 Swap lines *************************************************************************** */
|
||
VPos = 4;
|
||
while (VPos <= 2<<Po2)
|
||
{
|
||
LAST = MapDST->GetBase() + MapDST->PITCH * MapDST->SY;
|
||
DST = MapDST->GetBase() ;
|
||
DST2 = DST + MapDST->PITCH * ((VPos>>1)-1);
|
||
for (s32 SizeY = 0; SizeY < MapDST->SY;SizeY++)
|
||
{
|
||
s32 LocalPos = SizeY & (VPos-1);
|
||
if ((LocalPos < VPos>>1) && (LocalPos & 1))/* Swap Lines */MAP16_SwapLines(DST,DST2,MapDST->SX);
|
||
DST += MapDST->PITCH;
|
||
DST2 += MapDST->PITCH;
|
||
//if (DST2 >= LAST) SizeY = MapDST->SY;
|
||
|
||
}
|
||
VPos <<= 1;
|
||
}
|
||
|
||
/* 3 Radon trans *************************************************************************/
|
||
DST = MapDST->GetBase() ;
|
||
for (s32 SizeY = 0; SizeY < Max;SizeY += 2)
|
||
{
|
||
s16 A,B,DSTSave0,DSTSave1;
|
||
|
||
LAST = DST + MapDST->SX -1;
|
||
DST2 = DST + MapDST->PITCH;
|
||
if (Cyclemode)
|
||
{
|
||
DSTSave0 = *(DST);
|
||
DSTSave1 = *(DST2);
|
||
} else
|
||
{
|
||
DSTSave0 = 0;
|
||
DSTSave1 = 0;
|
||
}
|
||
|
||
if (1)
|
||
{
|
||
while (DST < LAST)
|
||
{
|
||
A = (*(DST2) + *(DST) ) ;
|
||
B = (*(DST2) + *(DST+1) ) ;
|
||
*(DST2++) = A>>1;
|
||
*(DST++) = B>>1;
|
||
}
|
||
A = (*(DST2) + *(DST)) ;
|
||
B = (DSTSave0 + *(DST2));
|
||
*(DST2++) = A>>1;
|
||
*(DST++) = B>>1;
|
||
} else
|
||
{
|
||
while (DST < LAST)
|
||
{
|
||
A = (*(DST2) + *(DST) ) - (*(DST+1));
|
||
B = (*(DST2) + *(DST+1) ) - (*(DST));
|
||
*(DST2++) = A>>1;
|
||
*(DST++) = B>>1;
|
||
}
|
||
A = (*(DST2) + *(DST)) - (DSTSave0);
|
||
B = (DSTSave0 + *(DST2))-(DSTSave1);
|
||
*(DST2++) = A>>1;
|
||
*(DST++) = B>>1;
|
||
}
|
||
|
||
DST+=MapDST->PITCH-MapDST->SX;
|
||
DST+=MapDST->PITCH;
|
||
}
|
||
}
|
||
|
||
|
||
|
||
|
||
void MAP16_HOUGHPostFilter(MAP16 *MapSRC,HOUGHParram *pFlags)
|
||
{
|
||
s16 *LAST,*SRC;
|
||
s32 *DST;
|
||
s32 Accum[2048];
|
||
/* MM H */
|
||
|
||
for (u32 SizeY = 0; SizeY < MapSRC->SY ;SizeY ++)
|
||
{
|
||
s32 CurrentV;
|
||
if (pFlags->POSTFILTERING)
|
||
{
|
||
DST = Accum;
|
||
SRC = MapSRC->GetBase()+SizeY*MapSRC->PITCH;
|
||
LAST = SRC + MapSRC->SX;
|
||
memset(DST, 0 , sizeof(Accum[0]) * (MapSRC->SX+1));
|
||
CurrentV = 0;
|
||
#ifdef BACKFILTERING
|
||
|
||
while (SRC < LAST)
|
||
{
|
||
POWERACC();
|
||
POWERDEC();
|
||
*DST += CurrentV;
|
||
SRC++;
|
||
DST++;
|
||
}
|
||
SRC -= MapSRC->SX;
|
||
DST -= MapSRC->SX;
|
||
while (SRC < LAST)
|
||
{
|
||
POWERDEC();
|
||
*DST += CurrentV;
|
||
SRC++;
|
||
DST++;
|
||
}
|
||
#else
|
||
SRC += MapSRC->SX;
|
||
DST += MapSRC->SX;
|
||
#endif
|
||
CurrentV = 0;
|
||
|
||
LAST -= MapSRC->SX;
|
||
while (SRC > LAST)
|
||
{
|
||
SRC--;
|
||
DST--;
|
||
POWERACC();
|
||
POWERDEC();
|
||
*DST += CurrentV;
|
||
}
|
||
SRC += MapSRC->SX;
|
||
DST += MapSRC->SX;
|
||
while (SRC > LAST)
|
||
{
|
||
SRC--;
|
||
DST--;
|
||
POWERDEC();
|
||
*DST += CurrentV;
|
||
}
|
||
LAST += MapSRC->SX;
|
||
while (SRC < LAST)
|
||
{
|
||
POWERAFFECT();
|
||
SRC++;
|
||
DST++;
|
||
}
|
||
|
||
SRC = MapSRC->GetBase()+SizeY*MapSRC->PITCH;
|
||
SRC[0] = 0;
|
||
SRC[1] = 0;
|
||
SRC[2] = 0;
|
||
SRC[3] = 0;
|
||
SRC[MapSRC->SX-1] = 0;
|
||
SRC[MapSRC->SX-2] = 0;
|
||
SRC[MapSRC->SX-3] = 0;
|
||
SRC[MapSRC->SX-4] = 0;
|
||
}
|
||
if (pFlags->COMPUTE_LAPLACIAN)
|
||
{
|
||
DST = Accum;
|
||
SRC = MapSRC->GetBase()+SizeY*MapSRC->PITCH;
|
||
LAST = SRC + MapSRC->SX;
|
||
*(DST) = 0;//(*(SRC + MapSRC->SX - 1) + *(SRC + 1))>>1;
|
||
*(DST + MapSRC->SX - 1) = 0;//(*(SRC + MapSRC->SX - 2) + *(SRC))>>1;
|
||
DST++;
|
||
SRC++;
|
||
while (SRC < LAST-1)
|
||
{
|
||
*DST = (*(SRC -1) + *(SRC + 1))>>1;
|
||
SRC++;
|
||
DST++;
|
||
}
|
||
SRC -= MapSRC->SX - 1;
|
||
DST -= MapSRC->SX - 1;
|
||
while (SRC < LAST)
|
||
{
|
||
*SRC -= *DST;
|
||
if (*SRC > pFlags->LimitUp) *SRC = pFlags->LimitUp;
|
||
if (*SRC < -pFlags->LimitUp) *SRC = -pFlags->LimitUp;
|
||
*SRC <<= pFlags->PRE_LAPLACIAN_SHIFT;
|
||
SRC++;
|
||
DST++;
|
||
}
|
||
SRC -= MapSRC->SX;
|
||
DST -= MapSRC->SX;
|
||
}
|
||
|
||
}
|
||
}
|
||
//#pragma optimize("",off)
|
||
void MAP16_HOUGHCosEnvellppe(MAP16 *MapSRC,HOUGHParram *pFlags)
|
||
{
|
||
s16 *LAST,*SRC;
|
||
s32 *DST;
|
||
float Factor[2048];
|
||
u32 Size = 1<<pFlags->SubWindowShift;
|
||
if (Size > MapSRC->SY) Size = MapSRC->SY;
|
||
for (int i = 0 ; i < Size ; i ++)
|
||
{
|
||
Factor[i] = (1.0f - cos(2.0f * 3.1415927f * ((float)i / (float)Size))) / 2.0f;
|
||
}
|
||
/* MM H */
|
||
SRC = MapSRC->GetBase();
|
||
for (u32 SizeY = 0; SizeY < MapSRC->SY ;SizeY ++)
|
||
{
|
||
LAST = SRC+MapSRC->SX;
|
||
float fFactor = Factor[SizeY & ((1<<pFlags->SubWindowShift)-1)] ;
|
||
|
||
while (SRC < LAST)
|
||
{
|
||
*(SRC++) = (s16)((float)*SRC*fFactor);
|
||
}
|
||
SRC += MapSRC->PITCH - MapSRC->SX;
|
||
}
|
||
}
|
||
|
||
|
||
void MAP16_HOUGHZeroCrossing(MAP16 *MapSRC, s32 ZC)
|
||
{
|
||
s16 *LAST,*SRC;
|
||
s32 *DST;
|
||
s32 Accum[2048];
|
||
/* MM H */
|
||
|
||
for (u32 SizeY = 0; SizeY < MapSRC->SY ;SizeY ++)
|
||
{
|
||
DST = Accum + 2;
|
||
SRC = MapSRC->GetBase()+SizeY*MapSRC->PITCH;
|
||
Accum[1] = SRC[MapSRC->SX];
|
||
Accum[0] = SRC[MapSRC->SX - 1];
|
||
Accum[MapSRC->SX + 2] = SRC[0];
|
||
Accum[MapSRC->SX + 3] = SRC[1];
|
||
LAST = SRC + MapSRC->SX;
|
||
while (SRC < LAST)
|
||
{
|
||
*DST = *SRC;
|
||
SRC++;
|
||
DST++;
|
||
}
|
||
SRC -= MapSRC->SX;
|
||
DST -= MapSRC->SX;
|
||
while (SRC < LAST)
|
||
{
|
||
if (*SRC > ZC)
|
||
{
|
||
if ((*(DST+1)<-ZC) || (*(DST-1)<-ZC)
|
||
//|| (*(DST+2)<0) || (*(DST-2)<0)
|
||
)
|
||
{}
|
||
else
|
||
*SRC = 0;
|
||
} else
|
||
if (*SRC < -ZC)
|
||
{
|
||
if ((*(DST+1)>ZC) ||(*(DST-1)>ZC)
|
||
//|| (*(DST+2)>0) ||(*(DST-2)>0)
|
||
)
|
||
{}
|
||
else
|
||
*SRC = 0;
|
||
} else
|
||
*SRC = 0;
|
||
SRC++;
|
||
DST++;
|
||
}
|
||
SRC -= MapSRC->SX;
|
||
DST -= MapSRC->SX;
|
||
}
|
||
}
|
||
|
||
|
||
void MAP16_HOUGHDivide0And45(MAP16 *MapSRC,u32 SubWindow)
|
||
{
|
||
s16 *LAST,*SRC;
|
||
SRC = MapSRC->GetBase();
|
||
for (u32 SizeY = 0; SizeY < MapSRC->SY ;SizeY ++, SRC += MapSRC->PITCH)
|
||
{
|
||
if (((SizeY & SubWindow) == 0) || ((SizeY & SubWindow) == SubWindow))
|
||
{
|
||
LAST = SRC + MapSRC->SX;
|
||
while (SRC < LAST)
|
||
{
|
||
*(SRC++)>>=1;
|
||
}
|
||
SRC -= MapSRC->SX;
|
||
}
|
||
|
||
}
|
||
}
|
||
|
||
|
||
|
||
void FAST_HOUGH(MAP16 *pSrc,MAP16 *pTmp,HOUGHParram *FLAGS)
|
||
{
|
||
MAP16 Local;
|
||
if (FLAGS->INVERSE)
|
||
{
|
||
pSrc->SX >>= 1;
|
||
pSrc->SY >>= 1;
|
||
|
||
/* Clean */
|
||
if (FLAGS->CLEAN)
|
||
{
|
||
Local = *pSrc; Local.staticBase = 1;
|
||
Local.MoveBase(Local.SX);
|
||
Local.SY<<=1;
|
||
MAP16_FLIP_V(&Local);
|
||
Local = *pSrc;
|
||
Local.SX<<=1;
|
||
MAP16_FLIP_V(&Local);
|
||
}
|
||
|
||
|
||
} else
|
||
{
|
||
if (FLAGS->COMPUTE_O2) MAP16_XO2(pSrc);
|
||
pSrc->SX >>= 1;
|
||
if (FLAGS->COMPUTE_O2) MAP16_YO2(pSrc);
|
||
pSrc->SY >>= 1;
|
||
if (FLAGS->SEPARATE_QUADRANTS)
|
||
{
|
||
Local = *pSrc; Local.staticBase = 1;
|
||
Local.MoveBase(pSrc->SX);
|
||
MAP16_BLUR_CopyTransposeFAST(pSrc,&Local);
|
||
Local.MoveBase(-pSrc->SX);
|
||
pSrc->SX <<= 1;
|
||
Local.SX <<= 1;
|
||
Local.MoveBase(pSrc->SY * pSrc->PITCH);
|
||
MAP16_CopyFlipV(pSrc,&Local);
|
||
pSrc->SX >>= 1;
|
||
Local.SX >>= 1;
|
||
}
|
||
}
|
||
|
||
|
||
|
||
if (pTmp)
|
||
{
|
||
if (!FLAGS->INPLACE) MAP16_Set(pTmp,0);
|
||
pTmp->SX>>=1;
|
||
pTmp->SY>>=1;
|
||
}
|
||
|
||
for (u32 QCounter = 0 ; QCounter < 4 ; QCounter ++ )
|
||
{
|
||
Local = *pSrc; Local.staticBase = 1;
|
||
if (QCounter & 1) Local.MoveBase(Local.SX);
|
||
if (QCounter & 2) Local.MoveBase(Local.SY*Local.PITCH);
|
||
s32 MAXLIM = Local.SX <= 1<<FLAGS->SubWindowShift ? Local.SX : 1<<FLAGS->SubWindowShift;
|
||
|
||
if (FLAGS->INVERSE)
|
||
{
|
||
MAP16_FLIP_H(&Local);
|
||
|
||
if (FLAGS->CLEAN)
|
||
{
|
||
/* Clean */
|
||
if (MAXLIM == Local.SX) MAP16_BLUR_ScissorX_Inplace(&Local,Local.SY/2);//*/
|
||
MAP16_FLIP_V(&Local);
|
||
}
|
||
|
||
}
|
||
else
|
||
{
|
||
if (FLAGS->POSTFILTERING || FLAGS->COMPUTE_LAPLACIAN)
|
||
{
|
||
MAP16_HOUGHPostFilter(&Local,FLAGS);
|
||
|
||
#ifdef BACKFILTERING
|
||
/*MAP16_BLUR_ScissorX_Inplace(&Local,-(s32)Local.SY);
|
||
MAP16_BLUR_CopyTransposeFAST(&Local,pTmp);
|
||
MAP16_HOUGHPostFilter(pTmp,FLAGS);
|
||
MAP16_BLUR_CopyTransposeFAST(pTmp,&Local);
|
||
MAP16_BLUR_ScissorX_Inplace(&Local,(s32)Local.SY);//*/
|
||
/*
|
||
MAP16_BLUR_CopyTransposeFAST(&Local,pTmp);
|
||
MAP16_HOUGHPostFilter(pTmp,FLAGS);
|
||
MAP16_BLUR_CopyTransposeFAST(pTmp,&Local);
|
||
//*/
|
||
#endif
|
||
|
||
}
|
||
if (FLAGS->COMPUTE_ENVELLOPPE) MAP16_HOUGHCosEnvellppe(&Local,FLAGS);
|
||
|
||
if (!FLAGS->SEPARATE_QUADRANTS) MAP16_FLIP_H(&Local);
|
||
}
|
||
|
||
if (FLAGS->COMPUTE)
|
||
{
|
||
if (!FLAGS->INPLACE && pTmp)
|
||
for (u32 Counter = 0; 1<<Counter < MAXLIM ; Counter+=2)
|
||
{
|
||
MAP16_Set(pTmp,0);
|
||
MAP16_FastHoughQuadran_V(&Local,pTmp,Counter,0); // 2
|
||
if (1<<(Counter+1) < MAXLIM)
|
||
MAP16_FastHoughQuadran_V(pTmp,&Local,Counter+1,0); // 4
|
||
else
|
||
MAP16_Copy(pTmp,&Local);
|
||
}
|
||
else
|
||
for (u32 Counter = 0; 1<<Counter < MAXLIM; Counter++)
|
||
MAP16_FastHoughQuadran_Inplace(&Local,Counter,FLAGS->MODE_CYCLIQUE,FLAGS->INVERSE); // 2) */
|
||
}
|
||
|
||
if (!(FLAGS->INVERSE))
|
||
{
|
||
/* Divide 0<> and 45<34> by 2 */
|
||
//MAP16_HOUGHDivide0And45(&Local,(1<<FLAGS->SubWindowShift)-1);
|
||
if (FLAGS->ZeroCrossing1) MAP16_HOUGHZeroCrossing(&Local,FLAGS->ZeroCrossing1);
|
||
if (FLAGS->Treshold) MAP16_Threshold(&Local,FLAGS->Treshold);
|
||
|
||
if (FLAGS->CLEAN)
|
||
{
|
||
/* Clean */
|
||
MAP16_FLIP_V(&Local);
|
||
if (MAXLIM == Local.SX) MAP16_BLUR_ScissorX_Inplace(&Local,Local.SY/2);//*/
|
||
}
|
||
} else
|
||
{
|
||
if (FLAGS->ZeroCrossing2) MAP16_HOUGHZeroCrossing(&Local,FLAGS->ZeroCrossing2);
|
||
}
|
||
|
||
|
||
if ((FLAGS->INVERSE) && (!(QCounter & 2)))
|
||
{
|
||
if (FLAGS->MERGE_QUADRANTS) MAP16_FLIP_V(&Local);
|
||
}
|
||
}
|
||
|
||
if (pTmp)
|
||
{
|
||
pTmp->SX<<=1;
|
||
pTmp->SY<<=1;
|
||
}
|
||
|
||
if (FLAGS->INVERSE)
|
||
{
|
||
if (FLAGS->MERGE_QUADRANTS)
|
||
{
|
||
pSrc->SX <<= 1;
|
||
Local = *pSrc; Local.staticBase = 1;
|
||
Local.MoveBase(Local.SY*Local.PITCH);
|
||
MAP16_Add(&Local,pSrc);
|
||
pSrc->SX >>= 1;
|
||
Local.SX >>= 1;
|
||
pSrc->MoveBase(pSrc->SX);
|
||
MAP16_BLUR_CopyTransposeFAST(pSrc,&Local);
|
||
pSrc->MoveBase(-pSrc->SX);
|
||
MAP16_Add(&Local,pSrc);
|
||
MAP16_FLIP_H(pSrc);
|
||
MAP16_FLIP_V(pSrc);//*/
|
||
}
|
||
pSrc->SY <<= 1;
|
||
pSrc->SX <<= 1;
|
||
if (FLAGS->COMPUTE_E2)
|
||
{
|
||
MAP16_XE2(pSrc);
|
||
MAP16_YE2(pSrc);
|
||
}
|
||
|
||
} else
|
||
{
|
||
/* Clean */
|
||
if (FLAGS->CLEAN)
|
||
{
|
||
Local = *pSrc; Local.staticBase = 1;
|
||
Local.SX<<=1;
|
||
MAP16_FLIP_V(&Local);
|
||
Local = *pSrc; Local.staticBase = 1;
|
||
Local.MoveBase(Local.SX);
|
||
Local.SY<<=1;
|
||
MAP16_FLIP_V(&Local);
|
||
}
|
||
pSrc->SY <<= 1;
|
||
pSrc->SX <<= 1;
|
||
}
|
||
|
||
|
||
}
|
||
|
||
void FAST_HOUGH_DEENTERLACE(MAP16 *MapDST,MAP16 *pTmp,u32 Po2)//*/
|
||
{
|
||
s16 *LAST,*BIGLAST,*TMP,*DST;
|
||
/* MM H */
|
||
|
||
BIGLAST = MapDST->GetBase() + MapDST->SY * MapDST->PITCH;
|
||
TMP = pTmp->GetBase();
|
||
DST = MapDST->GetBase();
|
||
for (u32 Counter = 0 ; Counter < 1<<Po2 ; Counter ++)
|
||
{
|
||
DST = MapDST->GetBase() + Counter * MapDST->PITCH;
|
||
while (DST < BIGLAST)
|
||
{
|
||
s32 CX = 0;
|
||
LAST = DST + MapDST->SX;
|
||
while (DST < LAST)
|
||
{
|
||
|
||
*(TMP++) = *(DST++);
|
||
}
|
||
DST += (MapDST->PITCH << Po2) - MapDST->SX;
|
||
TMP += pTmp->PITCH - pTmp->SX;
|
||
}
|
||
}
|
||
MAP16_Copy(pTmp,MapDST);
|
||
}
|
||
|
||
void HOUGH_Filtering(MAP16 *MapDST)
|
||
{
|
||
s16 *LAST,*DST,*DST2;
|
||
s16 Hysteresys[2048];
|
||
s16 HystereBlur[2048];
|
||
MAP16_Shift(MapDST,1);
|
||
static u32 Deperd = 32;
|
||
static u32 Tresh = 20;
|
||
/* MM H */
|
||
memset(Hysteresys , 0 , sizeof(Hysteresys));
|
||
DST = MapDST->GetBase();
|
||
for (u32 SizeY = 0; SizeY < MapDST->SY;SizeY ++)
|
||
{
|
||
u32 Index = 0;
|
||
LAST = DST + MapDST->SX;
|
||
while (DST < LAST)
|
||
{
|
||
if (abs(*DST) > Tresh)
|
||
{
|
||
Hysteresys[Index] = Deperd;
|
||
Hysteresys[(Index + 1)& (MapDST->SX-1)] = Deperd;
|
||
Hysteresys[(Index + MapDST->SX - 1)& (MapDST->SX-1)] = Deperd;
|
||
}
|
||
Index++;
|
||
DST++;
|
||
}
|
||
Index = 0;
|
||
DST -= MapDST->SX;
|
||
while (DST < LAST)
|
||
{
|
||
if (Hysteresys[Index]) *DST |= 1;
|
||
HystereBlur[Index] = Hysteresys[Index] + Hysteresys[Index] + Hysteresys[(Index + 1)& (MapDST->SX-1)] + Hysteresys[(Index + MapDST->SX - 1) & (MapDST->SX-1)];
|
||
HystereBlur[Index] >>= 2;
|
||
if (HystereBlur[Index]) HystereBlur[Index] --;
|
||
Index++;
|
||
DST++;
|
||
}
|
||
memcpy(Hysteresys,HystereBlur,MapDST->SX*sizeof(Hysteresys[0]));
|
||
DST += MapDST->PITCH - MapDST->SX;
|
||
}
|
||
DST = MapDST->GetBase() + (MapDST->SY-1) * MapDST->PITCH;
|
||
for (u32 SizeY = 0; SizeY < MapDST->SY;SizeY ++)
|
||
{
|
||
u32 Index = 0;
|
||
LAST = DST + MapDST->SX;
|
||
while (DST < LAST)
|
||
{
|
||
if (abs(*DST) > Tresh)
|
||
{
|
||
Hysteresys[Index] = Deperd;
|
||
Hysteresys[(Index + 1)& (MapDST->SX-1)] = Deperd;
|
||
Hysteresys[(Index + MapDST->SX - 1)& (MapDST->SX-1)] = Deperd;
|
||
}
|
||
Index++;
|
||
DST++;
|
||
}
|
||
Index = 0;
|
||
DST -= MapDST->SX;
|
||
while (DST < LAST)
|
||
{
|
||
if (Hysteresys[Index]) *DST |= 1;
|
||
HystereBlur[Index] = Hysteresys[Index] + Hysteresys[Index] + Hysteresys[(Index + 1)& (MapDST->SX-1)] + Hysteresys[(Index + MapDST->SX - 1) & (MapDST->SX-1)];
|
||
HystereBlur[Index] >>= 2;
|
||
if (HystereBlur[Index]) HystereBlur[Index] --;
|
||
Index++;
|
||
DST++;
|
||
}
|
||
memcpy(Hysteresys,HystereBlur,MapDST->SX*sizeof(Hysteresys[0]));
|
||
DST -= MapDST->SX;
|
||
DST -= MapDST->PITCH;
|
||
}
|
||
DST = MapDST->GetBase();
|
||
for (u32 SizeY = 0; SizeY < MapDST->SY;SizeY ++)
|
||
{
|
||
u32 Index = 0;
|
||
LAST = DST + MapDST->SX;
|
||
while (DST < LAST)
|
||
{
|
||
if (!(*DST & 1))
|
||
{
|
||
*DST = 0;
|
||
}
|
||
|
||
DST++;
|
||
}
|
||
DST += MapDST->PITCH - MapDST->SX;
|
||
}
|
||
MAP16_Shift(MapDST,-1);
|
||
}
|