wzpan
3/6/2014 - 6:30 AM

Perform FFT and IFFT operation on an image, based on FFTW and OpenCV 2.

Perform FFT and IFFT operation on an image, based on FFTW and OpenCV 2.

# Copyright (c) 2012 Marwan Abdellah <abdellah.marwan@gmail.com>

find_path(FFTW_INCLUDE_DIR "fftw3.h" 
  HINTS ${FFTW_ROOT}/include
  /usr/include
  /usr/local/include
  /opt/local/include 
)

find_library(FFTW_LIBRARIES NAMES fftw3 
  HINTS ${FFTW_ROOT}/lib
  PATHS /usr/lib /usr/local/lib /opt/local/lib
)

include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(FFTW DEFAULT_MSG FFTW_LIBRARIES FFTW_INCLUDE_DIR)

if(HWLOC_FOUND)
  message(STATUS "Found FFTW in ${FFTW_INCLUDE_DIR} ${FFTW_LIBRARIES}")
endif(HWLOC_FOUND)
/* 
 * FFT_CV.cxx:
 * Perform FFT and IFFT operation on an image
 *
 * Dependencies:
 * FFTW: >= 3
 * OpenCV: >= 2
 *
 * Author1:  Nashruddin Amin
 * Website: http://www.nashruddin.com
 * Author2:  Joseph Pan
 * Website: http://www.hahack.com
 */

#include <stdio.h>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <fftw3.h>

int main( int argc, char** argv )
{
    cv::Mat img1;
    cv::Mat img2;
    uchar *img1_data;
    uchar *img2_data;

    fftw_complex    *data_in;
    fftw_complex    *fft;        
    fftw_complex    *ifft;    
    fftw_plan       plan_f;
    fftw_plan       plan_b;
    
    int             width, height, step;
    int             i, j, k;
    
    // check for supplied argument
    if ( argc < 2 ) {
       fprintf( stderr, "Usage: fft_image <filename>\n" );
       return 1;
    }
    
    // load original image
    img1 = cv::imread( argv[1], 0 );
    
    // always check
    if ( !img1.data ) {
        fprintf( stderr, "Cannot load file %s!\n", argv[1] );
        return 1;
    }

    // create new image for IFFT result
    img2 = img1.clone();

    // get image properties
    width  	  = img1.size().width;
    height 	  = img1.size().height;
    step	  = img1.step;
    img1_data = ( uchar* ) img1.data;
    img2_data = ( uchar* ) img2.data;    
    
    // initialize arrays for fftw operations
    data_in = fftw_alloc_complex(width * height);
    fft     = fftw_alloc_complex(width * height);
    ifft    = fftw_alloc_complex(width * height);

    // create plans
    plan_f = fftw_plan_dft_1d( width * height, data_in, fft,  FFTW_FORWARD,  FFTW_ESTIMATE );
    plan_b = fftw_plan_dft_1d( width * height, fft,     ifft, FFTW_BACKWARD, FFTW_ESTIMATE );
    
    // load img1's data to fftw input
    for( i = 0, k = 0 ; i < height ; i++ ) {
        for( j = 0 ; j < width ; j++ ) {
            data_in[k][0] = ( double )img1_data[i * step + j];
            data_in[k][1] = 0.0;
            k++;
        }
    }
    
    // perform FFT
    fftw_execute( plan_f );
    
    // perform IFFT
    fftw_execute( plan_b );
    
    // normalize IFFT result
    for( i = 0 ; i < ( width * height ) ; i++ ) {
        ifft[i][0] /= ( double )( width * height );
    }
    
    // copy IFFT result to img2's data
    for( i = 0, k = 0 ; i < height ; i++ ) {
		for( j = 0 ; j < width ; j++ ) {
			img2_data[i * step + j] = ( uchar )ifft[k++][0];
		}
	}
    
    // display images
    cv::namedWindow( "original_image", CV_WINDOW_AUTOSIZE );
    cv::namedWindow( "IFFT", CV_WINDOW_AUTOSIZE );
    cv::imshow( "original_image", img1 );
    cv::imshow( "IFFT", img2 );

    char key;
    while (true) {
        key = cv::waitKey( 0 );
        if (27 == key)
            break;
    }	

    // free memory
    cv::destroyWindow( "original_image" );
    cv::destroyWindow( "IFFT" );
    img1.release();
    img2.release();
    fftw_destroy_plan( plan_f );
    fftw_destroy_plan( plan_b );
    fftw_free( data_in );
    fftw_free( fft );
    fftw_free( ifft );
    
    return 0;
}
# -----------------------------------------------------------------------------
# Author: Marwan Abdellah <abdellah.marwan@gmail.com>

