65.9K
CodeProject 正在变化。 阅读更多。
Home

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

starIconstarIconstarIconstarIconemptyStarIcon

4.00/5 (4投票s)

2017年5月11日

CPOL

2分钟阅读

viewsIcon

17943

downloadIcon

593

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

引言

基于GUI的二维离散傅里叶变换(2D-DFT)实现,用于处理大小为NxN(N为行数和列数,例如:256x256)的彩色BMP图像。GUI2DFT是一个用VC++实现的简单工具,它将彩色图像进行2D-DFT变换,并以RGB颜色显示结果图像。

背景

离散傅里叶变换(DFT)对于任何在专科或本科学习图像处理课程的学生来说都不陌生。互联网上有大量参考资料可以帮助理解DFT的工作原理。离散傅里叶变换在图像处理应用中的一些主要优点在于:

  1. 图像分析
  2. 图像过滤
  3. 图像重建
  4. 图像压缩

等等。

当我们将快速傅里叶变换(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];
    }

实现

所涉及的步骤如下:

  1. 读取BMP 24bpp彩色图像
  2. 将RGB通道分离为单独的NxN大小的图像
  3. 对这3个NxN大小的R、G和B图像执行DFT计算
  4. 最后通过组合所有3个单独计算的图像来显示dft.bmp彩色图像

DFT2GUI应用程序

对NxN输入图像(彩色BMP 24bpp)先逐行再逐列计算一维DFT,然后将低频值移到图像中心。并提供带有一些用户菜单控件的GUI。

VC++源代码在本帖中提供。

局限性

目前,计算速度较慢。因为该实现仅用于学习目的,不适合任何实时应用。

GUI

结果

历史

这是我的第一篇文章。欢迎提出任何建议。

© . All rights reserved.