⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 normaltran.cpp

📁 关于字符分割的程序
💻 CPP
📖 第 1 页 / 共 2 页
字号:



#include "StdAfx.h"
#include "normalTran.h"
#include "DIBApi.h"
//#include "complex"
//using namespace std;
#define PI 3.1415926535

int findq(int j,int power,int k1)
{
	int i ;
	int	p=0;
		for (i=power-k1;i<power;i++) {
			if (j&(1<<i)) {
				p+=1<<(power-i-1);
			}
		}
	return p;
}

VOID WINAPI FFT(complex<double> *TD,complex<double> * FD,int power)
{
	LONG count;
	int i,j,k;
	int bfsize,p;
	double angle;
	complex<double> *W;
	complex<double> *X1,*X2,*X;
	
	count = 1<<power;
	W= new complex<double>[count/2];
	X1= new complex<double>[count];
	X2= new complex<double>[count];

	for (i=0;i<count/2;i++) {
		angle=-i*PI*2/count;
		W[i]=complex<double>(cos(angle),sin(angle));
	}

	memcpy(X1,TD,sizeof(complex<double>)*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] = X1[i+p] + X1[i+p+bfsize/2];
//				X2[i+p+bfsize/2] = (X1[i+p] - X1[i+p+bfsize/2]) * W[i*(1<<k)];
//			
//		}}
//		X = X1;
//		X1= X2;
//		X2= X;
//	}

// 下面这段函数使用公式中的系数矩阵
	int q =0;
	for (k=0;k<power;k++) {
		bfsize=1<<(power-k);
		for (j=0;j<1<<k;j++) {
			p=j*bfsize;
			for (i=0;i<bfsize/2;i++) {
				X2[i+p] = X1[i+p] + X1[i+p+bfsize/2]* W[findq(i+p,power,k+1)*(bfsize/2)];
				X2[i+p+bfsize/2] = X1[i+p] - (X1[i+p+bfsize/2]) * W[findq(i+p,power,k+1)*(bfsize/2)];		
		}}
		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];
	}

	delete W;
	delete X1;
	delete X2;


	return;
}

VOID WINAPI IFFT(complex <double> *FD,complex <double> * TD,int power)
{
	LONG count;
	int i;
	complex<double> *X;
	count = 1<<power;

	X = new complex<double> [count];

	memcpy(X,FD,sizeof(complex<double>)*count);
	for (i=0;i<count;i++) {
		X[i]=complex<double>(X[i].real(),-X[i].imag());
	}
	FFT(X,TD,power);
	for (i=0;i<count;i++) {
		TD[i]=complex<double>(TD[i].real()/count,-TD[i].imag()/count);
	}
	delete X;
	
}

