(* 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]] ] ] ) ]