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["f6d54c4a-13ce-4db4-aae3-4d9f2eef5d9f"])(*,*)(*"1:eJxTTMoPSmNkYGAoZgESHvk5KRCeEJBwK8rPK3HNS3GtSE0uLUlMykkNVgEKp5mlmJokmyTqGhonp+qapCSZ6CYmphoDWZZpRqmpaaZAGgCVChbJ"*)(*]VB*)(*|*),(*|*)(*VB[*)(FrontEndRef["1ed5328e-402d-4c34-b037-96bdbcabe01b"])(*,*)(*"1:eJxTTMoPSmNkYGAoZgESHvk5KRCeEJBwK8rPK3HNS3GtSE0uLUlMykkNVgEKG6ammBobWaTqmhgYpeiaJBub6CYZGJvrWpolpSQlJyalGhgmAQCBrBXt"*)(*]VB*)}}(*]GB*)
Filter an amplidute spectrum
EventHandler[InputRaster[preview[amp]], (masked = #)&]
(*VB[*)(EventObject[<|"Id" -> "e53306a9-800e-416a-bfa9-9bbbb9e4efa5", "View" -> "11faab3a-8a0d-43e2-9970-3c93ea9620b6"|>])(*,*)(*"1:eJxTTMoPSmNkYGAoZgESHvk5KRCeEJBwK8rPK3HNS3GtSE0uLUlMykkNVgEKGxqmJSYmGSfqWiQapOiaGKca6VpamhvoGidbGqcmWpoZGSSZAQCJuRWY"*)(*]VB*)
Here is an example how it can be masked
masked // preview
(*VB[*)(FrontEndRef["1f6a81c1-3609-4915-a761-aa1796149201"])(*,*)(*"1:eJxTTMoPSmNkYGAoZgESHvk5KRCeEJBwK8rPK3HNS3GtSE0uLUlMykkNVgEKG6aZJVoYJhvqGpsZWOqaWBqa6iaamxnqJiYamluaGZpYGhkYAgB00hR8"*)(*]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["75166c47-f32c-4f1c-99a8-0afe20ebff13"])(*,*)(*"1:eJxTTMoPSmNkYGAoZgESHvk5KRCeEJBwK8rPK3HNS3GtSE0uLUlMykkNVgEKm5sampklm5jrphkbJeuapBkm61paJlroGiSmpRoZpCalpRkaAwB+3xXW"*)(*]VB*)(*|*),(*|*)(*VB[*)(FrontEndRef["a6c8468f-ddee-46f8-ae87-b4bfcd776380"])(*,*)(*"1:eJxTTMoPSmNkYGAoZgESHvk5KRCeEJBwK8rPK3HNS3GtSE0uLUlMykkNVgEKJ5olW5iYWaTppqSkpuqamKVZ6CamWpjrJpkkpSWnmJubGVsYAACV0hZQ"*)(*]VB*)}(*||*),(*||*){"Original"(*|*),(*|*)"Filtered"}}(*]GB*)