BOOL WINAPI Fourier(LPSTR lpDIB)
{
	LPBYTE lpSrc;
	LPSTR  lpDIBBits;
	LONG lWidth ,lHeight;

	double dSpectral;
	int p;
	BYTE PixelValue;

	LONG i,j;

	LONG w,h;

	int wp,hp;

	WORD wNumColors;
	LPBITMAPINFOHEADER lpbmi;

	LONG lLineBytes;

	lpbmi = (LPBITMAPINFOHEADER)lpDIB;
	lWidth=::DIBWidth(lpDIB);	
	lHeight=::DIBHeight(lpDIB);

	lpDIBBits=::FindDIBBits(lpDIB);

	lLineBytes =WIDTHBYTES ( lWidth*lpbmi->biBitCount);

	wNumColors=::DIBNumColors(lpDIB);

	w=h=1;
	wp=hp=0;

	while (w*2<=lWidth) {
		w*=2;
		wp++;
	}
	while (h*2<=lHeight) {
		h*=2;
		hp++;
	}
	complex<double> *TD = new complex<double>[w*h];
	complex<double> *FD = new complex<double>[w*h];

	for (i=0;i<h;i++) {
		for (j=0;j<w;j++) {
			if (wNumColors==256) {
				lpSrc=(LPBYTE)lpDIBBits+ lLineBytes * (lHeight-1-i) + j;
				//TD[j+w*i] = complex<double>((*(lpSrc)*pow(-1,i+j)),0);//
				TD[j + w * i] = complex<double>(*(lpSrc), 0);
			}
			else if (wNumColors=0) {
				p=j*3+i*lLineBytes;
				PixelValue=(BYTE) (0.299*(float)lpDIBBits[p+2] + 0.587*(float) lpDIBBits[p+1]
					+ 0.114 *(float)lpDIBBits[p]+0.1);
				//TD[j+w*i] = complex<double>( PixelValue * pow(-1,i+j),0);
				TD[j + w * i] = complex<double>(PixelValue, 0);
			}
			else
			{
				AfxMessageBox("Only 256 bmp and truecolor bmp");
				return false;
			}
		}
	}
	for (i=0;i<h;i++) {
			FFT(&TD[w*i],&FD[w*i],wp);
	}
	
	for (i=0;i<h;i++) {
		for (j=0;j<w;j++) {
			TD[i+h*j]= FD[j+w*i];
		}
	}
	
	for (i=0;i<w;i++) {
			FFT(&TD[i*h],&FD[i*h],hp);
	}

	for (i=0;i<h;i++) {
		for (j=0;j<w;j++) {
			dSpectral = sqrt(FD[j*h+i].real() * FD[j*h+i].real() +
								FD[j*h+i].imag() * FD[j*h+i].imag())/100;
			if (dSpectral>255) {
				dSpectral=255;
			}
			if (wNumColors==256) {
				// 指向DIB第(i<h/2 ? i+h/2 : i-h/2)行,第(j<w/2 ? j+w/2 : j-w/2)个象素的指针
				// 此处不直接取i和j,是为了将变换后的原点移到中心
				//lpSrc=(LPBYTE)lpDIBBits + lLineBytes * (lHeight-1-i) +j ;
				lpSrc = (LPBYTE)lpDIBBits + lLineBytes * 
					(lHeight - 1 - (i<h/2 ? i+h/2 : i-h/2)) + (j<w/2 ? j+w/2 : j-w/2);
				*lpSrc=(BYTE)dSpectral;
			}
			else
			{
				//lpSrc=(LPBYTE)lpDIBBits + lLineBytes * (lHeight-1-i) + 3*j;
				lpSrc = (LPBYTE)lpDIBBits + lLineBytes * 
					(lHeight - 1 - (i<h/2 ? i+h/2 : i-h/2)) + 3*(j<w/2 ? j+w/2 : j-w/2);
				*(lpSrc++)= (BYTE)dSpectral;
				*(lpSrc++)=0;
				*(lpSrc++)=0;
			}
		}
	}
	delete TD;
	delete FD;


	return TRUE;	
}

BOOL WINAPI IFourier(LPSTR lpDIB)
{
	LPBYTE lpSrc;
	LPSTR  lpDIBBits;
	LONG lWidth ,lHeight;

	double dSpectral;
	int p;
	BYTE PixelValue;

	LONG i,j;

	LONG w,h;

	int wp,hp;

	WORD wNumColors;
	LPBITMAPINFOHEADER lpbmi;

	LONG lLineBytes;

	lpbmi = (LPBITMAPINFOHEADER)lpDIB;
	lWidth=::DIBWidth(lpDIB);	
	lHeight=::DIBHeight(lpDIB);

	lpDIBBits=::FindDIBBits(lpDIB);

	lLineBytes =WIDTHBYTES ( lWidth*lpbmi->biBitCount);

	wNumColors=::DIBNumColors(lpDIB);

	w=h=1;
	wp=hp=0;

	while (w*2<=lWidth) {
		w*=2;
		wp++;
	}
	while (h*2<=lHeight) {
		h*=2;
		hp++;
	}
	complex<double> *TD = new complex<double>[w*h];
	complex<double> *FD = new complex<double>[w*h];

	for (i=0;i<h;i++) {
		for (j=0;j<w;j++) {
			if (wNumColors==256) {
				lpSrc=(LPBYTE)lpDIBBits+ lLineBytes * (lHeight-1-i) + j;
				TD[j+w*i] = complex<double>((*(lpSrc)),0);//*pow(-1,i+j)
			}
			else if (wNumColors=0) {
				p=j*3+i*lLineBytes;
				PixelValue=(BYTE) (0.299*(float)lpDIBBits[p+2] + 0.587*(float) lpDIBBits[p+1]
					+ 0.114 *(float)lpDIBBits[p]+0.1);
				TD[j+w*i] = complex<double>( PixelValue,0);// * pow(-1,i+j),0);
			}
			else
			{
				AfxMessageBox("Only 256 bmp and truecolor bmp");
				return false;
			}
		}
	}
	for (i=0;i<h;i++) {
			FFT(&TD[w*i],&FD[w*i],wp);
	}
	
	for (i=0;i<h;i++) {
		for (j=0;j<w;j++) {
			TD[i+h*j]= FD[j+w*i];
		}
	}
	
	for (i=0;i<w;i++) {
			FFT(&TD[i*h],&FD[i*h],hp);
	}
/*
	for (i=0;i<h;i++) {
		for (j=0;j<w;j++) {
			dSpectral = sqrt(FD[j*h+i].real() * FD[j*h+i].real() +
								FD[j*h+i].imag() * FD[j*h+i].imag())/100;
			if (dSpectral>255) {
				dSpectral=255;
			}
			if (wNumColors==256) {
				lpSrc=(LPBYTE)lpDIBBits + lLineBytes * (lHeight-1-i) +j ;
				*lpSrc=(BYTE)dSpectral;
			}
			else
			{
				lpSrc=(LPBYTE)lpDIBBits + lLineBytes * (lHeight-1-i) + 3*j;
				*(lpSrc++)= (BYTE)dSpectral;
				*(lpSrc++)=0;
				*(lpSrc++)=0;
			}
		}
	}

  */
	for (i=0;i<h;i++) {
		for (j=0;j<w;j++) {
			//TD[i+h*j]=complex<double>( FD[j+w*i].real()/10000, FD[j+w*i].imag()/10000);
			TD[i+h*j]=FD[j+w*i];
		}
	}

	for (i=0;i<h;i++) {
			IFFT(&TD[w*i],&FD[w*i],wp);
	}
	
	for (i=0;i<h;i++) {
		for (j=0;j<w;j++) {
			TD[i+h*j]= FD[j+w*i];
		}
	}
	
	for (i=0;i<w;i++) {
			IFFT(&TD[i*h],&FD[i*h],hp);
	
	}
	for (i=0;i<h;i++) {
		for (j=0;j<w;j++) {
			dSpectral = sqrt(FD[j*h+i].real() * FD[j*h+i].real() +
								FD[j*h+i].imag() * FD[j*h+i].imag())/100;
			if (dSpectral>255) {
				dSpectral=255;
			}
			if (wNumColors==256) {
				lpSrc=(LPBYTE)lpDIBBits + lLineBytes * (lHeight-1-i) +j ;
				/**lpSrc=(BYTE)dSpectral;*/
				*lpSrc=(BYTE)FD[j*h+i].real();
			}
			else
			{
				lpSrc=(LPBYTE)lpDIBBits + lLineBytes * (lHeight-1-i) + 3*j;
				*(lpSrc++)= (BYTE)dSpectral;
				*(lpSrc++)=0;
				*(lpSrc++)=0;
			}
		}
	}
	delete TD;
	delete FD;


	return TRUE;	
}


