?? ip.cpp
字號:
// source dib buffer
LPBITMAPINFO lpSrcDIB = (LPBITMAPINFO)GlobalLock(hDib);
if (! lpSrcDIB)
{
WaitCursorBegin();
return FALSE;
}
// New DIB buffer
LPBITMAPINFO lpbmi = (LPBITMAPINFO)GlobalLock(hNewDIB);
if (! lpbmi)
{
WaitCursorBegin();
return FALSE;
}
// start erosion...
LPBYTE lpPtr;
LPBYTE lpTempPtr;
LONG x,y;
BYTE num, num0;
int i;
LONG lHeight = DIBHeight(lpSrcDIB);
LONG lWidth = DIBWidth(lpSrcDIB);
DWORD dwBufferSize = GlobalSize(lpSrcDIB);
int nLineBytes = BytesPerLine(lpSrcDIB);
// Step 1: erosion
if(bHori)
{
for (y=0; y<lHeight; y++)
{
lpPtr=(BYTE *)lpSrcDIB+(dwBufferSize-nLineBytes-y*nLineBytes)+1;
lpTempPtr=(BYTE *)lpbmi+(dwBufferSize-nLineBytes-y*nLineBytes)+1;
for (x=1; x<lWidth-1; x++)
{
num0 = num = 0 ;
for(i=0;i<3;i++)
{
num=(unsigned char)*(lpPtr+i-1);
if(num > num0)
num0 = num;
}
*lpTempPtr=(unsigned char)num0;
/*
num=(unsigned char)*lpPtr;
if (num==0)
{
*lpTempPtr=(unsigned char)0;
for(i=0;i<3;i++)
{
num=(unsigned char)*(lpPtr+i-1);
if(num==255)
{
*lpTempPtr=(unsigned char)255;
break;
}
}
}
else
*lpTempPtr=(unsigned char)255;
*/
lpPtr++;
lpTempPtr++;
}
}
}
else // Vertical
{
for (y=1; y<lHeight-1; y++)
{
lpPtr=(BYTE *)lpSrcDIB+(dwBufferSize-nLineBytes-y*nLineBytes);
lpTempPtr=(BYTE *)lpbmi+(dwBufferSize-nLineBytes-y*nLineBytes);
for (x=0; x<lWidth; x++)
{
num0 = num = 0 ;
for(i=0;i<3;i++)
{
num=(unsigned char)*(lpPtr+i-1);
if(num > num0)
num0 = num;
}
*lpTempPtr=(unsigned char)num0;
/*
num=(unsigned char)*lpPtr;
if (num==0)
{
*lpTempPtr=(unsigned char)0;
for(i=0;i<3;i++)
{
num=(unsigned char)*(lpPtr+(i-1)*nLineBytes);
if(num==255)
{
*lpTempPtr=(unsigned char)255;
break;
}
}
}
else
*lpTempPtr=(unsigned char)255;
*/
lpPtr++;
lpTempPtr++;
}
}
}
// Step 2: original image minues dilation image
if(bHori)
{
for(y=0;y<lHeight;y++)
{
lpPtr=(BYTE *)lpbmi+(dwBufferSize-nLineBytes-y*nLineBytes)+1;
lpTempPtr=(BYTE *)lpSrcDIB+(dwBufferSize-nLineBytes-y*nLineBytes)+1;
for(x=1;x<lWidth-1;x++)
{
if (*lpTempPtr == *lpPtr)
*lpTempPtr = (BYTE)255;
else
*lpTempPtr = *lpTempPtr - *lpPtr;
lpPtr++;
lpTempPtr++;
}
}
}
else
{
for(y=1;y<lHeight-1;y++)
{
lpPtr=(BYTE *)lpbmi+(dwBufferSize-nLineBytes-y*nLineBytes);
lpTempPtr=(BYTE *)lpSrcDIB+(dwBufferSize-nLineBytes-y*nLineBytes);
for(x=0;x<lWidth;x++)
{
if (*lpTempPtr == *lpPtr)
*lpTempPtr = (BYTE)255;
else
*lpTempPtr = *lpTempPtr - *lpPtr;
lpPtr++;
lpTempPtr++;
}
}
}
// cleanup
GlobalUnlock(hDib);
GlobalUnlock(hNewDIB);
GlobalFree(hNewDIB);
return TRUE;
}
/*************************************************************************
*
* ThinningDIB()
*
* Parameters:
*
* HDIB hDib - objective DIB handle
*
* Return Value:
*
* BOOL - True is success, else False
*
* Description:
*
* This function thins a DIB
*
************************************************************************/
BOOL ThinningDIB(HDIB hDib)
{
static int erasetable[256]=
{
0,0,1,1,0,0,1,1,
1,1,0,1,1,1,0,1,
1,1,0,0,1,1,1,1,
0,0,0,0,0,0,0,1,
0,0,1,1,0,0,1,1,
1,1,0,1,1,1,0,1,
1,1,0,0,1,1,1,1,
0,0,0,0,0,0,0,1,
1,1,0,0,1,1,0,0,
0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,
1,1,0,0,1,1,0,0,
1,1,0,1,1,1,0,1,
0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,
0,0,1,1,0,0,1,1,
1,1,0,1,1,1,0,1,
1,1,0,0,1,1,1,1,
0,0,0,0,0,0,0,1,
0,0,1,1,0,0,1,1,
1,1,0,1,1,1,0,1,
1,1,0,0,1,1,1,1,
0,0,0,0,0,0,0,0,
1,1,0,0,1,1,0,0,
0,0,0,0,0,0,0,0,
1,1,0,0,1,1,1,1,
0,0,0,0,0,0,0,0,
1,1,0,0,1,1,0,0,
1,1,0,1,1,1,0,0,
1,1,0,0,1,1,1,0,
1,1,0,0,1,0,0,0
};
// start wait cursor
WaitCursorBegin();
// Old DIB buffer
if (hDib == NULL)
{
WaitCursorEnd();
return FALSE;
}
// only support 256 color image
WORD wBitCount = DIBBitCount(hDib);
if (wBitCount != 8)
{
WaitCursorEnd();
return FALSE;
}
// new DIB
HDIB hNewDIB = CopyHandle(hDib);
if (! hNewDIB)
{
WaitCursorEnd();
return FALSE;
}
// source dib buffer
LPBITMAPINFO lpSrcDIB = (LPBITMAPINFO)GlobalLock(hDib);
if (! lpSrcDIB)
{
WaitCursorBegin();
return FALSE;
}
// New DIB buffer
LPBITMAPINFO lpbmi = (LPBITMAPINFO)GlobalLock(hNewDIB);
if (! lpbmi)
{
WaitCursorBegin();
return FALSE;
}
// start erosion...
LPSTR lpPtr;
LPSTR lpTempPtr;
LONG x,y;
BYTE num;
LONG lHeight = DIBHeight(lpSrcDIB);
LONG lWidth = DIBWidth(lpSrcDIB);
DWORD dwBufferSize = GlobalSize(lpSrcDIB);
int nLineBytes = BytesPerLine(lpSrcDIB);
int nw,n,ne,w,e,sw,s,se;
BOOL Finished=FALSE;
while(!Finished)
{
Finished=TRUE;
for (y=1;y<lHeight-1;y++)
{
lpPtr=(char *)lpbmi+(dwBufferSize-nLineBytes-y*nLineBytes);
lpTempPtr=(char *)lpSrcDIB+(dwBufferSize-nLineBytes-y*nLineBytes);
x=1;
while(x<lWidth-1)
{
if(*(lpPtr+x)==0)
{
w=(unsigned char)*(lpPtr+x-1);
e=(unsigned char)*(lpPtr+x+1);
if( (w==255)|| (e==255))
{
nw=(unsigned char)*(lpPtr+x+nLineBytes-1);
n=(unsigned char)*(lpPtr+x+nLineBytes);
ne=(unsigned char)*(lpPtr+x+nLineBytes+1);
sw=(unsigned char)*(lpPtr+x-nLineBytes-1);
s=(unsigned char)*(lpPtr+x-nLineBytes);
se=(unsigned char)*(lpPtr+x-nLineBytes+1);
num=nw/255+n/255*2+ne/255*4+w/255*8+e/255*16+sw/255*32+s/255*64+se/255*128;
if(erasetable[num]==1)
{
*(lpPtr+x)=(BYTE)255;
*(lpTempPtr+x)=(BYTE)255;
Finished=FALSE;
x++;
}
}
}
x++;
}
}
for (x=1;x<lWidth-1;x++)
{
y=1;
while(y<lHeight-1)
{
lpPtr=(char *)lpbmi+(dwBufferSize-nLineBytes-y*nLineBytes);
lpTempPtr=(char *)lpSrcDIB+(dwBufferSize-nLineBytes-y*nLineBytes);
if(*(lpPtr+x)==0)
{
n=(unsigned char)*(lpPtr+x+nLineBytes);
s=(unsigned char)*(lpPtr+x-nLineBytes);
if( (n==255)|| (s==255))
{
nw=(unsigned char)*(lpPtr+x+nLineBytes-1);
ne=(unsigned char)*(lpPtr+x+nLineBytes+1);
w=(unsigned char)*(lpPtr+x-1);
e=(unsigned char)*(lpPtr+x+1);
sw=(unsigned char)*(lpPtr+x-nLineBytes-1);
se=(unsigned char)*(lpPtr+x-nLineBytes+1);
num=nw/255+n/255*2+ne/255*4+w/255*8+e/255*16+sw/255*32+s/255*64+se/255*128;
if(erasetable[num]==1)
{
*(lpPtr+x)=(BYTE)255;
*(lpTempPtr+x)=(BYTE)255;
Finished=FALSE;
y++;
}
}
}
y++;
}
}
}
// cleanup
GlobalUnlock(hDib);
GlobalUnlock(hNewDIB);
GlobalFree(hNewDIB);
return TRUE;
}
//////////////////////////////////////////////////////////
// internal definitions
#define PI (double)3.14159265359
/*complex number*/
typedef struct
{
double re;
double im;
}COMPLEX;
/*complex add*/
COMPLEX Add(COMPLEX c1, COMPLEX c2)
{
COMPLEX c;
c.re=c1.re+c2.re;
c.im=c1.im+c2.im;
return c;
}
/*complex substract*/
COMPLEX Sub(COMPLEX c1, COMPLEX c2)
{
COMPLEX c;
c.re=c1.re-c2.re;
c.im=c1.im-c2.im;
return c;
}
/*complex multiple*/
COMPLEX Mul(COMPLEX c1, COMPLEX c2)
{
COMPLEX c;
c.re=c1.re*c2.re-c1.im*c2.im;
c.im=c1.re*c2.im+c2.re*c1.im;
return c;
}
//////////////////////////////////////////////////////////
/*
void FFT(COMPLEX * TD, COMPLEX * FD, int power);
void IFFT(COMPLEX * FD, COMPLEX * TD, int power);
void DCT(double *f, double *F, int power);
void IDCT(double *F, double *f, int power);
void WALh(double *f, double *W, int power);
void IWALh(double *W, double *f, int power);
*/
/****************************************************
FFT()
參數(shù):
TD為時域值
FD為頻域值
power為2的冪數(shù)
返回值:
無
說明:
本函數(shù)實現(xiàn)快速傅立葉變換
****************************************************/
void FFT(COMPLEX * TD, COMPLEX * FD, int power)
{
int count;
int i,j,k,bfsize,p;
double angle;
COMPLEX *W,*X1,*X2,*X;
/*計算傅立葉變換點數(shù)*/
count=1<<power;
/*分配運算所需存儲器*/
W=(COMPLEX *)malloc(sizeof(COMPLEX)*count/2);
X1=(COMPLEX *)malloc(sizeof(COMPLEX)*count);
X2=(COMPLEX *)malloc(sizeof(COMPLEX)*count);
/*計算加權(quán)系數(shù)*/
for(i=0;i<count/2;i++)
{
angle=-i*PI*2/count;
W[i].re=cos(angle);
W[i].im=sin(angle);
}
/*將時域點寫入存儲器*/
memcpy(X1,TD,sizeof(COMPLEX)*count);
/*蝶形運算*/
for(k=0;k<power;k++)
{
for(j=0;j<1<<k;j++)
{
bfsize=1<<(power-k);
for(i=0;i<bfsize/2;i++)
{
p=j*bfsize;
X2[i+p]=Add(X1[i+p],X1[i+p+bfsize/2]);
X2[i+p+bfsize/2]=Mul(Sub(X1[i+p],X1[i+p+bfsize/2]),W[i*(1<<k)]);
}
}
X=X1;
X1=X2;
X2=X;
}
/*重新排序*/
for(j=0;j<count;j++)
{
p=0;
for(i=0;i<power;i++)
{
if (j&(1<<i)) p+=1<<(power-i-1);
}
FD[j]=X1[p];
}
/*釋放存儲器*/
free(W);
free(X1);
free(X2);
}
/****************************************************
IFFT()
參數(shù):
FD為頻域值
TD為時域值
power為2的冪數(shù)
返回值:
無
說明:
本函數(shù)利用快速傅立葉變換實現(xiàn)傅立葉反變換
****************************************************/
void IFFT(COMPLEX * FD, COMPLEX * TD, int power)
{
int i, count;
COMPLEX *x;
/*計算傅立葉反變換點數(shù)*/
count=1<<power;
/*分配運算所需存儲器*/
x=(COMPLEX *)malloc(sizeof(COMPLEX)*count);
/*將頻域點寫入存儲器*/
memcpy(x,FD,sizeof(COMPLEX)*count);
/*求頻域點的共軛*/
for(i=0;i<count;i++)
x[i].im = -x[i].im;
/*調(diào)用FFT*/
FFT(x, TD, power);
/*求時域點的共軛*/
for(i=0;i<count;i++)
{
TD[i].re /= count;
TD[i].im = -TD[i].im / count;
}
/*釋放存儲器*/
free(x);
}
/*******************************************************
DCT()
參數(shù):
f為時域值
F為頻域值
power為2的冪數(shù)
返回值:
無
說明:
本函數(shù)利用快速傅立葉變換實現(xiàn)快速離散余弦變換
********************************************************/
void DCT(double *f, double *F, int power)
{
int i,count;
COMPLEX *X;
double s;
/*計算離散余弦變換點數(shù)*/
count=1<<power;
/*分配運算所需存儲器*/
X=(COMPLEX *)malloc(sizeof(COMPLEX)*count*2);
/*延拓*/
memset(X,0,sizeof(COMPLEX)*count*2);
/*將時域點寫入存儲器*/
for(i=0;i<count;i++)
{
X[i].re=f[i];
}
/*調(diào)用快速傅立葉變換*/
FFT(X,X,power+1);
/*調(diào)整系數(shù)*/
s=1/sqrt(count);
F[0]=X[0].re*s;
s*=sqrt(2);
for(i=1;i<count;i++)
{
F[i]=(X[i].re*cos(i*PI/(count*2))+X[i].im*sin(i*PI/(count*2)))*s;
}
/*釋放存儲器*/
free(X);
}
/************************************************************
IDCT()
參數(shù):
F為頻域值
f為時域值
power為2的冪數(shù)
返回值:
無
說明:
本函數(shù)利用快速傅立葉反變換實現(xiàn)快速離散反余弦變換
*************************************************************/
void IDCT(double *F, double *f, int power)
{
int i,count;
COMPLEX *X;
double s;
/*計算離散反余弦變換點數(shù)*/
count=1<<power;
/*分配運算所需存儲器*/
X=(COMPLEX *)malloc(sizeof(COMPLEX)*count*2);
/*延拓*/
memset(X,0,sizeof(COMPLEX)*count*2);
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -