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

📄 fftanalysisdlg.cpp

📁 OpenCV
💻 CPP
字号:
// FftAnalysisDlg.cpp : implementation file
//

#include "stdafx.h"
#include "FftAnalysis.h"
#include "FftAnalysisDlg.h"
#include "cv.h"
#include "highgui.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CAboutDlg dialog used for App About

class CAboutDlg : public CDialog
{
public:
	CAboutDlg();

// Dialog Data
	//{{AFX_DATA(CAboutDlg)
	enum { IDD = IDD_ABOUTBOX };
	//}}AFX_DATA

	// ClassWizard generated virtual function overrides
	//{{AFX_VIRTUAL(CAboutDlg)
	protected:
	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
	//}}AFX_VIRTUAL

// Implementation
protected:
	//{{AFX_MSG(CAboutDlg)
	//}}AFX_MSG
	DECLARE_MESSAGE_MAP()
};

CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
	//{{AFX_DATA_INIT(CAboutDlg)
	//}}AFX_DATA_INIT
}

void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CAboutDlg)
	//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
	//{{AFX_MSG_MAP(CAboutDlg)
		// No message handlers
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CFftAnalysisDlg dialog

CFftAnalysisDlg::CFftAnalysisDlg(CWnd* pParent /*=NULL*/)
	: CDialog(CFftAnalysisDlg::IDD, pParent)
{
	//{{AFX_DATA_INIT(CFftAnalysisDlg)
		// NOTE: the ClassWizard will add member initialization here
	//}}AFX_DATA_INIT
	// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}

void CFftAnalysisDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CFftAnalysisDlg)
		// NOTE: the ClassWizard will add DDX and DDV calls here
	//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CFftAnalysisDlg, CDialog)
	//{{AFX_MSG_MAP(CFftAnalysisDlg)
	ON_WM_SYSCOMMAND()
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	ON_BN_CLICKED(IDC_OPEN_IMG, OnOpenImg)
	ON_BN_CLICKED(IDC_FFT_TRANSFORM, OnFftTransform)
	ON_BN_CLICKED(IDC_IMG_SHOW, OnImgShow)
	ON_BN_CLICKED(IDC_EXIT, OnExit)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CFftAnalysisDlg message handlers

BOOL CFftAnalysisDlg::OnInitDialog()
{
	CDialog::OnInitDialog();

	// Add "About..." menu item to system menu.

	// IDM_ABOUTBOX must be in the system command range.
	ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
	ASSERT(IDM_ABOUTBOX < 0xF000);

	CMenu* pSysMenu = GetSystemMenu(FALSE);
	if (pSysMenu != NULL)
	{
		CString strAboutMenu;
		strAboutMenu.LoadString(IDS_ABOUTBOX);
		if (!strAboutMenu.IsEmpty())
		{
			pSysMenu->AppendMenu(MF_SEPARATOR);
			pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
		}
	}

	// Set the icon for this dialog.  The framework does this automatically
	//  when the application's main window is not a dialog
	SetIcon(m_hIcon, TRUE);			// Set big icon
	SetIcon(m_hIcon, FALSE);		// Set small icon
	
	// TODO: Add extra initialization here
	
	return TRUE;  // return TRUE  unless you set the focus to a control
}

void CFftAnalysisDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
	if ((nID & 0xFFF0) == IDM_ABOUTBOX)
	{
		CAboutDlg dlgAbout;
		dlgAbout.DoModal();
	}
	else
	{
		CDialog::OnSysCommand(nID, lParam);
	}
}

// If you add a minimize button to your dialog, you will need the code below
//  to draw the icon.  For MFC applications using the document/view model,
//  this is automatically done for you by the framework.

