Skip to content

Instantly share code, notes, and snippets.

@wzpan
Last active December 20, 2021 09:13
Show Gist options
  • Save wzpan/9383590 to your computer and use it in GitHub Desktop.
Save wzpan/9383590 to your computer and use it in GitHub Desktop.
Perform FFT and IFFT operation on an image, based on FFTW and OpenCV 2.
# 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)
# -----------------------------------------------------------------------------
# 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)
/*
* 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;
}
# 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)
@wzpan
Copy link
Author

wzpan commented Mar 6, 2014

Project skeleton:

-- FFTW-OpenCV  /
        |
        |- FFT-CV.cxx
        |- CMakeLists.txt
        |- CMake  /
              |              
              |- FindFFTW.cmake
              |- CPackConfig.cmake

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment