Skip to content

Commit 8b7f38d

Browse files
tbirdsohjmjohnson
authored andcommitted
ENH: Add 1D FFT Example
1 parent 64c20ec commit 8b7f38d

11 files changed

+171
-1
lines changed

src/Filtering/FFT/CMakeLists.txt

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,17 @@
1-
add_example(FilterImageInFourierDomain)
1+
add_example(ComputeFFTInOneDimension)
2+
compare_to_baseline(
3+
PYTHON_ONLY
4+
EXAMPLE_NAME ComputeFFTInOneDimension
5+
TEST_NAME ComputeFFTInOneDimensionModulusBaselineComparison
6+
BASELINE_PREFIX MouseLiver1DFFTModulusOutputBaseline
7+
)
8+
compare_to_baseline(
9+
PYTHON_ONLY
10+
EXAMPLE_NAME ComputeFFTInOneDimension
11+
TEST_NAME ComputeFFTInOneDimensionPhaseBaselineComparison
12+
BASELINE_PREFIX MouseLiver1DFFTPhaseOutputBaseline
13+
)
14+
215
compare_to_baseline(
316
EXAMPLE_NAME FilterImageInFourierDomain
417
BASELINE_PREFIX OutputBaseline
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
cmake_minimum_required(VERSION 3.16.3)
2+
3+
project(ComputeFFTInOneDimension)
4+
5+
find_package(ITK REQUIRED)
6+
include(${ITK_USE_FILE})
7+
8+
install(FILES Code.py CMakeLists.txt
9+
DESTINATION share/ITKSphinxExamples/Code/Filtering/FFT/ComputeFFTInOneDimension
10+
COMPONENT Code
11+
)
12+
13+
enable_testing()
14+
15+
if(ITK_WRAP_PYTHON)
16+
find_package(PythonInterp REQUIRED)
17+
add_test(NAME ComputeFFTInOneDimensionTestPython
18+
COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/Code.py
19+
${CMAKE_CURRENT_BINARY_DIR}/MouseLiverRF.mha
20+
${CMAKE_CURRENT_BINARY_DIR}/MouseLiver1DFFTModulusOutputPython.mha
21+
${CMAKE_CURRENT_BINARY_DIR}/MouseLiver1DFFTPhaseOutputPython.mha
22+
)
23+
endif()
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
#!/usr/bin/env python
2+
3+
# Copyright NumFOCUS
4+
#
5+
# Licensed under the Apache License, Version 2.0 (the "License");
6+
# you may not use this file except in compliance with the License.
7+
# You may obtain a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0.txt
10+
#
11+
# Unless required by applicable law or agreed to in writing, software
12+
# distributed under the License is distributed on an "AS IS" BASIS,
13+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
# See the License for the specific language governing permissions and
15+
# limitations under the License.
16+
17+
import itk
18+
import argparse
19+
20+
parser = argparse.ArgumentParser(description="Compute Inverse FFT Of Image.")
21+
parser.add_argument("input_path", nargs=1, type=str)
22+
parser.add_argument("modulus_output_path", nargs=1, type=str)
23+
parser.add_argument("phase_output_path", nargs=1, type=str)
24+
parser.add_argument("fft_direction", nargs="?", default=0, type=int)
25+
args = parser.parse_args()
26+
27+
# Read input image
28+
pixel_type = itk.F
29+
image = itk.imread(args.input_path[0], pixel_type=pixel_type)
30+
print(f"Read real input image of type {type(image)} and size {itk.size(image)}")
31+
32+
assert (
33+
args.fft_direction < image.GetImageDimension()
34+
), "FFT direction must be an image dimension"
35+
36+
# Perform FFT in given direction
37+
padded_image = itk.fft_pad_image_filter(image)
38+
print(f"Padded input image to size {itk.size(image)}")
39+
print(f"Performing FFT along axis {args.fft_direction}")
40+
complex_image = itk.forward1_dfft_image_filter(image, direction=args.fft_direction)
41+
print(
42+
f"Generated complex frequency image of type {type(complex_image)} and size {itk.size(complex_image)}"
43+
)
44+
45+
# Shift image along FFT dimension to represent complex range (-f_B, +f_B]
46+
shift = [0] * complex_image.GetImageDimension()
47+
shift[args.fft_direction] = int(itk.size(complex_image)[args.fft_direction] / 2)
48+
shift = [int(itk.size(complex_image)[args.fft_direction] / 2), 0]
49+
shifted_image = itk.cyclic_shift_image_filter(complex_image, shift=shift)
50+
51+
# Write out modulus and phase images for visualization in PNG format
52+
modulus_image = itk.complex_to_modulus_image_filter(shifted_image)
53+
itk.imwrite(modulus_image, args.modulus_output_path[0])
54+
55+
phase_image = itk.complex_to_phase_image_filter(shifted_image)
56+
itk.imwrite(phase_image, args.phase_output_path[0])
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
:name: ComputeFFTInOneDimension
2+
3+
Compute Forward FFT In One Dimension
4+
====================================
5+
6+
.. index::
7+
single: Forward1DFFTImageFilter
8+
single: ComplexToRealImageFilter
9+
single: ComplexToImaginaryImageFilter
10+
single: ComplexToModulusImageFilter
11+
single: CyclicShiftImageFilter
12+
single: ImageFileReader
13+
single: ImageFileWriter
14+
15+
Synopsis
16+
--------
17+
18+
Compute forward FFT of an image in one dimension.
19+
20+
21+
Results
22+
-------
23+
24+
.. figure:: MouseLiverRFInput.png
25+
:scale: 50%
26+
:alt: Input image
27+
28+
Input RF Ultrasound Image
29+
30+
.. figure:: MouseLiverModulusOutput.png
31+
:scale: 50%
32+
:alt: Modulus Image
33+
34+
Output Modulus Image
35+
36+
.. figure:: MouseLiverPhaseOutput.png
37+
:scale: 50%
38+
:alt: Phase Image
39+
40+
Output Phase Image
41+
42+
Output::
43+
44+
Read real input image of type <class 'itk.itkImagePython.itkImageF2'> and size itkSize2 ([1536, 128])
45+
Padded input image to size itkSize2 ([1536, 128])
46+
Performing FFT along axis 0
47+
Generated complex frequency image of type <class 'itk.itkImagePython.itkImageCF2'> and size itkSize2 ([1536, 128])
48+
49+
Code
50+
----
51+
52+
Python
53+
......
54+
55+
.. literalinclude:: Code.py
56+
:language: python
57+
:lines: 1, 16-
58+
59+
60+
Classes demonstrated
61+
--------------------
62+
63+
.. breathelink:: itk::FFTPadImageFilter
64+
65+
.. breathelink:: itk::Forward1DFFTImageFilter
66+
67+
.. breathelink:: itk::CyclicShiftImageFilter
68+
69+
.. breathelink:: itk::ComplexToModulusImageFilter
70+
71+
.. breathelink:: itk::ComplexToPhaseImageFilter
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
bcbead186f60040a16fa7091598b2da7ead8f97935efcd078c285ede14a57b717d53f95ffb2db1df6235cc19be67f98e617fc63deb24a18c7278345fd9ba24f7
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
f59ba4947c6394fa1b1dc77ff123b53d61b676a2bcdfd16758b0cd2672360cd3ed631e49890a8e0aa31a90eaa4fb44f1b10396b27896ffa26f0a144fc31bfd07
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
d09c892a12a7deafd6465652b30a95c102e4f242e3e9eedbc69603eb61afa08c44b3bdea39bf4e2207de0f59f3c3a3e5f7af76d9ea8380872f5f3eac2a46c29e
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
20da0fff4cc937515571e60464f88b83f591f4e71af507d5206ab1460259df6cd0f1d6df98c55d880b25502b49586d5d789f918d4702b5c411d745a88fe7fec2
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
e0db3e0f2409e80d0c707507f29b78c9d493e7d603010bfbfe6c97df6e56b6c92c22c3ce7e7894cb27c7321992314045fd7ce7ac1d22c657e8ec0b4d37495b9e
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
812462759ad316c4bde411b70de48db56256b51365f14886d5dc82ee4b719ce1e2e0778c4a3cad076d807a5d2a3880df9f6aacc5766a58b277d40c5c8a7740a1

0 commit comments

Comments
 (0)