/*************************************************************************
 *
 * 函数名称:
 *   Fourier()
 *
 * 参数:
 *   LPSTR lpDIBBits    - 指向源DIB图像指针
 *   LONG  lWidth       - 源图像宽度(象素数)
 *   LONG  lHeight      - 源图像高度(象素数)
 *
 * 返回值:
 *   BOOL               - 成功返回TRUE,否则返回FALSE。
 *
 * 说明:
 *   该函数用来对图像进行付立叶变换。
 *
 ************************************************************************/
BOOL WINAPI Fourier(LPSTR lpDIBBits, LONG lWidth, LONG lHeight)
{
	
	// 指向源图像的指针
	unsigned char*	lpSrc;
	
	// 中间变量
	double	dTemp;
	
	// 循环变量
	LONG	i;
	LONG	j;
	
	// 进行付立叶变换的宽度和高度(2的整数次方)
	LONG	w;
	LONG	h;
	
	int		wp;
	int		hp;
	
	// 图像每行的字节数
	LONG	lLineBytes;
	
	// 计算图像每行的字节数
	lLineBytes = WIDTHBYTES(lWidth * 8);
	
	// 赋初值
	w = 1;
	h = 1;
	wp = 0;
	hp = 0;
	
	// 计算进行付立叶变换的宽度和高度(2的整数次方)
	while(w * 2 <= lWidth)
	{
		w *= 2;
		wp++;
	}
	
	while(h * 2 <= lHeight)
	{
		h *= 2;
		hp++;
	}
	
	// 分配内存
	complex<double> *TD = new complex<double>[w * h];
	complex<double> *FD = new complex<double>[w * h];
	
	// 行
	for(i = 0; i < h; i++)
	{
		// 列
		for(j = 0; j < w; j++)
		{
			// 指向DIB第i行,第j个象素的指针
			lpSrc = (unsigned char*)lpDIBBits + lLineBytes * (lHeight - 1 - i) + j;
			
			// 给时域赋值
			TD[j + w * i] = complex<double>(*(lpSrc), 0);
		}
	}
	
	for(i = 0; i < h; i++)
	{
		// 对y方向进行快速付立叶变换
		FFT(&TD[w * i], &FD[w * i], wp);
	}
	
	// 保存变换结果
	for(i = 0; i < h; i++)
	{
		for(j = 0; j < w; j++)
		{
			TD[i + h * j] = FD[j + w * i];
		}
	}
	
	for(i = 0; i < w; i++)
	{
		// 对x方向进行快速付立叶变换
		FFT(&TD[i * h], &FD[i * h], hp);
	}
	
	// 行
	for(i = 0; i < h; i++)
	{
		// 列
		for(j = 0; j < w; j++)
		{
			// 计算频谱
			dTemp = sqrt(FD[j * h + i].real() * FD[j * h + i].real() + 
				         FD[j * h + i].imag() * FD[j * h + i].imag()) / 100;
			
			// 判断是否超过255
			if (dTemp > 255)
			{
				// 对于超过的,直接设置为255
				dTemp = 255;
			}
			
			// 指向DIB第(i<h/2 ? i+h/2 : i-h/2)行,第(j<w/2 ? j+w/2 : j-w/2)个象素的指针
			// 此处不直接取i和j,是为了将变换后的原点移到中心
			//lpSrc = (unsigned char*)lpDIBBits + lLineBytes * (lHeight - 1 - i) + j;
			lpSrc = (unsigned char*)lpDIBBits + lLineBytes * 
				(lHeight - 1 - (i<h/2 ? i+h/2 : i-h/2)) + (j<w/2 ? j+w/2 : j-w/2);
			
			// 更新源图像
			* (lpSrc) = (BYTE)(dTemp);
		}
	}
	
	// 删除临时变量
	delete TD;
	delete FD;
	
	// 返回
	return TRUE;
}

