Skip to content

Commit 5bad8f9

Browse files
added more filters
1 parent 6b90b4f commit 5bad8f9

File tree

4 files changed

+108
-8
lines changed

4 files changed

+108
-8
lines changed

Project.toml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,14 @@ LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
1111
NDTools = "98581153-e998-4eef-8d0d-5ec2c052313d"
1212
NFFT = "efe261a4-0d2b-5849-be55-fc731d526b0d"
1313
PaddedViews = "5432bcbf-9aad-5242-b902-cca2824c8663"
14-
SeparableFunctions = "c8c7ead4-852c-491e-a42d-3d43bc74259e"
1514
ShiftedArrays = "1277b4bf-5013-50f5-be3d-901d8477a67a"
1615

1716
[compat]
1817
ChainRulesCore = "0.9, 0.10, 1.0, 1.1, 1"
1918
FFTW = "1.5"
2019
ImageTransformations = "0.9"
2120
IndexFunArrays = "0.2"
22-
NDTools = "0.5"
21+
NDTools = "0.5.1"
2322
NFFT = "0.11, 0.12, 0.13"
2423
PaddedViews = "0.5"
2524
ShiftedArrays = "1"

src/fourier_filtering.jl

Lines changed: 101 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
export fourier_filter!, fourier_filter
2-
export filter_gaussian # , filter_gaussian2
2+
export filter_gaussian, filter_gaussian!, filter_hann, filter_hann!, filter_hamming, filter_hamming!
33