void CFftAnalysisDlg::OnPaint() 
{
	if (IsIconic())
	{
		CPaintDC dc(this); // device context for painting

		SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);

		// Center icon in client rectangle
		int cxIcon = GetSystemMetrics(SM_CXICON);
		int cyIcon = GetSystemMetrics(SM_CYICON);
		CRect rect;
		GetClientRect(&rect);
		int x = (rect.Width() - cxIcon + 1) / 2;
		int y = (rect.Height() - cyIcon + 1) / 2;

		// Draw the icon
		dc.DrawIcon(x, y, m_hIcon);
	}
	else
	{
		CDialog::OnPaint();
	}
}

// The system calls this to obtain the cursor to display while the user drags
//  the minimized window.
HCURSOR CFftAnalysisDlg::OnQueryDragIcon()
{
	return (HCURSOR) m_hIcon;
}


void CFftAnalysisDlg::ShiftDFT(CvArr * src_arr, CvArr * dst_arr)
{
	CvMat * tmp;
    CvMat q1stub, q2stub;
    CvMat q3stub, q4stub;
    CvMat d1stub, d2stub;
    CvMat d3stub, d4stub;
    CvMat * q1, * q2, * q3, * q4;
    CvMat * d1, * d2, * d3, * d4;

    CvSize size = cvGetSize(src_arr);
    CvSize dst_size = cvGetSize(dst_arr);
    int cx, cy;

    if(dst_size.width != size.width || 
       dst_size.height != size.height)
	{
        cvError( CV_StsUnmatchedSizes, "cvShiftDFT", 
			     "Source and Destination arrays must have equal sizes", __FILE__, __LINE__ );   
    }

    if(src_arr==dst_arr)
	{
        tmp = cvCreateMat(size.height/2, size.width/2, cvGetElemType(src_arr));
    }
    
    cx = size.width/2;
    cy = size.height/2; // image center

    q1 = cvGetSubRect( src_arr, &q1stub, cvRect(0,0,cx, cy) );
    q2 = cvGetSubRect( src_arr, &q2stub, cvRect(cx,0,cx,cy) );
    q3 = cvGetSubRect( src_arr, &q3stub, cvRect(cx,cy,cx,cy) );
    q4 = cvGetSubRect( src_arr, &q4stub, cvRect(0,cy,cx,cy) );
    d1 = cvGetSubRect( src_arr, &d1stub, cvRect(0,0,cx,cy) );
    d2 = cvGetSubRect( src_arr, &d2stub, cvRect(cx,0,cx,cy) );
    d3 = cvGetSubRect( src_arr, &d3stub, cvRect(cx,cy,cx,cy) );
    d4 = cvGetSubRect( src_arr, &d4stub, cvRect(0,cy,cx,cy) );

    if(src_arr!=dst_arr)
	{
        if( !CV_ARE_TYPES_EQ( q1, d1 ))
		{
            cvError( CV_StsUnmatchedFormats, "cvShiftDFT", 
				"Source and Destination arrays must have the same format", __FILE__, __LINE__ ); 
        }
        cvCopy(q3, d1, 0);
        cvCopy(q4, d2, 0);
        cvCopy(q1, d3, 0);
        cvCopy(q2, d4, 0);
    }
    else{
        cvCopy(q3, tmp, 0);
        cvCopy(q1, q3, 0);
        cvCopy(tmp, q1, 0);
        cvCopy(q4, tmp, 0);
        cvCopy(q2, q4, 0);
        cvCopy(tmp, q2, 0);

		cvReleaseMat(&tmp);
    }
}

