Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ENH: Add 1D FFT Example #379

Merged
merged 2 commits into from
Nov 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion CMake/ITKSphinxExamplesMacros.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,9 @@ endmacro()
# // ${EXAMPLE_NAME}TestPython.
# )
function(compare_to_baseline)
set(options)
set(options
PYTHON_ONLY
)

set(oneValueArgs
EXAMPLE_NAME
Expand Down Expand Up @@ -130,6 +132,7 @@ function(compare_to_baseline)
set(test_name ${LOCAL_COMPARISON_TEST_NAME})
endif()

if(NOT ${PYTHON_ONLY})
add_test(NAME ${test_name}
COMMAND "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/ImageCompareCommand"
--test-image "${test_image}"
Expand All @@ -139,6 +142,7 @@ function(compare_to_baseline)
set_tests_properties(${test_name}
PROPERTIES DEPENDS ${depends}
)
endif()

if(ITK_WRAP_PYTHON AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${LOCAL_COMPARISON_EXAMPLE_NAME}/Code.py")
set(python_test_name ${test_name}Python)
Expand Down
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 ComputeFFTInOneDimensionTestPython
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:: MouseLiverRFInput.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
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
812462759ad316c4bde411b70de48db56256b51365f14886d5dc82ee4b719ce1e2e0778c4a3cad076d807a5d2a3880df9f6aacc5766a58b277d40c5c8a7740a1
1 change: 1 addition & 0 deletions src/Filtering/FFT/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ FFT
.. toctree::
:maxdepth: 1

ComputeFFTInOneDimension/Documentation.rst
ComputeForwardFFT/Documentation.rst
ComputeImageSpectralDensity/Documentation.rst
ComputeInverseFFTOfImage/Documentation.rst
Expand Down