# General CPack configuration 
# Info: http://www.itk.org/Wiki/CMake:Component_Install_With_CPack
# -----------------------------------------------------------------------------

# Package Name 
set(CPACK_PACKAGE_NAME "FFT_CV")

# Vendor 
set(CPACK_PACKAGE_VENDOR "ABDELLAH") 

# Summary 
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Simple application to test the FFTW library with OpenCV")

# Maintainer 
set(CPACK_PACKAGE_CONTACT "Marwan Abdellah <abdellah.marwan@gmail.com")

# Package version 
set(CPACK_PACKAGE_VERSION ${VERSION})
set(CPACK_PACKAGE_VERSION_MAJOR 1)
set(CPACK_PACKAGE_VERSION_MINOR 0)
set(CPACK_PACKAGE_VERSION_PATCH 0)

# Select package generator
if(MSVC)
  set(CPACK_GENERATOR "NSIS")
endif(MSVC)

if (${CMAKE_SYSTEM_NAME} MATCHES Linux)
  find_program(RPM_EXE rpmbuild)
  if(${RPM_EXE} MATCHES RPM_EXE-NOTFOUND)
    set(CPACK_GENERATOR "TGZ;DEB")
  else()
    set(CPACK_GENERATOR "TGZ;DEB;RPM")
  endif()
endif()

# Debian specific configuration (minimum)
set(CPACK_DEBIAN_PACKAGE_MAINTAINER "${CPACK_PACKAGE_CONTACT}")

# X11 dependency 
set(CPACK_DEBIAN_PACKAGE_DEPENDS "libfftw3-dev libopencv-dev")

# RPM specific configuration (minimum)
set(CPACK_RPM_PACKAGE_LICENSE "LGPL")
set(CPACK_RPM_PACKAGE_GROUP "Miscellaneous")
set(CPACK_RPM_PACKAGE_VERSION ${VERSION})

include(InstallRequiredSystemLibraries)
include(CPack)
# Copyright (c) 2012 Marwan Abdellah <abdellah.marwan@gmail.com>

# Minimum required CMake version 
cmake_minimum_required(VERSION 2.6)

# FFT 
PROJECT(FFT_CV)

# Add CMake modules 
SET(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/CMake)

# FFTW 
SET(FFTW_ROOT ${PROJECT_SOURCE_DIR}/../install)
FIND_PACKAGE(FFTW REQUIRED)

# OpenCV
SET(OpenCV_DIR ${PROJECT_SOURCE_DIR}/../install/share/OpenCV)
FIND_PACKAGE(OpenCV REQUIRED)

# Add the heade files to the include directories
INCLUDE_DIRECTORIES("${FFTW_INCLUDE_DIR} ${OpenCV_INCLUDE_DIRS}")

# Generate the executable 
ADD_EXECUTABLE(FFT_CV FFT_CV.cxx)

# Link aginst the FFTW libraries 
TARGET_LINK_LIBRARIES(FFT_CV ${FFTW_LIBRARIES} ${OpenCV_LIBS})

# Installation directory 
SET(CMAKE_INSTALL_PREFIX "${PROJECT_SOURCE_DIR}/../install" 
CACHE PATH "Install path prefix" FORCE)

# Packaging 
include(CPackConfig)