void CFftAnalysisDlg::OnOpenImg() 
{
	
    CString filename;	
    char szFileFilter[] = 
		    "JPG File(*.jpg)|*.jpg|"
		    "BMP File(*.bmp)|*.bmp|"
		    "TIFFFile(*.tiff)|*.tiff|" 
			"TIF File(*.tif)|*.tif|" ;
	
	CFileDialog dlg(TRUE, NULL, NULL, OFN_HIDEREADONLY, szFileFilter);
	if(dlg.DoModal()== IDOK)
	{
	  CString filename = dlg.GetPathName();
      	   
	  img_original = cvLoadImage(filename, CV_LOAD_IMAGE_GRAYSCALE);	  
	  cvNamedWindow("Original Image", CV_WINDOW_AUTOSIZE);
	  cvShowImage(  "Original Image", img_original );
	}  
}

                     
void CFftAnalysisDlg::OnFftTransform() 
{

	IplImage * realInput;
    IplImage * imaginaryInput;
    IplImage * complexInput;
    int dft_M, dft_N;
    CvMat* dft_A, tmp;

	IplImage * image_Im;
    double m, M;

	realInput = cvCreateImage( cvGetSize(img_original), IPL_DEPTH_64F, 1);
    imaginaryInput = cvCreateImage( cvGetSize(img_original), IPL_DEPTH_64F, 1);
    complexInput = cvCreateImage( cvGetSize(img_original), IPL_DEPTH_64F, 2);

	cvScale(img_original, realInput, 1.0, 0.0);
    cvZero(imaginaryInput);
    cvMerge(realInput, imaginaryInput, NULL, NULL, complexInput);

    dft_M = cvGetOptimalDFTSize( img_original->height - 1 );
    dft_N = cvGetOptimalDFTSize( img_original->width - 1 );

    dft_A = cvCreateMat( dft_M, dft_N, CV_64FC2 );
    img_transform = cvCreateImage( cvSize(dft_N, dft_M), IPL_DEPTH_64F, 1);
    image_Im = cvCreateImage( cvSize(dft_N, dft_M), IPL_DEPTH_64F, 1);


	// copy A to dft_A and pad dft_A with zeros
    cvGetSubRect( dft_A, &tmp, cvRect(0,0, img_original->width, img_original->height));
    cvCopy( complexInput, &tmp, NULL );
    cvGetSubRect( dft_A, &tmp, cvRect(img_original->width,0, dft_A->cols - img_original->width,img_original->height));
    

    // no need to pad bottom part of dft_A with zeros because of
    // use nonzero_rows parameter in cvDFT() call below

    cvDFT( dft_A, dft_A, CV_DXT_FORWARD, complexInput->height );

	// Split Fourier in real and imaginary parts
    cvSplit( dft_A, img_transform, image_Im, 0, 0 );

    // 计算功率谱 Mag = sqrt(Re^2 + Im^2)
    cvPow( img_transform, img_transform, 2.0);
    cvPow( image_Im, image_Im, 2.0);
    cvAdd( img_transform, image_Im, img_transform, NULL);
    cvPow( img_transform, img_transform, 0.5 );   // 你说的系数就在这个img_transform里面

    // 计算 log(1 + Mag)
    cvAddS( img_transform, cvScalarAll(1.0), img_transform, NULL ); // 1 + Mag
    cvLog( img_transform, img_transform ); // log(1 + Mag)


    // 重新安排四个象限,使得原点在图像中心
    ShiftDFT( img_transform, img_transform );

	// 调整显示象素的区间,保证最大值为白色,最小值为黑色
    cvMinMaxLoc(img_transform, &m, &M, NULL, NULL, NULL);
    cvScale(img_transform, img_transform, 1.0/(M-m), 1.0*(-m)/(M-m));

	//释放内存
	cvReleaseImage(&realInput);
	cvReleaseImage(&imaginaryInput);
	cvReleaseImage(&complexInput);
	cvReleaseImage(&image_Im);

	cvReleaseMat(&dft_A);
}

void CFftAnalysisDlg::OnImgShow() 
{
	cvNamedWindow("magnitude", 0);
    cvShowImage("magnitude", img_transform);
	
}

void CFftAnalysisDlg::OnExit() 
{
    //释放内存,销毁显示窗口
	cvReleaseImage(&img_transform);
	cvReleaseImage(&img_original);

	cvDestroyAllWindows();
}

⌨️ 快捷键说明

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