(* by Nasser M. Abbasi, version July 4, 2011 *)

Manipulate[
 Row[{
   
   (*--------------------*)
   (* reset event        *)
   (*--------------------*)

      Dynamic[Refresh[
     If[Not[event == "reset"],
      {
       
       If[originalImage == 0,
        {
         originalImage = getImage[imageName, imsize];
         originalImageFFT2 = 
          fft2[originalImage, fftOn3D, True, 
           fftOn3DOriginalImageScale, fftOn3DInverseImageScale, 
           imsizeForDisplay]
         }];
       
       If[isSweep,
        lastRadonImage = 
         Radon[originalImage, {n, 
           ImageDimensions[originalImage][[2]]}, {-Pi/
            2, -Pi/2 + (n)*(Pi/128)}, Method -> method],
        lastRadonImage = 
         Radon[originalImage, {n, 
           ImageDimensions[originalImage][[2]]}, {-Pi/2, Pi/2}, 
          Method -> method]
        ];
       
       iradonImage = 
        InverseRadon[lastRadonImage, "Filter" -> inverseMethod, 
         "CutoffFrequency" -> cutOffFrequency];
       result = ImageAdjust[iradonImage];
       iradonFFT2 = 
        fft2[result, fftOn3D, False, fftOn3DOriginalImageScale, 
         fftOn3DInverseImageScale, imsizeForDisplay];
       
       event = "reset"
       }
      ];
     
     Grid[{
       {
        Text@
         Row[{Style["number of projection angles = ", 12], 
           Style[n, 12]}], SpanFromLeft
        },
       {
        Grid[{
          
          {
           Show[result, ImageSize -> imsizeForDisplay],
           
           Show[ImageAdjust@ImageResize[lastRadonImage, imsize], 
            ImageSize -> imsizeForDisplay]},
          
          {Text[Style["Inverse Radon image", 12]], 
           Text[Style["Radon image", 12]]}
          }, Frame -> None, 
         FrameStyle -> Directive[Thickness[.001], Gray], 
         Alignment -> Center, Spacings -> {.6, .3}]
        }
       ,
       {
        Grid[{
          {Show[iradonFFT2, ImageSize -> imsizeForDisplay], 
           Show[originalImageFFT2, ImageSize -> imsizeForDisplay]},
          {Text[Style["Inverse Radon magnitude spectrum", 12]], 
           Text[Style["Original image magnitude spectrum", 12]]}
          }, Frame -> None, 
         FrameStyle -> Directive[Thickness[.001], Gray],
         
         Alignment -> Center, Spacings -> {.6, .3}
         ]
        }
       
       }, Alignment -> Center, Spacings -> {0, .5}
      ],
     TrackedSymbols -> {event}] 
    ],
   
   (*--------------------*)
   (* method event       *)
   (*--------------------*)

      Dynamic[Refresh[event = "method";
     If[originalImage == 0,
      {
       originalImage = getImage[imageName, imsize];
       originalImageFFT2 = 
        fft2[originalImage, fftOn3D, True, fftOn3DOriginalImageScale, 
         fftOn3DInverseImageScale, imsizeForDisplay]
       }];
     
     lastRadonImage = 
      Radon[originalImage, {n, 
        ImageDimensions[originalImage][[2]]}, {-Pi/2, Pi/2}, 
       Method -> method];
     
     "", TrackedSymbols -> {method, imageName}]
    ],
   
   (*--------------------*)
   (* trigger event      *)
   (*--------------------*)

      Dynamic[Refresh[event = "n"; "", TrackedSymbols -> {n}]],
   
   (*--------------------*)
   (* fftOn3D event      *)
   (*--------------------*)

      Dynamic[Refresh[event = "fftOn3D";
     If[originalImage == 0,
      {
       originalImage = getImage[imageName, imsize];
       lastRadonImage = 
        Radon[originalImage, {n, 
          ImageDimensions[originalImage][[2]]}, {-Pi/2, Pi/2}, 
         Method -> method]
       
       }];
     originalImageFFT2 = 
      fft2[originalImage, fftOn3D, True, fftOn3DOriginalImageScale, 
       fftOn3DInverseImageScale, imsizeForDisplay];
     
     "", TrackedSymbols -> {fftOn3D}]],
   
   (*-------------------------*)
   (* 
   cutOffFrequency event   *)
   (*-------------------------*)
   
   Dynamic[Refresh[event = "cutOffFrequency"; "", 
     TrackedSymbols -> {cutOffFrequency}]],
   
   (*-------------------------*)
   (* 
   isSweep event           *)
   (*-------------------------*)
   
   Dynamic[Refresh[event = "isSweep"; "", 
     TrackedSymbols -> {isSweep}]],
   
   (*-------------------------*)
   (* 
   inverseMethod event     *)
   (*-------------------------*)
   
   Dynamic[Refresh[event = "inverseMethod"; "", 
     TrackedSymbols -> {inverseMethod}]],
   
   (*-------------------------------------*)
   (* 
   fftOn3DOriginalImageScale event     *)
   \
(*-------------------------------------*)
   
   Dynamic[Refresh[event = "fftOn3DOriginalImageScale";
     If[originalImage == 0,
      {
       originalImage = getImage[imageName, imsize];
       lastRadonImage = 
        Radon[originalImage, {n, 
          ImageDimensions[originalImage][[2]]}, {-Pi/2, Pi/2}, 
         Method -> method]
       }];
     
     originalImageFFT2 = 
      fft2[originalImage, fftOn3D, True, fftOn3DOriginalImageScale, 
       fftOn3DInverseImageScale, imsizeForDisplay];
     
     "", TrackedSymbols -> {fftOn3DOriginalImageScale}]
    ],
   (*-------------------------------------*)
   (* 
   fftOn3DInverseImageScale event      *)
   \
(*-------------------------------------*)
   
   Dynamic[Refresh[event = "fftOn3DInverseImageScale"; "", 
     TrackedSymbols -> {fftOn3DInverseImageScale}]],
   
   (*------------------*)
   (* image event      *)
   (*------------------*)

      Dynamic[Refresh[
     event = "image";
     
     originalImage = getImage[imageName, imsize];
     originalImageFFT2 = 
      fft2[originalImage, fftOn3D, True, fftOn3DOriginalImageScale, 
       fftOn3DInverseImageScale, imsizeForDisplay];
     
     lastRadonImage = 
      Radon[originalImage, {n, 
        ImageDimensions[originalImage][[2]]}, {-Pi/2, Pi/2}, 
       Method -> method];
     
     "", TrackedSymbols -> {imageName}]]
   }],
 
 (*--------------------*)
 (* Start of controls  *)
 (*--------------------*)
 
 Grid[{
   
   {
    Framed[Grid[{
       
       {
        Control[{{n, 1, Style["N", 11]}, 1, maxNumberOfAngles, 1, 
          ControlType -> Trigger, DisplayAllSteps -> True, 
          ImageSize -> Tiny, 
          
          AppearanceElements -> {"ProgressSlider", "ResetPlayButton", 
            "PauseButton", "StepLeftButton", "StepRightButton", 
            "ResetButton"}}]
        },
       
       {
        Control[{{cutOffFrequency, 1, 
           Text@Row[{Subscript[Style["f", Italic, 11], 
              Style["c", Italic, 11]]}]}, .01, 1, 0.01, 
          ImageSize -> Small, Appearance -> "Labeled"}]
        }
       
       }, Spacings -> {.5, .3}, Alignment -> Left
      ], FrameStyle -> Directive[Thickness[.001], Gray]
     ]
    },
   
   {
    Framed[Grid[{
       
       {
        Control[{ {method, "Radon", 
           Style["Radon", 11]}, (# -> Style[#, 11]) & /@ {"Radon", 
            "Hough"}, ControlType -> PopupMenu, ImageSize -> All}],
        
        Control[{ {isSweep, False, Style["incremental", 11]}, {True, 
           False}, ControlType -> Checkbox, ImageSize -> All}]
        
        },
       
       {
        Control[{ {inverseMethod, # Cos[# Pi] &, Style["Inverse", 11]},
          {(1 + Cos[# Pi])/2 & -> Style["Hann", 11],
           1 & -> Style["Rectangular", 11],
           # & -> Style["Ramp-Lak", 11],
           # Sin[# 2 Pi ] & -> Style["Sin Ramp", 11],
           # Cos[# Pi ] & -> Style["Cosine Ramp", 11],
           ((1 - 0.16)/2 - (1/2) Cos[# Pi] + 0.08 Cos[# 2 Pi]) & -> 
            Style["Blackman", 11],
           (0.355768 - 0.487396 Cos[# Pi] + 0.144232 Cos[# 2 Pi]) - 
              0.012604 Cos[# 3 Pi] & -> Style["Nuttal window", 11],
           Sinc[#] & -> Style["Shepp-Logan", 11],
           (.54 + .46 Cos[# Pi]) & -> Style["Hamming", 11],
           Sqrt[1/(1 + #^(2))] & -> Style["Butterworth order 1", 11],
           Sqrt[1/(1 + #^(4))] & -> Style["Butterworth order 2", 11],
           Sqrt[1/(1 + #^(6))] & -> Style["Butterworth order 3", 11],
           None -> Style["No filter", 11]
           }, ControlType -> PopupMenu, ImageSize -> All}], 
        SpanFromLeft
        }
       }, Spacings -> {.5, .3}, Alignment -> Left], 
     FrameStyle -> Directive[Thickness[.001], Gray]
     ]
    },
   
   {
    Framed[Grid[{
       {Control[{ {imageName, "head CT", 
           Style["image", 11]}, (# -> Style[#, 11]) & /@ {"Lena", 
            "Mandrill", "ResolutionChart", "2 white spots", 
            "4 white spots", "Moon", "head CT", "horizontal line", 
            "large dot", "small dot", "Numbers", "Clock", "Bricks", 
            "Bubbles2", "Wall", "SheppLogan", "ellipse", "square", 
            "vertical bar"},
          ControlType -> PopupMenu, ImageSize -> All}]},
       {Dynamic[Show[originalImage, ImageSize -> 180]]}
       }, Alignment -> Center, Spacings -> {0, .5}], 
     FrameStyle -> Directive[Thickness[.001], Gray]
     ]
    },
   
   {
    
    Control[{ {fftOn3D, False, Style["show fft in 3D", 11]}, {True, 
       False}, ControlType -> Checkbox }]
    
    },
   
   {
    Grid[{
      {
       Style["original image spectrum y-scale", 11] 
       },
      {
       Control[{ {fftOn3DOriginalImageScale, .8, ""}, 0.01, 1, .01 , 
         ImageSize -> Small, Appearance -> "Labeled"}]
       }
      }, Spacings -> .5, Alignment -> Left, Frame -> All, 
     FrameStyle -> Directive[Thickness[.001], Gray]
     ]
    },
   
   {
    Grid[{
      {
       Style["inverse radon spectrum y-scale", 11] 
       },
      {
       Control[{ {fftOn3DInverseImageScale, .8, ""}, 0.01, 1, .01 , 
         ImageSize -> Small, Appearance -> "Labeled"}]
       }
      }, Spacings -> .5, Alignment -> Left, Frame -> All, 
     FrameStyle -> Directive[Thickness[.001], Gray]
     ]
    }
   }],
 
 {{lastRadonImage, 0}, ControlType -> None},
 {{originalImage, 0}, ControlType -> None},
 {{event, "reset"}, ControlType -> None},
 {{result, 0}, ControlType -> None},
 {{originalImageFFT2, 0}, ControlType -> None},
 {{iradonFFT2, 0}, ControlType -> None},
 {{maxNumberOfAngles, 128}, ControlType -> None},
 {{imsize, {256, 256}}, ControlType -> None},
 {{imsizeForDisplay, {200, 200}}, ControlType -> None},
 {{iradonImage, 0}, ControlType -> None},
 
 
 {{im1, \!\(\*
GraphicsBox[
TagBox[RasterBox[CompressedData["
AAAA7PoCT3gTBA==
"], {{0, 129}, {129, 0}}, {0., 1.},
ColorFunction->GrayLevel],
BoxForm`ImageTag[
       "Real", ColorSpace -> Automatic, Interleaving -> None],
Selectable->False],
BaseStyle->"ImageGraphics",
ImageSizeRaw->{129, 129},
PlotRange->{{0, 129}, {0, 129}}]\)}, ControlType -> None},
 {{im2, \!\(\*
GraphicsBox[
TagBox[RasterBox[CompressedData["
RYTBsnPq02zV76AwHjI=
"], {{0, 128}, {128, 0}}, {0, 65535},
ColorFunction->GrayLevel],
BoxForm`ImageTag[
       "Bit16", ColorSpace -> Automatic, ImageSize -> All, 
        Interleaving -> None],
Selectable->False],
BaseStyle->"ImageGraphics",
ImageSize->{72., Automatic},
ImageSizeRaw->{128, 128},
PlotRange->{{0, 128}, {0, 128}}]\)}, ControlType -> None},
 {{im4, \!\(\*
GraphicsBox[
TagBox[RasterBox[CompressedData["
1:eJztxUEJACAQAMHDJkYwgR2MIPi2uhH8mEF9zMCyuc82UkSUEwAAAAAAAAAA
wFur+g8HAAAAAAAAAAC4bwMQSTwN
"], {{0, 49}, {49, 0}}, {0., 1.},
ColorFunction->GrayLevel],
BoxForm`ImageTag[
       "Real", ColorSpace -> Automatic, Interleaving -> None],
Selectable->False],
BaseStyle->"ImageGraphics",
ImageSize->Magnification[1],
ImageSizeRaw->{49, 49},
PlotRange->{{0, 49}, {0, 49}}]\)}, ControlType -> None},
 {{im5, \!\(\*
GraphicsBox[
TagBox[RasterBox[CompressedData["
24WdAkmSbcjc+f7/Jn7fXg==
"], {{0, 128}, {128, 0}}, {0., 1.},
ColorFunction->GrayLevel],
BoxForm`ImageTag[
       "Real", ColorSpace -> Automatic, Interleaving -> None],
Selectable->False],
BaseStyle->"ImageGraphics",
ImageSizeRaw->{128, 128},
PlotRange->{{0, 128}, {0, 128}}]\)}, ControlType -> None},
 {{im6, \!\(\*
GraphicsBox[
TagBox[RasterBox[CompressedData["
dOr9rxTo1PtfKQAAAAAAAAAAwPv+AOCoIVw=
"], {{0, 145}, {145, 0}}, {0., 
        1.},
ColorFunction->GrayLevel],
BoxForm`ImageTag[
       "Real", ColorSpace -> Automatic, Interleaving -> None],
Selectable->False],
BaseStyle->"ImageGraphics",
ImageSizeRaw->{145, 145},
PlotRange->{{0, 145}, {0, 145}}]\)}, ControlType -> None},
 {{im7, \!\(\*
GraphicsBox[
TagBox[RasterBox[CompressedData["
AAAAAAAAZOEfXAor2g==
"], {{0, 128}, {128, 0}}, {0., 1.},
ColorFunction->GrayLevel],
BoxForm`ImageTag[
       "Real", ColorSpace -> Automatic, Interleaving -> None],
Selectable->False],
BaseStyle->"ImageGraphics",
ImageSizeRaw->{128, 128},
PlotRange->{{0, 128}, {0, 128}}]\)}, ControlType -> None},
 {{im8, \!\(\*
GraphicsBox[
TagBox[RasterBox[CompressedData["
9rJarWzaOT4+Pjo6Go1Gtl5iOQ0AAAAAAADs4n+2oMOu
"], {{0, 432}, {194, 
        0}}, {0, 255},
ColorFunction->RGBColor],
BoxForm`ImageTag["Byte", ColorSpace -> "RGB", Interleaving -> True],
Selectable->False],
BaseStyle->"ImageGraphics",
ImageSizeRaw->{194, 432},
PlotRange->{{0, 194}, {0, 432}}]\)}, ControlType -> None},
 {{im9, \!\(\*
GraphicsBox[
TagBox[RasterBox[CompressedData["
03TuPAEAAAAAAAD4t34A8Rohkg==
"], {{0, 361}, {360, 0}}, {0, 255},
ColorFunction->RGBColor],
BoxForm`ImageTag["Byte", ColorSpace -> "RGB", Interleaving -> True],
Selectable->False],
BaseStyle->"ImageGraphics",
ImageSize->{51., Automatic},
ImageSizeRaw->{360, 361},
PlotRange->{{0, 360}, {0, 361}}]\)}, ControlType -> None},
 {{im10, \!\(\*
GraphicsBox[
TagBox[RasterBox[CompressedData["
bgAp3QBSaTcAAAAAAAAAWM9/AI3xp00=
"], {{0, 359}, {360, 0}}, {0, 255},
ColorFunction->RGBColor],
BoxForm`ImageTag["Byte", ColorSpace -> "RGB", Interleaving -> True],
Selectable->False],
BaseStyle->"ImageGraphics",
ImageSize->{48., Automatic},
ImageSizeRaw->{360, 359},
PlotRange->{{0, 360}, {0, 359}}]\)}, ControlType -> None},
 {{im11, \!\(\*
GraphicsBox[{
{GrayLevel[1], RectangleBox[{-4, -10}, {4, 10}]}, 
       RectangleBox[{-1, -10}, {1, 10}]}]\)}, ControlType -> None},
 
 ContinuousAction -> False,
 SynchronousUpdating -> True,
 TrackedSymbols -> {None},
 Alignment -> Center,
 ImageMargins -> 0,
 ControlPlacement -> Left,
 Initialization :> 
  (
   (*--------------------*)
   (*  read image        *)
   (*--------------------*)

      getImage[imageName_String, imsize_] := Module[{returnedImage},
     
     Which[imageName == "2 white spots", returnedImage = im1,
      imageName == "4 white spots", returnedImage = im6,
      imageName == "head CT", returnedImage = im2,
      imageName == "horizontal line", returnedImage = im4,
      imageName == "large dot", returnedImage = im5,
      imageName == "SheppLogan", returnedImage = im7,
      imageName == "ellipse", returnedImage = im8,
      imageName == "square", returnedImage = im9,
      imageName == "small dot", returnedImage = im10,
      imageName == "vertical bar", returnedImage = im11,
      
      imageName == "Bricks", 
      returnedImage = ExampleData[{"Texture", imageName}],
      imageName == "Bubbles2", 
      returnedImage = ExampleData[{"Texture", imageName}],
      imageName == "Wall", 
      returnedImage = ExampleData[{"Texture", imageName}],
      
      True, returnedImage = ExampleData[{"TestImage", imageName}]
      ];
     
     If[ ImageChannels[returnedImage] == 3, 
      returnedImage = 
       Image[ImageData[returnedImage][[All, All, 1]]]];
     
     ImageResize[returnedImage, imsize]
     ];
   
   (*--------------------*)
   (* find FFT2          *)
   (*--------------------*)

      fft2[theImage_, fftOn3D_, isOriginal_, yForOriginal_, 
     yForRadon_, imsizeForDisplay_] := 
    Module[{data, i, j, nRow, nCol, fw, tb, scale},
     
     data = ImageData[theImage][[All, All]];
     {nRow, nCol} = Dimensions[data];
     tb = N@Table[i + j, {i, nRow}, {j, nCol}];
     data = data*Power[-1, tb];
     
     fw = Fourier[data, FourierParameters -> {1, 1}];
     
     scale = If[fftOn3D,
       1,
       If[isOriginal, 100*yForOriginal, 10*yForRadon ]
       ];
     
     abs = scale*Log[0.1 + Abs@fw];
     
     If[fftOn3D,
      
      Image@
       ListPlot3D[abs, MaxPlotPoints -> 60, 
        ImageSize -> imsizeForDisplay, 
        PlotRange -> {All, 
          All, {0, 
           If[isOriginal, yForOriginal Max[abs], 
            yForRadon Max[abs]]}}, ImageMargins -> 2, 
        ImagePadding -> 20],
      
      ImageAdjust[Image[abs]]
      
      ]
     ]
   )
 
 ]