📄 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()
参数:
TD为时域值
FD为频域值
power为2的幂数
返回值:
无
说明:
本函数实现快速傅立叶变换
****************************************************/
void FFT(COMPLEX * TD, COMPLEX * FD, int power)
{
int count;
int i,j,k,bfsize,p;
double angle;
COMPLEX *W,*X1,*X2,*X;
/*计算傅立叶变换点数*/
count=1<<power;
/*分配运算所需存储器*/
W=(COMPLEX *)malloc(sizeof(COMPLEX)*count/2);
X1=(COMPLEX *)malloc(sizeof(COMPLEX)*count);
X2=(COMPLEX *)malloc(sizeof(COMPLEX)*count);
/*计算加权系数*/
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()
参数:
FD为频域值
TD为时域值
power为2的幂数
返回值:
无
说明:
本函数利用快速傅立叶变换实现傅立叶反变换
****************************************************/
void IFFT(COMPLEX * FD, COMPLEX * TD, int power)
{
int i, count;
COMPLEX *x;
/*计算傅立叶反变换点数*/
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;
/*调用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()
参数:
f为时域值
F为频域值
power为2的幂数
返回值:
无
说明:
本函数利用快速傅立叶变换实现快速离散余弦变换
********************************************************/
void DCT(double *f, double *F, int power)
{
int i,count;
COMPLEX *X;
double s;
/*计算离散余弦变换点数*/
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];
}
/*调用快速傅立叶变换*/
FFT(X,X,power+1);
/*调整系数*/
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()
参数:
F为频域值
f为时域值
power为2的幂数
返回值:
无
说明:
本函数利用快速傅立叶反变换实现快速离散反余弦变换
*************************************************************/
void IDCT(double *F, double *f, int power)
{
int i,count;
COMPLEX *X;
double s;
/*计算离散反余弦变换点数*/
count=1<<power;
/*分配运算所需存储器*/
X=(COMPLEX *)malloc(sizeof(COMPLEX)*count*2);
/*延拓*/
memset(X,0,sizeof(COMPLEX)*count*2);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -