彩色图像的 2D-DFT - VC++ GUI 实现





4.00/5 (4投票s)
彩色图像的 2D DFT - GUI 实现
引言
基于GUI的二维离散傅里叶变换(2D-DFT)实现,用于处理大小为NxN(N为行数和列数,例如:256x256)的彩色BMP图像。GUI2DFT
是一个用VC++实现的简单工具,它将彩色
图像进行2D-DFT变换,并以RGB颜色显示结果图像。
背景
离散傅里叶变换(DFT)对于任何在专科或本科学习图像处理课程的学生来说都不陌生。互联网上有大量参考资料可以帮助理解DFT的工作原理。离散傅里叶变换在图像处理应用中的一些主要优点在于:
- 图像分析
- 图像过滤
- 图像重建
- 图像压缩
等等。
当我们将快速傅里叶变换(FFT)和离散傅里叶变换(DFT)进行比较时,FFT会考虑所有频率来形成图像,而DFT只是FFT的最简单版本,并没有考虑整个频率范围,而只是一组足以描述空间域中图像的样本。
在空间域中,像素数量与频域中的频率数量类似。因此,用于分析的图像文件大小在两个域中都是相同的。
假设图像大小为NxM,其中N是像素值的行数,M是像素值的列数,则计算图像DFT的公式为:
对于NxN大小(假设它是一个正方形图像,行数和列数相同)的图像,二维DFT为:
Using the Code
STEP1:
//Method open bmp file separates header, raw data is stored in an array
int bmpfile::BmpfileRead(const char *fname_s)
{
int bpp_check = 0;
fopen_s(&fp_read_bmp,fname_s,"rb");
if (fp_read_bmp == NULL)
{
//cout << "Error opening in file ";
return -1;
}
...
//Separately allocate memory to read Red, Blue, and Green bands.
//Red
image_r = new unsigned char*[iwidth];
for(unsigned int i = 0; i < iheight; ++i)
image_r[i] = new unsigned char[iheight];
if (image_r == NULL)
{
sprintf_s(buflog, 25, "image_t error\n");
return -1;
}
//Green
image_g = new unsigned char*[iwidth];
for(unsigned int i = 0; i < iheight; ++i)
image_g[i] = new unsigned char[iheight];
if (image_g == NULL)
{
sprintf_s(buflog, 25, "image_t error\n");
return -1;
}
//Blue
image_b = new unsigned char*[iwidth];
for(unsigned int i = 0; i < iheight; ++i)
image_b[i] = new unsigned char[iheight];
if (image_b == NULL)
{
sprintf_s(buflog, 25, "image_t error\n");
return -1;
}
...
}
STEP2:
//Below code snippet is used to calculate dft for a single row data from the 2d image.
bool Dft::dft_oneD(int *x, int r)
{
int n,l;
double c1,c2,twedle,sp1=0.0,sp2=0.0;
for(l=0;l<r;l++)
{
for(n=0; n<r; n++){
twedle = 2.0*(3.141592653589)*n*l/r;
c1 = *(x+n)*cos(twedle);
c2 = *(x+n)*sin(-twedle);
sp1 = sp1+c1;
sp2 = sp2+c2;
}
yy[l].r = sp1;
yy[l].img = sp2;
sp1 = 0.0;
sp2 = 0.0;
}
return true;
}
STEP3:
//Perform row vise calculation first and then column vise, save the result in to separate 2d array
...
for(m=0;m<bfp->iwidth;m++)
{
YR[n][m] = yi[m].r;
YI[n][m] = yi[m].img;
if(YR[n][m] == YR[n][m]*(-1)) YR[n][m]*=(-1);
if(YI[n][m] == YI[n][m]*(-1)) YI[n][m]*=(-1);
RY[n][m] = (int) abs(YR[n][m]*YR[n][m] + YI[n][m]*YI[n][m]);
RY[n][m] = (int)sqrt(RY[n][m]*1.0)/bfp->iwidth;
}
STEP4:
//write to output bmp image file
for(unsigned int j = 0; j != bfp->iheight; ++j)
{
for(unsigned int i = 0; i != bfp->iwidth; ++i)
{
bfp->image_r[j][i] = RY[j][i];
bfp->image_g[j][i] = GY[j][i];
bfp->image_b[j][i] = BY[j][i];
}
}
if(output_file != NULL)
{
bfp->BmpfileWrite(output_file);
}
else
{
//OUTPUT FILE
bfp->BmpfileWrite("dft.bmp");
}
//clean any resources used
for(unsigned int i = 0; i < bfp->iwidth; ++i)
{
delete [] RY[i];
delete [] GY[i];
delete [] BY[i];
}
实现
所涉及的步骤如下:
- 读取BMP 24bpp彩色图像
- 将RGB通道分离为单独的NxN大小的图像
- 对这3个NxN大小的R、G和B图像执行DFT计算
- 最后通过组合所有3个单独计算的图像来显示dft.bmp彩色图像
DFT2GUI应用程序
对NxN输入图像(彩色BMP 24bpp)先逐行再逐列计算一维DFT,然后将低频值移到图像中心。并提供带有一些用户菜单控件的GUI。
VC++源代码在本帖中提供。
局限性
目前,计算速度较慢。因为该实现仅用于学习目的,不适合任何实时应用。
GUI
结果
历史
这是我的第一篇文章。欢迎提出任何建议。