Filtering a periodic noise
Note the dithering in the image below
Download original notebook(*VB[*)(FrontEndRef["42d99f3c-deb2-402c-ac07-1b664f611765"])(*,*)(*"1:eJxTTMoPSmNkYGAoZgESHvk5KRCeEJBwK8rPK3HNS3GtSE0uLUlMykkNVgEKmxilWFqmGSfrpqQmGemaGBgl6yYmG5jrGiaZmZmkmRkampuZAgCIexVv"*)(*]VB*)
We can use 2D Fourier transformation and filtern it out in the frequency space. Firstly, lets convert an image to normal array.
donald = ImageData[ ColorSeparate[(*VB[*)(FrontEndRef["42d99f3c-deb2-402c-ac07-1b664f611765"])(*,*)(*"1:eJxTTMoPSmNkYGAoZgESHvk5KRCeEJBwK8rPK3HNS3GtSE0uLUlMykkNVgEKmxilWFqmGSfrpqQmGemaGBgl6yYmG5jrGiaZmZmkmRkampuZAgCIexVv"*)(*]VB*), "L"] , "Real32"];
Helper functions
It implements a symmetric 2D fourier transformation and its inverse version
fourier2d[data_] := Module[{d, fw, nRow, nCol}, {nRow, nCol} = Dimensions[data]; d = data; d = d (*SpB[*)Power[(-1)(*|*),(*|*)Table[i + j, {i, nRow}, {j, nCol}]](*]SpB*); fw = Fourier[d, FourierParameters -> {1, 1}]; {Log[1 + Abs@fw], Arg[fw]} ] ifourier2d[amp_, phase_] := Module[{d, nRow, nCol}, {nRow, nCol} = Dimensions[amp]; d = (Exp[amp] - 1.0) Exp[I phase]; InverseFourier[d, FourierParameters -> {1, 1}] // Abs ] preview[data_, opts___] := With[{a = data}, Image[a / Max[a], "Real32", opts] ]
Filtering in frequency domain
Decompose an image to an amplitude and phase using 2D fourier transformation
{amp, phase} = fourier2d[donald]; Row[preview /@ {amp, phase}]
(*GB[*){{(*VB[*)(FrontEndRef["ae7ff7bc-fbe0-48f9-b002-34692c9a02f1"])(*,*)(*"1:eJxTTMoPSmNkYGAoZgESHvk5KRCeEJBwK8rPK3HNS3GtSE0uLUlMykkNVgEKJ6aap6WZJyXrpiWlGuiaWKRZ6iYZGBjpGpuYWRolWyYaGKUZAgCYoxYC"*)(*]VB*)(*|*),(*|*)(*VB[*)(FrontEndRef["52b0789a-ced5-400f-a2fb-3f83841a7aef"])(*,*)(*"1:eJxTTMoPSmNkYGAoZgESHvk5KRCeEJBwK8rPK3HNS3GtSE0uLUlMykkNVgEKmxolGZhbWCbqJqemmOqaGBik6SYapSXpGqdZGFuYGCaaJ6amAQCFtBYA"*)(*]VB*)}}(*]GB*)
Filter an amplidute spectrum
EventHandler[InputRaster[preview[amp]], (masked = #)&]
(*VB[*)(EventObject[<|"Id" -> "10b52017-f695-4ab4-9978-91d2d0544679", "View" -> "a25c2ee4-9038-4b3f-8b3b-27e4fd68ff56"|>])(*,*)(*"1:eJxTTMoPSmNkYGAoZgESHvk5KRCeEJBwK8rPK3HNS3GtSE0uLUlMykkNVgEKJxqZJhulpproWhoYW+iaJBmn6VokGSfpGpmnmqSlmFmkpZmaAQCGtBXh"*)(*]VB*)
Here is an example how it can be masked
masked // preview
(*VB[*)(FrontEndRef["f46a0e1d-ec19-4d28-954f-4155aaecbb8a"])(*,*)(*"1:eJxTTMoPSmNkYGAoZgESHvk5KRCeEJBwK8rPK3HNS3GtSE0uLUlMykkNVgEKp5mYJRqkGqbopiYbWuqapBhZ6FqamqTpmhiamiYmpiYnJVkkAgCKWhYw"*)(*]VB*)
Take masked amplitude and recombine it with phase to get back a normal image
ifourier2d @@ {With[{max = Max[amp]}, ImageData[masked, "Real32"][[All,All,1]] max ], phase}; Grid[{ {preview[donald, Magnification->2], preview[%, Magnification->2]}, {"Original", "Filtered"} }]
(*GB[*){{(*VB[*)(FrontEndRef["913b0b2f-1c22-4509-80c8-b61a22b3ea86"])(*,*)(*"1:eJxTTMoPSmNkYGAoZgESHvk5KRCeEJBwK8rPK3HNS3GtSE0uLUlMykkNVgEKWxoaJxkkGaXpGiYbGemamBpY6loYJFvoJpkZJhoZJRmnJlqYAQB5EhUw"*)(*]VB*)(*|*),(*|*)(*VB[*)(FrontEndRef["cee750d0-43e2-4c88-9f00-17884b94bfd1"])(*,*)(*"1:eJxTTMoPSmNkYGAoZgESHvk5KRCeEJBwK8rPK3HNS3GtSE0uLUlMykkNVgEKJ6emmpsapBjomhinGumaJFtY6FqmGRjoGppbWJgkWZokpaUYAgCDmxV8"*)(*]VB*)}(*||*),(*||*){"Original"(*|*),(*|*)"Filtered"}}(*]GB*)