/*************************************************************************
 *
 * 函数名称:
 *   DCT()
 *
 * 参数:
 *   double * f				- 指向时域值的指针
 *   double * F				- 指向频域值的指针
 *   r						-2的幂数
 *
 * 返回值:
 *   无。
 *
 * 说明:
 *   该函数用来实现快速离散余弦变换。该函数利用2N点的快速付立叶变换
 * 来实现离散余弦变换。
 *
 ************************************************************************/
VOID WINAPI DCT(double *f, double *F, int r)
{
	// 离散余弦变换点数
	LONG	count;
	
	// 循环变量
	int		i;
	
	// 中间变量
	double	dTemp;
	
	complex<double> *X;
	
	// 计算离散余弦变换点数
	count = 1<<r;
	
	// 分配内存
	X = new complex<double>[count*2];
	
	// 赋初值为0
	memset(X, 0, sizeof(complex<double>) * count * 2);
	
	// 将时域点写入数组X
	for(i=0;i<count;i++)
	{
		X[i] = complex<double> (f[i], 0);
	}
	
	// 调用快速付立叶变换
	FFT(X,X,r+1);
	
	// 调整系数
	dTemp = 1/sqrt(count);
	
	// 求F[0]
	F[0] = X[0].real() * dTemp;
	
	dTemp *= sqrt(2);
	
	// 求F[u]	
	for(i = 1; i < count; i++)
	{
		F[i]=(X[i].real() * cos(i*PI/(count*2)) + X[i].imag() * sin(i*PI/(count*2))) * dTemp;
	}
	
	// 释放内存
	delete X;
}

/*************************************************************************
 *
 * 函数名称:
 *   IDCT()
 *
 * 参数:
 *   double * F				- 指向频域值的指针
 *   double * f				- 指向时域值的指针
 *   r						-2的幂数
 *
 * 返回值:
 *   无。
 *
 * 说明:
 *   该函数用来实现快速离散余弦反变换。该函数也利用2N点的快速付立叶变换
 * 来实现离散余弦反变换。
 *
 ************************************************************************/
VOID WINAPI IDCT(double *F, double *f, int r)
{
	// 离散余弦反变换点数
	LONG	count;
	
	// 循环变量
	int		i;
	
	// 中间变量
	double	dTemp, d0;
	
	complex<double> *X;
	
	// 计算离散余弦变换点数
	count = 1<<r;
	
	// 分配内存
	X = new complex<double>[count*2];
	
	// 赋初值为0
	memset(X, 0, sizeof(complex<double>) * count * 2);
	
	// 将频域变换后点写入数组X
	for(i=0;i<count;i++)
	{
		X[i] = complex<double> (F[i] * cos(i*PI/(count*2)), F[i] * sin(i*PI/(count*2)));
	}
	
	// 调用快速付立叶反变换
	IFFT(X,X,r+1);
	
	// 调整系数
	dTemp = sqrt(2.0/count);
	d0 = (sqrt(1.0/count) - dTemp) * F[0];
	
	// 计算f(x)
	for(i = 0; i < count; i++)
	{
		f[i] = d0 + X[i].real()* dTemp * 2 * count;
	}
	
	// 释放内存
	delete X;
}

/*************************************************************************
 *
 * 函数名称:
 *   DIBDct()
 *
 * 参数:
 *   LPSTR lpDIBBits    - 指向源DIB图像指针

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -