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

📄 transform_dct.cpp

📁 将数字图像处理的一般算法都集中在一个MFC的框架中
💻 CPP
字号:
#include "stdafx.h"
#include "transform_DCT.h"
#include "math.h"

transform_DCT::transform_DCT()
{
	pDctBuff = NULL;
}

transform_DCT::transform_DCT(CSize size, int nBitCount, LPRGBQUAD lpColorTable, unsigned char *pImgData):
Transform_FFT(size, nBitCount, lpColorTable, pImgData)
{
	pDctBuff = NULL;
}

transform_DCT::~transform_DCT()
{
	if (pDctBuff != NULL)
	{
		delete[] pDctBuff;
		pDctBuff = NULL;
	}
}
/**********************************************************************
 *
 * 函数名称:
 * DCT()
 *
 * 参数:
 * double *f 时域数据指针
 * double *F 频域数据指针
 * int r 高度
 *
 * 返回值:
 * void
 *
 * 说明:
 * 利用快速傅立叶变换实现快速离散余弦变换
 *
 **********************************************************************/
void transform_DCT::DCT(double *f, double *F, int r)
{
	
	int	count;			// 离散余弦变换点数	
	int		i;				// 循环变量	
	double	dTemp;	
	
	count = 1<<r;			// 计算离散余弦变换点数	
	ComplexNumber *array = new ComplexNumber[count*2];	
	memset(array, 0, sizeof(ComplexNumber) * count * 2);	// 赋初值为0
	
	// 将时域点写入数组array
	for(i=0;i<count;i++)
	{
		array[i].real = (float)f[i];
		array[i].imag = 0;
	}

	FFT1D(array, count * 2);// 调用快速傅立叶变换		
	
	dTemp = 1 / sqrt(count);	// 调整系数		
	F[0] = array[0].real * dTemp;	// 求F[0]	
	dTemp *= sqrt(2);
	
	// 求F[u]	
	for(i = 1; i < count; i++)
	{
		F[i] = (array[i].real * cos(i*PI/(count*2)) + array[i].imag * 
			sin(i*PI/(count*2))) * dTemp;
	}
	
	delete[] array;
}
/**********************************************************************
 *
 * 函数名称:
 * ImgDCT()
 *
 * 参数:
 * 无
 *
 * 返回值:
 * void
 *
 * 说明:
 * 实现图像的离散余弦变换
 *
 **********************************************************************/
void transform_DCT::ImgDCT()
{
    unsigned char*	pSrc;	// 指向源图像的指针	
	unsigned char*  pDst;
	int	i,j;				// 循环变量
	double	dTemp;

	if(m_pImgDataOut!=NULL)
	{
		delete []m_pImgDataOut;
		m_pImgDataOut=NULL;
	}
	//计算图像每行的字节数
   	int lineByte=(m_imgWidth*m_nBitCount/8+3)/4*4;

	if(m_nBitCount!=8)
	{
		AfxMessageBox("只能处理8位灰度图像!");
		return ;
	}
	//分配内存,以保存新图像
	m_nBitCountOut=m_nBitCount;
    int lineByteOut=(m_imgWidth*m_nBitCountOut/8+3)/4*4;
	if (!m_pImgDataOut)
	{
		//为处理后的图像分配内存空间
		m_pImgDataOut=new unsigned char[lineByteOut*m_imgHeight];
	}
	int pixelByte=m_nBitCountOut/8;
	for(i=0; i<m_imgHeight; i++){
		for(j=0; j<m_imgWidth*pixelByte; j++)
			*(m_pImgDataOut+i*lineByteOut+j)= *(m_pImgData+i*lineByteOut+j);
	}
		
	// 赋初值
	w = 1;
	h = 1;
	wp = 0;
	hp = 0;
	
	// 计算进行离散余弦变换的宽度和高度(2的整数次方)
	while(w * 2 <= m_imgWidth)
	{
		w *= 2;
		wp++;
	}
	
	while(h * 2 <= m_imgHeight)
	{
		h *= 2;
		hp++;
	}
	
	double *f = new double[w * h];
	pDctBuff = new double[w * h];
	double *F = pDctBuff;
	
	
	for(i = 0; i < h; i++)			// 行
	{		
		for(j = 0; j < w; j++)		// 列
		{
			// 指向DIB第i行,第j个象素的指针
			pSrc = (unsigned char*)m_pImgData + lineByte * (m_imgHeight - 1 - i) + j;
			
			// 给时域赋值
			f[j + i * w] = *(pSrc);
		}
	}
	
	for(i = 0; i < h; i++)
	{
		// 对y方向进行离散余弦变换
		DCT(&f[w * i], &F[w * i], wp);
	}
	
	// 保存计算结果
	for(i = 0; i < h; i++)
	{
		for(j = 0; j < w; j++)
		{
			f[j * h + i] = F[j + w * i];
		}
	}
	
	for(j = 0; j < w; j++)
	{
		// 对x方向进行离散余弦变换
		DCT(&f[j * h], &F[j * h], hp);
	}	
	
	for(i = 0; i < h; i++)			// 行
	{
		for(j = 0; j < w; j++)		// 列
		{
			//指向新DIB第i行第j列的像素的指针
			pDst = m_pImgDataOut + lineByte * (m_imgHeight -1 - i) + j;

			dTemp = fabs(F[j*h+i]);	// 计算频谱
			
			// 判断是否超过255
			if (dTemp > 255)
			{
				dTemp = 255;
			}
			// 复制新DIB位图的像素值
			*pDst=(BYTE)(dTemp);
		}
	}
	m_imgWidthOut=m_imgWidth;
	m_imgHeightOut=m_imgHeight;
	delete[] f;
}

/*************************************************************************
* 函数名称:
*   IDCT()
* 参数:
*   double * F	- 指向频域值的指针
*   double * f	- 指向时域值的指针
*   r-2的幂数
* 返回值:
*   无。
* 说明:
*   该函数用来实现快速离散余弦反变换。该函数也利用2N点的快速付立叶变换
* 来实现离散余弦反变换。
************************************************************************/
void transform_DCT::IDCT(double *F, double *f, int r)
{
	LONG	count;			// 离散余弦反变换点数
	int		i;				// 循环变量
	double	dTemp, d0;	

	count = 1<<r;			// 计算离散余弦变换点数
	ComplexNumber *array = new ComplexNumber[count*2];
	memset(array, 0, sizeof(ComplexNumber) * count * 2);	// 赋初值为0
	
	// 将频域变换后点写入数组array
	for(i=0;i<count;i++)
	{
		array[i].real = (float)(F[i] * cos(i*PI/(count*2)));
		array[i].imag = (float)(F[i] * sin(i*PI/(count*2)));
	}
	
	IFFT1D(array, count * 2);// 调用快速傅立叶反变换	
	
	// 调整系数
	dTemp = sqrt(2.0/count);
	d0 = (sqrt(1.0/count) - dTemp) * F[0];
	
	for(i = 0; i < count; i++)
	{
		f[i] = d0 + array[i].real * dTemp * 2 * count;
	}
	
	delete[] array;
}

/**********************************************************************
 *
 * 函数名称:
 * ImgIDCT()
 *
 * 参数:
 * 无
 *
 * 返回值:
 * void
 *
 * 说明:
 * 实现图像的离散余弦反变换
 *
 **********************************************************************/
void transform_DCT::ImgIDCT()
{
	if (pDctBuff == NULL)
	{
		AfxMessageBox("请先进行DCT变换!");
		return;
	}	
	unsigned char*  pDst;	// 指向时域图像的指针	
	int	i,j;	// 循环变量
	double	dTemp;

	if(m_pImgDataOut!=NULL)
	{
		delete []m_pImgDataOut;
		m_pImgDataOut=NULL;
	}
	//计算图像每行的字节数
   	int lineByte=(m_imgWidth*m_nBitCount/8+3)/4*4;

	//分配内存,以保存新图像
	m_nBitCountOut=m_nBitCount;
    int lineByteOut=(m_imgWidth*m_nBitCountOut/8+3)/4*4;
	if (!m_pImgDataOut)
	{
		//为处理后的图像分配内存空间
		m_pImgDataOut=new unsigned char[lineByteOut*m_imgHeight];
	}
	int pixelByte=m_nBitCountOut/8;
	for(i=0; i<m_imgHeight; i++){
		for(j=0; j<m_imgWidth*pixelByte; j++)
			*(m_pImgDataOut+i*lineByteOut+j)= *(m_pImgData+i*lineByteOut+j);
	}
	
	double *f = new double[w * h];
	double *F = pDctBuff;
	
	for(i = 0; i < h; i++)
	{
		// 对y方向进行离散余弦变换
		IDCT(&F[w * i], &f[w * i], wp);
	}
	
	// 保存计算结果
	for(i = 0; i < h; i++)
	{
		for(j = 0; j < w; j++)
		{
			F[j * h + i] = f[j + w * i];
		}
	}
	
	for(j = 0; j < w; j++)
	{
		// 对x方向进行离散余弦变换
		IDCT(&F[j * h], &f[j * h], hp);
	}	
	
	for(i = 0; i < h; i++)			// 行
	{
		for(j = 0; j < w; j++)		// 列
		{
			//指向新DIB第i行第j列的像素的指针
			pDst = m_pImgDataOut + lineByte * (m_imgHeight -1 - i) + j;

			dTemp = fabs(f[i*h+j]);	// 计算频谱,转置操作
			
			// 判断是否超过255
			if (dTemp > 255)
			{
				dTemp = 255;
			}
			// 复制新DIB位图的像素值
			*pDst=(BYTE)(dTemp);
		}
	}
	m_imgWidthOut=m_imgWidth;
	m_imgHeightOut=m_imgHeight;
	delete[] f;
}

⌨️ 快捷键说明

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