44
"""
55
fourier_filter!(arr::AbstractArray, fct=window_gaussian; kwargs...)
@@ -183,11 +183,106 @@ function fourier_filter_by_1D_RFT!(arr::TA, fct=window_gaussian; dims=(1:ndims(a
183183
return arr # this breaks the for loop and finishes the algorithm
184184
end
185185

186+
"""
187+
filter_hann(arr; border_in=(real(eltype(arr)))(0.8), border_out=(real(eltype(arr)))(1), kwargs...)
188+
189+
performs Hann filtering by multiplying a Hann function in Fourier space.
190+
Note that this filter is separable but not circularly symmetric.
191+
See also `fourier_filter()`.
192+
193+
#Arguments
194+
+`arr`: the array to filter
195+
+`sigma`: the real-space standard deviation to filter with. From this the Fourier-space standard deviation will be calculated.
196+
+`kwargs...`: additional arguments to be passed to `window_gaussian`, which is the underlying function from `IndexFunArray.jl`.
197+
Of particular importance are `border_in` and `border_out` defining the inner and outer border of the window relative to the Nyquist frequency.
198+
#Example
199+
```jdoctest
200+
julia> res = filter_hann(FourierTools.delta((7,6)), border_in=0.3, border_out=0.4)
201+
7×6 Matrix{Float64}:
202+
0.00954688 -0.00477344 -0.0334141 -0.0477344 -0.0334141 -0.00477344
203+
-0.00660664 0.00330332 0.0231233 0.0330332 0.0231233 0.00330332
204+
-0.0267498 0.0133749 0.0936242 0.133749 0.0936242 0.0133749
205+
-0.0357143 0.0178571 0.125 0.178571 0.125 0.0178571
206+
-0.0267498 0.0133749 0.0936242 0.133749 0.0936242 0.0133749
207+
-0.00660664 0.00330332 0.0231233 0.0330332 0.0231233 0.00330332
208+
0.00954688 -0.00477344 -0.0334141 -0.0477344 -0.0334141 -0.00477344
209+
```
210+
"""
211+
function filter_hann(arr; border_in=(real(eltype(arr)))(0.8), border_out=(real(eltype(arr)))(1), kwargs...)
212+
filter_hann!(copy(arr); border_in=border_in, border_out=border_out, kwargs...)
213+
end
214+
215+
"""
216+
filter_hann!(arr; border_in=(real(eltype(arr)))(0.8), border_out=(real(eltype(arr)))(1), kwargs...)
217+
218+
performs in-place Hann filtering by multiplying a Hann function in Fourier space.
219+
Note that this filter is separable but not circularly symmetric.
220+
See also `fourier_filter!()`.
221+
222+
#Arguments
223+
+`arr`: the array to replace by filtered version
224+
+`sigma`: the real-space standard deviation to filter with. From this the Fourier-space standard deviation will be calculated.
225+
+`kwargs...`: additional arguments to be passed to `window_gaussian`, which is the underlying function from `IndexFunArray.jl`.
226+
Of particular importance are `border_in` and `border_out` defining the inner and outer border of the window relative to the Nyquist frequency.
227+
228+
See filter_hann() for an example.
229+
"""
230+
function filter_hann!(arr; border_in=(real(eltype(arr)))(0.8), border_out=(real(eltype(arr)))(1), kwargs...)
231+
return fourier_filter!(arr, window_hanning; border_in=border_in, border_out=border_out, kwargs...)
232+
end
233+
234+
"""
235+
filter_hamming(arr; border_in=(real(eltype(arr)))(0.8), border_out=(real(eltype(arr)))(1), kwargs...)
236+
237+
performs Hamming filtering by multiplying a Hamming function in Fourier space.
238+
Note that this filter is separable but not circularly symmetric.
239+
See also `fourier_filter()`.
240+
241+
#Arguments
242+
+`arr`: the array to filter
243+
+`sigma`: the real-space standard deviation to filter with. From this the Fourier-space standard deviation will be calculated.
244+
+`kwargs...`: additional arguments to be passed to `window_gaussian`, which is the underlying function from `IndexFunArray.jl`.
245+
Of particular importance are `border_in` and `border_out` defining the inner and outer border of the window relative to the Nyquist frequency.
246+
#Example
247+
```jdoctest
248+
julia> res = filter_hamming(FourierTools.delta((7,6)), border_in=0.3, border_out=0.4)
249+
7×6 Matrix{Float64}:
250+
0.00808048 -0.00404024 -0.0282817 -0.0488342 -0.0282817 -0.00404024
251+
-0.00559186 0.00279593 0.0195715 0.0337943 0.0195715 0.00279593
252+
-0.022641 0.0113205 0.0792435 0.13683 0.0792435 0.0113205
253+
-0.0363619 0.018181 0.127267 0.219752 0.127267 0.018181
254+
-0.022641 0.0113205 0.0792435 0.13683 0.0792435 0.0113205
255+
-0.00559186 0.00279593 0.0195715 0.0337943 0.0195715 0.00279593
256+
0.00808048 -0.00404024 -0.0282817 -0.0488342 -0.0282817 -0.00404024
257+
```
258+
"""
259+
function filter_hamming(arr; border_in=(real(eltype(arr)))(0.8), border_out=(real(eltype(arr)))(1), kwargs...)
260+
filter_hamming!(copy(arr); border_in=border_in, border_out=border_out, kwargs...)
261+
end
262+
263+
"""
264+
filter_hamming!(arr; border_in=(real(eltype(arr)))(0.8), border_out=(real(eltype(arr)))(1), kwargs...)
265+
266+
performs in-place Hamming filtering by multiplying a Hann function in Fourier space.
267+
Note that this filter is separable but not circularly symmetric.
268+
See also `fourier_filter!()`.
269+
270+
#Arguments
271+
+`arr`: the array to replace by filtered version
272+
+`sigma`: the real-space standard deviation to filter with. From this the Fourier-space standard deviation will be calculated.
273+
+`kwargs...`: additional arguments to be passed to `window_gaussian`, which is the underlying function from `IndexFunArray.jl`.
274+
Of particular importance are `border_in` and `border_out` defining the inner and outer border of the window relative to the Nyquist frequency.
275+
276+
See filter_hamming() for an example.
277+
"""
278+
function filter_hamming!(arr; border_in=(real(eltype(arr)))(0.8), border_out=(real(eltype(arr)))(1), kwargs...)
279+
return fourier_filter!(arr, window_hamming; border_in=border_in, border_out=border_out, kwargs...)
280+
end
281+
186282
"""
187283
filter_gaussian(arr, sigma=eltype(arr)(1); real_space_kernel=true, border_in=(real(eltype(arr)))(0), border_out=(real(eltype(arr))).(2 ./ (pi .* sigma)), kwargs...)
188284
189-
performs Gaussian filtering by multiplying a Gaussian function in Fourier space.
190-
Note that the argument `real_space_kernel` defines whether the Gaussian is computed in real or Fourier-space. Especially for small array sizes and small kernelsizes, the real-space version is preferred.
285+
performs Gaussian filtering via Fourier filtering. Note that the argument `real_space_kernel` defines whether the Gaussian is computed in real or Fourier-space. Especially for small array sizes and small kernelsizes, the real-space version is preferred.
191286
See also `filter_gaussian!()` and `fourier_filter()`.
192287
193288
#Arguments
@@ -203,12 +298,12 @@ end
203298
"""
204299
filter_gaussian!(arr, sigma=eltype(arr)(1); real_space_kernel=true, border_in=(real(eltype(arr)))(0), border_out=(real(eltype(arr))).(2 ./ (pi .* sigma)), kwargs...)
205300
206-
performs in-place Gaussian filtering by multiplying a Gaussian function in Fourier space.
301+
performs in-place Gaussian filtering by mulitplication in Fourier space.
207302
Note that the argument `real_space_kernel` defines whether the Gaussian is computed in real or Fourier-space. Especially for small array sizes and small kernelsizes, the real-space version is preferred.
208-
See also `filter_gaussian()` adn `fourier_filter!()`.
303+
See also `filter_gaussian()` and `fourier_filter!()`.
209304
210305
#Arguments
211-
+`arr`: the array to filter
306+
+`arr`: the array to replace by filtered version
212307
+`sigma`: the real-space standard deviation to filter with. From this the Fourier-space standard deviation will be calculated.
213308
+ `real_space_kernel`: if `true`, the separable Gaussians are computed in real space and then Fourier-transformed. The overhead is relatively small, but the result does not create fringes.
214309
+`kwargs...`: additional arguments to be passed to `window_gaussian`, which is the underlying function from `IndexFunArray.jl`. This can be useful to create Fourier-shifted (Gabor-) filtering.

src/fourier_shifting.jl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ function shift_by_1D_FT!(arr::TA, shifts; soft_fraction=0, take_real=false, fix_
8888
end
8989
# better use reorient from NDTools here?
9090
# TR = real_arr_type(TA)
91+
9192
freqs = similar(arr, real(eltype(arr)), select_sizes(arr, d))
9293
# freqs = TR(reorient(fftfreq(size(arr, d)),d, Val(N)))
9394
freqs .= reorient(fftfreq(size(arr, d)),d, Val(N))
@@ -98,6 +99,7 @@ function shift_by_1D_FT!(arr::TA, shifts; soft_fraction=0, take_real=false, fix_
9899
else
99100
ϕ = soft_shift(freqs, shift, soft_fraction)
100101
end
102+
# ϕ = exp_ikx_sep(complex_arr_type(TA), size(arr), dims=(d,), shift_by = shift)[1]
101103
# in even case, set one value to real
102104
if iseven(size(arr, d))
103105
s = size(arr, d) ÷ 2 + 1

test/fourier_filtering.jl

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,4 +29,8 @@ Random.seed!(42)
2929
gf2 = conv_psf(x, k)
3030
@test (gf,gf2, rtol=1e-2) # it is realatively inaccurate due to the kernel being generated in different places
3131
end
32+
@testset "Other filters" begin
33+
@test filter_hamming(FourierTools.delta(Float32, (3,)), border_in=0.0, border_out=1.0) [0.23,0.54, 0.23]
34+
@test filter_hann(FourierTools.delta(Float32, (3,)), border_in=0.0, border_out=1.0) [0.25,0.5, 0.25]
35+
end
3236
end

0 commit comments

Comments
 (0)