2
$\begingroup$

Let us say I have a table:

tab = RandomReal[{-1, 1}, {128, 128}];

I can filter it using GaussianFilter as follows

GaussianFilter[tab, 12] // Image // ImageAdjust

enter image description here

But imagine I want the resulting image/cube to be periodic.

Question:

How come GaussianFilter not have a Periodic option?

I would ideally want to have

 GaussianFilter[tab, 8,Periodic->True] // Image // ImageAdjust

to produce something like this?

enter image description here

This should be easily done using Fourier Transform?

In principle it could work for tensors of any rank, like so?

tab = RandomReal[{-1, 1}, {32, 32, 32}]
 GaussianFilter[tab, 8,Periodic->True] // Image3D // ImageAdjust

enter image description here

$\endgroup$

2 Answers 2

7
$\begingroup$

You know the GaussianFilter[] option Padding->"Periodic" ? I think that's the option you're looking for!

Your first example

tab = RandomReal[{-1, 1}, {256}];
{tab, GaussianFilter[tab, 5,Padding->"Periodic"]} // ListLinePlot

evaluates a periodic result too.

enter image description here

This option evaluates the 2D-example too

tab = RandomReal[{-1, 1}, {128, 128}]; 
GaussianFilter[tab, 12, Padding -> "Periodic"] // Image //ImageAdjust
    

enter image description here

$\endgroup$
3
  • 1
    $\begingroup$ Arg! you are right... Oh well so much for spending a few hours coding this :-) $\endgroup$
    – chris
    Commented Nov 4, 2021 at 9:35
  • 1
    $\begingroup$ @Chris Sorry ;-) $\endgroup$ Commented Nov 4, 2021 at 9:44
  • $\begingroup$ Its on me for not remembering this. I had used it in the past. Mathematica has so many options and ways of implementing them it is a maze. $\endgroup$
    – chris
    Commented Nov 4, 2021 at 9:53
3
$\begingroup$

Ok I cheated a bit: I knew the answer :-) But I believe it should become a built in option to GaussianFilter!

This function will do the trick for even tensors:

fftIndgen[size_] := 
  2. Pi/ size ArrayPad[
    Range[0, Quotient[size, 2]], {0, Quotient[size, 2] - 1}, 
    "ReflectedNegation"];
FourierGaussianFilter::usage = 
  "FourierGaussianFilter[tab,size] does Gaussian periodic filtering";
FourierGaussianFilter::odd = "tensor size should be even";
FourierGaussianFilter[data_, R_] := 
 Module[{d = data // TensorRank, l = data // Length},
  If[OddQ[l] == True, Message[FourierGaussianFilter::odd]; 
   Abort[]];
  InverseFourier[
     Fourier[data]*
      Exp[-0.5 R^2 Map[# . # &, 
         Outer[List, Sequence @@ Table[fftIndgen[l], d]
          ], {d}]
       ]] // Re // Chop]

Should work for tensors on any rank. E.g.

tab = RandomReal[{-1, 1}, {256}];
{tab, FourierGaussianFilter[tab, 5]} // ListLinePlot

enter image description here

It also works for, say, rank 4 tensors:

tab = RandomReal[{-1, 1}, 2{8, 8, 8, 8}];
Map[ImageAdjust[Image3D[#]] &, FourierGaussianFilter[tab, 5]]

enter image description here

It could be improved to work with irregular/odd (hyper)cubes?

$\endgroup$
2
  • 1
    $\begingroup$ Compare the timing if you have a few moments to spare. $\endgroup$
    – Syed
    Commented Nov 4, 2021 at 11:22
  • 1
    $\begingroup$ @syed yes it is not very favourable which is hardly surprising! $\endgroup$
    – chris
    Commented Nov 4, 2021 at 17:19

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.