Skip to content

Commit

Permalink
ENH: Add 1D FFT Example
Browse files Browse the repository at this point in the history
  • Loading branch information
tbirdso committed May 20, 2022
1 parent f752d81 commit 0c7d8ef
Show file tree
Hide file tree
Showing 9 changed files with 169 additions and 1 deletion.
15 changes: 14 additions & 1 deletion src/Filtering/FFT/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,17 @@
add_example(FilterImageInFourierDomain)
add_example(ComputeFFTInOneDimension)
compare_to_baseline(
PYTHON_ONLY
EXAMPLE_NAME ComputeFFTInOneDimension
TEST_NAME ComputeFFTInOneDimensionModulusBaselineComparison
BASELINE_PREFIX MouseLiver1DFFTModulusOutputBaseline
)
compare_to_baseline(
PYTHON_ONLY
EXAMPLE_NAME ComputeFFTInOneDimension
TEST_NAME ComputeFFTInOneDimensionPhaseBaselineComparison
BASELINE_PREFIX MouseLiver1DFFTPhaseOutputBaseline
)

compare_to_baseline(
EXAMPLE_NAME FilterImageInFourierDomain
BASELINE_PREFIX OutputBaseline
Expand Down
23 changes: 23 additions & 0 deletions src/Filtering/FFT/ComputeFFTInOneDimension/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
cmake_minimum_required(VERSION 3.16.3)

project(ComputeFFTInOneDimension)

find_package(ITK REQUIRED)
include(${ITK_USE_FILE})

install(FILES Code.py CMakeLists.txt
DESTINATION share/ITKSphinxExamples/Code/Filtering/FFT/ComputeFFTInOneDimension
COMPONENT Code
)

enable_testing()

if(ITK_WRAP_PYTHON)
find_package(PythonInterp REQUIRED)
add_test(NAME ComputeFFTInOneDimensionPython
COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/Code.py
${CMAKE_CURRENT_BINARY_DIR}/MouseLiverRF.mha
${CMAKE_CURRENT_BINARY_DIR}/MouseLiver1DFFTModulusOutputPython.mha
${CMAKE_CURRENT_BINARY_DIR}/MouseLiver1DFFTPhaseOutputPython.mha
)
endif()
56 changes: 56 additions & 0 deletions src/Filtering/FFT/ComputeFFTInOneDimension/Code.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
#!/usr/bin/env python

# Copyright NumFOCUS
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0.txt
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

import itk
import argparse

parser = argparse.ArgumentParser(description="Compute Inverse FFT Of Image.")
parser.add_argument("input_path", nargs=1, type=str)
parser.add_argument("modulus_output_path", nargs=1, type=str)
parser.add_argument("phase_output_path", nargs=1, type=str)
parser.add_argument("fft_direction", nargs="?", default=0, type=int)
args = parser.parse_args()

# Read input image
pixel_type = itk.F
image = itk.imread(args.input_path[0], pixel_type=pixel_type)
print(f"Read real input image of type {type(image)} and size {itk.size(image)}")

assert (
args.fft_direction < image.GetImageDimension()
), "FFT direction must be an image dimension"

# Perform FFT in given direction
padded_image = itk.fft_pad_image_filter(image)
print(f"Padded input image to size {itk.size(image)}")
print(f"Performing FFT along axis {args.fft_direction}")
complex_image = itk.forward1_dfft_image_filter(image, direction=args.fft_direction)
print(
f"Generated complex frequency image of type {type(complex_image)} and size {itk.size(complex_image)}"
)

# Shift image along FFT dimension to represent complex range (-f_B, +f_B]
shift = [0] * complex_image.GetImageDimension()
shift[args.fft_direction] = int(itk.size(complex_image)[args.fft_direction] / 2)
shift = [int(itk.size(complex_image)[args.fft_direction] / 2), 0]
shifted_image = itk.cyclic_shift_image_filter(complex_image, shift=shift)

# Write out modulus and phase images for visualization in PNG format
modulus_image = itk.complex_to_modulus_image_filter(shifted_image)
itk.imwrite(modulus_image, args.modulus_output_path[0])

phase_image = itk.complex_to_phase_image_filter(shifted_image)
itk.imwrite(phase_image, args.phase_output_path[0])
71 changes: 71 additions & 0 deletions src/Filtering/FFT/ComputeFFTInOneDimension/Documentation.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
:name: ComputeFFTInOneDimension

Compute Forward FFT In One Dimension
====================================

.. index::
single: Forward1DFFTImageFilter
single: ComplexToRealImageFilter
single: ComplexToImaginaryImageFilter
single: ComplexToModulusImageFilter
single: CyclicShiftImageFilter
single: ImageFileReader
single: ImageFileWriter

Synopsis
--------

Compute forward FFT of an image in one dimension.


Results
-------

.. figure:: MouseLiverRF.png
:scale: 50%
:alt: Input image

Input RF Ultrasound Image

.. figure:: MouseLiverModulusOutput.png
:scale: 50%
:alt: Modulus Image

Output Modulus Image

.. figure:: MouseLiverPhaseOutput.png
:scale: 50%
:alt: Phase Image

Output Phase Image

Output::

Read real input image of type <class 'itk.itkImagePython.itkImageF2'> and size itkSize2 ([1536, 128])
Padded input image to size itkSize2 ([1536, 128])
Performing FFT along axis 0
Generated complex frequency image of type <class 'itk.itkImagePython.itkImageCF2'> and size itkSize2 ([1536, 128])

Code
----

Python
......

.. literalinclude:: Code.py
:language: python
:lines: 1, 16-


Classes demonstrated
--------------------

.. breathelink:: itk::FFTPadImageFilter

.. breathelink:: itk::Forward1DFFTImageFilter

.. breathelink:: itk::CyclicShiftImageFilter

.. breathelink:: itk::ComplexToModulusImageFilter

.. breathelink:: itk::ComplexToPhaseImageFilter
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
bcbead186f60040a16fa7091598b2da7ead8f97935efcd078c285ede14a57b717d53f95ffb2db1df6235cc19be67f98e617fc63deb24a18c7278345fd9ba24f7
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
f59ba4947c6394fa1b1dc77ff123b53d61b676a2bcdfd16758b0cd2672360cd3ed631e49890a8e0aa31a90eaa4fb44f1b10396b27896ffa26f0a144fc31bfd07
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
d09c892a12a7deafd6465652b30a95c102e4f242e3e9eedbc69603eb61afa08c44b3bdea39bf4e2207de0f59f3c3a3e5f7af76d9ea8380872f5f3eac2a46c29e
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
20da0fff4cc937515571e60464f88b83f591f4e71af507d5206ab1460259df6cd0f1d6df98c55d880b25502b49586d5d789f918d4702b5c411d745a88fe7fec2
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
e0db3e0f2409e80d0c707507f29b78c9d493e7d603010bfbfe6c97df6e56b6c92c22c3ce7e7894cb27c7321992314045fd7ce7ac1d22c657e8ec0b4d37495b9e

0 comments on commit 0c7d8ef

Please sign in to comment.