📄 cdib.cpp
字号:
{
// x方向进行快速傅立叶变换
FastFourierTran(&pTd[wid * i], &pFd[wid * i], widpor);
}
// pFd中目前存储了pTd经过行变换的结果
// 为了直接利用FastFourierTran,需要把pFd的二维数据转置,再一次利用FastFourierTran进行
// 傅立叶行变换(实际上相当于对列进行傅立叶变换)
for(i = 0; i < hei; i++)
{
for(j = 0; j < wid; j++)
{
pTd[hei * j + i] = pFd[wid * i + j];
}
}
for(j = 0; j < wid; j++)
{
// 对x方向进行快速傅立叶变换,实际上相当于对原来的图象数据进行列方向的
// 傅立叶变换
FastFourierTran(&pTd[j * hei], &pFd[j * hei], heiPor);
}
// pFd中目前存储了pTd经过二维傅立叶变换的结果,但是为了方便列方向
// 的傅立叶变换,对其进行了转置,现在把结果转置回来
for(i = 0; i < hei; i++)
{
for(j = 0; j < wid; j++)
{
pTd[wid * i + j] = pFd[hei * j + i];
}
}
memcpy(pTd, pFd, sizeof(CplexNum) * hei * wid );
for(j=0;j<hei;j++)
{
for(i=0;i<wid;i++)
{
temp=sqrt(pTd[i*hei+j].re*pTd[i*hei+j].re+pTd[i*hei+j].im*pTd[i*hei+j].im)/100;
if(temp>255)
temp=255;
p=rong+lLineBytes*(m_Height-(j<hei/2?j+hei/2:j-hei/2)-1)+
(i<wid/2?i+wid/2:i-wid/2);//将变换后的原点移到中心
p=rong+lLineBytes*(m_Height-(j<hei/2?j:j)-1)+
(i<wid/2?i:i);
*(p)=(BYTE)(temp);
}
}
// memcpy(rong,pTd,sizeof(CplexNum) * hei * wid);
// Fourier( pTd, m_Width, m_Height, pFd);
delete pTd;
delete pFd;
return TRUE;
}
BOOL CDib::Fourier2()//进行平移后的图像
{
int j;
int i;
int wid=1;
int hei=1;
int widpor=0,heiPor=0;//2的幂数
unsigned char* rong=m_pDibBits;
unsigned char* p;
long lLineBytes=WIDTHBYTES(m_Width*8);
double temp;//中间变量
while(wid * 2 <= m_Width)// 计算进行付立叶变换的宽度和高度(2的整数次方)
{
wid *= 2;
widpor++;
}
while(hei * 2 <= m_Height)
{
hei *= 2;
heiPor++;
}
CplexNum *pTd = new CplexNum[sizeof(CplexNum)*wid * hei];// 分配内存
CplexNum *pFd = new CplexNum[sizeof(CplexNum)*wid * hei];
for (j=0;j<hei;j++)
{
for (i=0;i<wid;i++)
{
p=rong+lLineBytes*(m_Height-j-1)+i;
pTd[i+wid*j].re=*(p);
pTd[i+wid*j].im=0;
}
}
for(i = 0; i < hei; i++)
{
FastFourierTran(&pTd[wid * i], &pFd[wid * i], widpor);
}
for(i = 0; i < hei; i++)
{
for(j = 0; j < wid; j++)
{
pTd[hei * j + i] = pFd[wid * i + j];
}
}
for(j = 0; j < wid; j++)
{
FastFourierTran(&pTd[j * hei], &pFd[j * hei], heiPor);
}
for(i = 0; i < hei; i++)
{
for(j = 0; j < wid; j++)
{
pTd[wid * i + j] = pFd[hei * j + i];
}
}
memcpy(pTd, pFd, sizeof(CplexNum) * hei * wid );
for(j=0;j<hei;j++)
{
for(i=0;i<wid;i++)
{
temp=sqrt(pTd[i*hei+j].re*pTd[i*hei+j].re+pTd[i*hei+j].im*pTd[i*hei+j].im)/100;
if(temp>255)
temp=255;
p=rong+lLineBytes*(m_Height-(j<hei/2?j+hei/2:j-hei/2)-1)+
(i<wid/2?i+wid/2:i-wid/2);//将变换后的原点移到中心
*(p)=(BYTE)(temp);
}
}
delete pTd;
delete pFd;
return TRUE;
}
void fourier(double * data, int height, int width, int isign)
{
int idim;
unsigned long i1,i2,i3,i2rev,i3rev,ip1,ip2,ip3,ifp1,ifp2;
unsigned long ibit,k1,k2,n,nprev,nrem,ntot,nn[3];
double tempi,tempr;
double theta,wi,wpi,wpr,wr,wtemp;
ntot=height*width;
nn[1]=height;
nn[2]=width;
nprev=1;
for (idim=2;idim>=1;idim--)
{
n=nn[idim];
nrem=ntot/(n*nprev);
ip1=nprev << 1;
ip2=ip1*n;
ip3=ip2*nrem;
i2rev=1;
for (i2=1;i2<=ip2;i2+=ip1)
{
if (i2 < i2rev)
{
for (i1=i2;i1<=i2+ip1-2;i1+=2)
{
for (i3=i1;i3<=ip3;i3+=ip2)
{
i3rev=i2rev+i3-i2;
SWAP(data[i3],data[i3rev]);
SWAP(data[i3+1],data[i3rev+1]);
}
}
}
ibit=ip2 >> 1;
while (ibit >= ip1 && i2rev > ibit)
{
i2rev -= ibit;
ibit >>= 1;
}
i2rev += ibit;
}
ifp1=ip1;
while (ifp1 < ip2)
{
ifp2=ifp1 << 1;
theta=isign*pi*2/(ifp2/ip1);
wtemp=sin(0.5*theta);
wpr = -2.0*wtemp*wtemp;
wpi=sin(theta);
wr=1.0;
wi=0.0;
for (i3=1;i3<=ifp1;i3+=ip1)
{
for (i1=i3;i1<=i3+ip1-2;i1+=2)
{
for (i2=i1;i2<=ip3;i2+=ifp2)
{
k1=i2;
k2=k1+ifp1;
tempr=wr*data[k2]-wi*data[k2+1];
tempi=wr*data[k2+1]+wi*data[k2];
data[k2]=data[k1]-tempr;
data[k2+1]=data[k1+1]-tempi;
data[k1] += tempr;
data[k1+1] += tempi;
}
}
wr=(wtemp=wr)*wpr-wi*wpi+wr;
wi=wi*wpr+wtemp*wpi+wi;
}
ifp1=ifp2;
}
nprev *= n;
}
}
BOOL CDib::rotate(int angle)
{
int newwidth,newheight;
unsigned char*lpDIB, *lp;
unsigned char*lpsrc,*lpdst;
BITMAPINFOHEADER *lpinfo;
double arcangle;
int i,j,i0,j0;
float f1,f2;
float fsin,fcos;
float srcx1,srcx2,srcx3,srcx4;
float srcy1,srcy2,srcy3,srcy4;
float dstx1,dstx2,dstx3,dstx4;
float dsty1,dsty2,dsty3,dsty4;
arcangle=(angle*pi)/180.0;
fsin=(float)sin(arcangle);
fcos=(float)cos(arcangle);
srcx1=(float)(-(m_Width-1)/2);
srcy1=(float)((m_Height-1)/2);
srcx2=(float)((m_Width-1)/2);
srcy2=(float)((m_Height-1)/2);
srcx3=(float)(-(m_Width-1)/2);
srcy3=(float)(-(m_Height-1)/2);
srcx4=(float)((m_Width-1)/2);
srcy4=(float)(-(m_Height-1)/2);
dstx1=fcos*srcx1+fsin*srcy1;
dsty1=-fsin*srcx1+fcos*srcy1;
dstx2=fcos*srcx2+fsin*srcy2;
dsty2=-fsin*srcx2+fcos*srcy2;
dstx3=fcos*srcx3+fsin*srcy3;
dsty3=-fsin*srcx3+fcos*srcy3;
dstx4=fcos*srcx4+fsin*srcy4;
dsty4=-fsin*srcx4+fcos*srcy4;
newwidth=(int)(max(fabs(dstx4-dstx1),fabs(dstx3-dstx2))+0.5);
newheight=(int)(max(fabs(dsty4-dsty1),fabs(dsty3-dsty2))+0.5);
int lineBytes = GetReqByteWidth(newwidth*8);
int OldLineBytes = GetReqByteWidth(m_Width*8);
f1=(float)(-0.5*(m_Width-1));
f2=(float)(0.5*(m_Height-1));
lpDIB =new unsigned char[lineBytes*newheight+m_nPaletteEntries*sizeof(RGBQUAD) + sizeof(BITMAPINFOHEADER)];
if (lpDIB== NULL) {
return(FALSE);
}
lp = lpDIB + m_nPaletteEntries*sizeof(RGBQUAD) + sizeof(BITMAPINFOHEADER);
if (lp==NULL)
return (FALSE);
memset(lp,(BYTE)255,lineBytes*newheight);
memcpy(lpDIB,m_pDib,m_nPaletteEntries*sizeof(RGBQUAD) + sizeof(BITMAPINFOHEADER));
lpinfo=(BITMAPINFOHEADER*)lpDIB;
lpinfo->biWidth=newwidth;
lpinfo->biHeight=newheight;
for(i=0;i<newheight;i++)
{
for(j=0;j<newwidth;j++)
{
lpdst=(unsigned char*)lp+(newheight-1-i)*lineBytes+j;
i0=(long)(((float)i)*fcos-((float) j)*fsin+f2+0.5);
j0=(long)(((float)i)*fsin+((float) j)*fcos+f1+0.5);
if((i0>=0)&&(i0<m_Width)&&(j0>=0)&&(j0<m_Height))
{
lpsrc=(unsigned char*)m_pDibBits+OldLineBytes*(m_Height-1-i0)+j0;
*lpdst=*lpsrc;
}
}
}
delete []m_pDib;
m_pDib = lpDIB;
m_pDibBits = lp;
m_pBIH = lpinfo;
m_pBIH->biSizeImage = lineBytes* m_Height;
m_Width = lpinfo->biWidth;
m_Height = lpinfo->biHeight;
return TRUE;
}
BOOL CDib::zoomout(float xratio )
{
int i,j;
float i0,j0;
int x,y;
int newwidth,newheight;
unsigned char* lp;
unsigned char*lpsrc,*lpdst;
float temp1,temp2;
BITMAPINFOHEADER *lpinfo;
newwidth=(int)(m_Width*xratio+0.5);
newheight=(int)(m_Height*xratio+0.5);
lpinfo=m_pBIH;
lpinfo->biWidth=newwidth;
lpinfo->biHeight=newheight;
int lineBytes = GetReqByteWidth(newwidth*8);
int OldlinBytes = GetReqByteWidth(m_Width*8);
m_Width = lpinfo->biWidth;
m_Height = lpinfo->biHeight;
lp=new unsigned char[lineBytes*newheight];
for(i=1;i<newheight-1;i++)
{
for(j=1;j<newwidth-1;j++)
{
lpsrc=m_pDibBits;
lpdst=(unsigned char*)lp+i*lineBytes+j;
i0=i/xratio;
j0=j/xratio;
x=(int)i0;
y=(int)j0;
temp1=(i0-x)*(lpsrc[x*OldlinBytes+y])+((x+1)-i0)*(lpsrc[(x+1)*OldlinBytes+y]);
temp2=(i0-x)*(lpsrc[x*OldlinBytes+(y+1)])+((x+1)-i0)*(lpsrc[(x+1)*OldlinBytes+(y+1)]);
*lpdst=(unsigned char)((j0-y)*temp1+((y+1)-j0)*temp2);
}
}
m_pDibBits=lp;
return TRUE;
}
BOOL CDib::zoomin(float xratio)
{
int i,j;
float i0,j0;
int x,y;
int newwidth,newheight;
unsigned char* lp;
unsigned char*lpsrc,*lpdst;
BITMAPINFOHEADER *lpinfo;
float temp1,temp2;
newwidth=(int)(m_Width*xratio+0.5);
newheight=(int)(m_Height*xratio+0.5);
lpinfo=m_pBIH;
lpinfo->biWidth=newwidth;
lpinfo->biHeight=newheight;
int lineBytes = GetReqByteWidth(newwidth*8);
int OldlinBytes = GetReqByteWidth(m_Width*8);
m_Width = lpinfo->biWidth;
m_Height = lpinfo->biHeight;
lp=new unsigned char[lineBytes*newheight];
// lp=new unsigned char[newwidth*newheight];
for(i=1;i<newheight-1;i++)
{
for(j=1;j<newwidth-1;j++)
{
lpsrc=m_pDibBits;
lpdst=(unsigned char*)lp+i*lineBytes+j;
i0=i/xratio;
j0=j/xratio;
x=(int)i0;
y=(int)j0;
temp1=(i0-x)*(lpsrc[x*OldlinBytes+y])+((x+1)-i0)*(lpsrc[(x+1)*OldlinBytes+y]);
temp2=(i0-x)*(lpsrc[x*OldlinBytes+(y+1)])+((x+1)-i0)*(lpsrc[(x+1)*OldlinBytes+(y+1)]);
*lpdst=(unsigned char)((j0-y)*temp1+((y+1)-j0)*temp2);
}
}
m_pDibBits=lp;
return TRUE;
}
int CDib::GetReqByteWidth(int bits)
{
int getBytes=(bits + 31) / 32 * 4;
return getBytes;
}
BOOL CDib::PerfectFilterL(int u,int v)
{
LPBYTE rong, p;//指向原图象数据区指针
int i,j;
double d0,max=0.0;//中间变量
double *t,*H;
rong=m_pDibBits;//指向原图象数据
long lLineBytes=WIDTHBYTES(m_Width*8);
t=new double [m_Height*lLineBytes*2+1];//分配存储器空间
H=new double [m_Height*lLineBytes*2+1];
d0=sqrt(u*u+v*v);//计算截止频率d0
for(j=0;j<m_Height;j++)
{
for(i=0;i<lLineBytes;i++)
{
p=rong+lLineBytes*j+i;//指向第i行第j列象素
t[(2*lLineBytes)*j+2*i+1]=*(p);//给时域赋值
t[(2*lLineBytes)*j+2*i+2]=0.0;
if((sqrt(i*i+j*j))<=d0)
H[2*i+(2*lLineBytes)*j+1]=1.0;
else
H[2*i+(2*lLineBytes)*j+1]=0.0;
H[2*i+(2*lLineBytes)*j+2]=0.0;
}
}
fourier(t,m_Height,lLineBytes,1);
for(j=1;j<m_Height*lLineBytes*2;j+=2)
{
t[j]=t[j]*H[j]-t[j+1]*H[j+1];
t[j+1]=t[j]*H[j+1]+t[j+1]*H[j];
}
fourier(t,m_Height,lLineBytes,-1);
for(j=0;j<m_Height;j++)
{
for(i=0;i<lLineBytes;i++)
{
t[(2*lLineBytes)*j+2*i+1]=sqrt(t[(2*lLineBytes)*j+2*i+1]*t[(2*lLineBytes)*j+2*i+1]+t[(2*lLineBytes)*j+2*i+2]*t[(2*lLineBytes)*j+2*i+2]);
if(max<t[(2*lLineBytes)*j+2*i+1])
max=t[(2*lLineBytes)*j+2*i+1];
}
}
for(j=0;j<m_Height;j++)
{
for(i=0;i<lLineBytes;i++)
{
p=rong+lLineBytes*j+i;
*(p)=(BYTE)(t[(2*lLineBytes)*j+2*i+1]*255.0/max);
}
}
delete t;
delete H;
return TRUE;
}
BOOL CDib::PerfectFilterH(int u,int v)
{
LPBYTE rong, p;//指向原图象数据区指针
int i,j;
double d0,max=0.0;//中间变量
double *t,*H;
rong=m_pDibBits;//指向原图象数据
long lLineBytes=WIDTHBYTES(m_Width*8);//计算图象每行的字节数
t=new double [m_Height*lLineBytes*2+1];//分配存储器空间
H=new double [m_Height*lLineBytes*2+1];
d0=sqrt(u*u+v*v);//计算截止频率d0
for(j=0;j<m_Height;j++)
{
for(i=0;i<lLineBytes;i++)
{
p=rong+lLineBytes*j+i;//指向第i行第j列象素
t[(2*lLineBytes)*j+2*i+1]=*(p);//给时域赋值
t[(2*lLineBytes)*j+2*i+2]=0.0;
if((sqrt(i*i+j*j))<=d0)
H[2*i+(2*lLineBytes)*j+1]=0.0;
else
H[2*i+(2*lLineBytes)*j+1]=1.0;
H[2*i+(2*lLineBytes)*j+2]=0.0;
}
}
fourier(t,m_Height,lLineBytes,1);
for(j=1;j<m_Height*lLineBytes*2;j+=2)
{
t[j]=t[j]*H[j]-t[j+1]*H[j+1];
t[j+1]=t[j]*H[j+1]+t[j+1]*H[j];
}
fourier(t,m_Height,lLineBytes,-1);
for(j=0;j<m_Height;j++)
{
for(i=0;i<lLineBytes;i++)
{
t[(2*lLineBytes)*j+2*i+1]=sqrt(t[(2*lLineBytes)*j+2*i+1]*t[(2*lLineBytes)*j+2*i+1]+t[(2*lLineBytes)*j+2*i+2]*t[(2*lLineBytes)*j+2*i+2]);
if(max<t[(2*lLineBytes)*j+2*i+1])
max=t[(2*lLineBytes)*j+2*i+1];
}
}
for(j=0;j<m_Height;j++)
{
for(i=0;i<lLineBytes;i++)
{
p=rong+lLineBytes*j+i;
*(p)=(BYTE)(t[(2*lLineBytes)*j+2*i+1]*255.0/max);
}
}
delete t;
delete H;
return TRUE;
}
BOOL CDib::Erosion()
{
// 指向DIB象素指针
LPBYTE p_data;
// 指向源图像的指针
LPBYTE lpSrc;
// 指向缓存图像的指针
LPBYTE lpDst;
// 指向缓存DIB图像的指针
LPBYTE temp;
//循环变量
int i;
int j;
int m;
int n;
// 找到DIB图像象素起始位置
p_data = m_pDibBits;
// DIB的宽度
LONG wide= m_Width;
// DIB的高度
LONG height =m_Height;
if (m_pBIH->biBitCount <9)
{
// 暂时分配内存,以保存新图像
temp =new BYTE[wide*height];
// 初始化新分配的内存,设定初始值为255
lpDst = (LPBYTE)temp;
memset(lpDst, (BYTE)255, wide * height);
// 3×3的结构元素
int B[9] = {1, 0, 1,
0, 0, 0,
1, 0, 1};
// 使用全方向的结构元素进行腐蚀
for (j = 1; j < height - 1; j++)
{
for (i = 1; i < wide - 1; i++)
{
// 由于使用3×3的结构元素,为防止越界,所以不处理最左、右、上、下四边的像素
// 指向源图像倒数第j行,第i个象素的指针
lpSrc = (unsigned char *)(p_data + wide * j + i);
// 指向目标图像倒数第j行,第i个象素的指针
lpDst = (unsigned char *)(temp + wide * j + i);
// 目标图像中的当前点先赋成黑色
*lpDst = 0;
// 如果源图像中3×3结构元素对应位置有白点
// 则将目标图像中的(0,0)点赋成白色
for (m = 0; m < 3; m++)
{
for (n = 0; n < 3; n++)
{
if (B[m + n] == 1)
continue;
if (*(lpSrc + (1 - m) * wide +(n - 1) ) > 128)
{
*lpDst = 255;
break;
}
}
}
}
}
// 复制腐蚀后的图像
memcpy(p_data, temp, wide * height);
// 释放内存
delete temp;
}
else
{
// 暂时分配内存,以保存新图像
temp =new BYTE[wide*height*3 ];
// 初始化新分配的内存,设定初始值为255
lpDst = (LPBYTE)temp;
memset(lpDst, (BYTE)255, wide * height*3 );
// 3×3的结构元素
int B[9] = {1, 0, 1,
0, 0, 0,
1, 0, 1};
// 使用全方向的结构元素进行腐蚀
for (j = 1; j < height - 1; j++)
{
for (i = 1; i < 3*wide - 1; i++)
{
lpSrc = (unsigned char *)(p_data + 3*wide * j + i);
lpDst = (unsigned char *)(temp + 3* wide * j + i);
*lpDst = 0;
for (m = 0; m < 3; m++)
{
for (n = 0; n < 3; n++)
{
if (B[m + n] == 1)
continue;
if (*(lpSrc + (1 - m) * wide *3+(n - 1) ) > 128)
{
*lpDst = 255;
break;
}
}
}
}
}
// 复制腐蚀后的图像
memcpy(p_data, temp, wide * height*3);
// 释放内存
delete temp;
}
return TRUE;
}
BOOL CDib::Dilation()
{
// 指向DIB象素指针
LPBYTE p_data;
// 指向源图像的指针
LPBYTE lpSrc;
// 指向缓存图像的指针
LPBYTE lpDst;
// 指向缓存DIB图像的指针
LPBYTE temp;
//循环变量
int i;
int j;
int m;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -