(* by Nasser M. Abbasi, version July 4, 2011 *)
Manipulate[
Row[{
Dynamic[Refresh[
If[originalImage === 0,
{
originalImage =
getImage[imageName, imsize, images, keepColor];
originalImageFFT2 =
fft2[originalImage, fftOn3D, True, fftOn3DOriginalImageScale,
fftOn3DInverseImageScale, imsizeForDisplay];
nRowsForRadon =
Round[Sqrt[(#[[1]]^2 + #[[2]]^2)]] & @
ImageDimensions[originalImage]
}];
lastRadonImage =
Radon[originalImage, {n, nRowsForRadon}, {-Pi/2, Pi/2},
Method -> method];
iradonImage =
InverseRadon[lastRadonImage, "Filter" -> inverseMethod,
"CutoffFrequency" -> cutOffFrequency];
displayResult[showSpectrum, iradonImage, originalImageFFT2,
imsizeForDisplay, lastRadonImage, imsizeForDisplayOneImage,
fftOn3D, fftOn3DOriginalImageScale, fftOn3DInverseImageScale, n],
TrackedSymbols -> {event, method, n, cutOffFrequency,
inverseMethod, showSpectrum, fftOn3DInverseImageScale}],
SynchronousUpdating -> False
],
Dynamic[Refresh[event = Date[];
originalImageFFT2 =
fft2[originalImage, fftOn3D, True, fftOn3DOriginalImageScale,
fftOn3DInverseImageScale, imsizeForDisplay];
"", TrackedSymbols -> {fftOn3D, fftOn3DOriginalImageScale}]
],
Dynamic[Refresh[
event = Date[];
originalImage = getImage[imageName, imsize, images, keepColor];
originalImageFFT2 =
fft2[originalImage, fftOn3D, True, fftOn3DOriginalImageScale,
fftOn3DInverseImageScale, imsizeForDisplay];
nRowsForRadon =
Round[Sqrt[(#[[1]]^2 + #[[2]]^2)]] & @
ImageDimensions[originalImage];
lastRadonImage =
Radon[originalImage, {n, nRowsForRadon}, {-Pi/2, Pi/2},
Method -> method];
"", TrackedSymbols -> {imageName, keepColor}],
SynchronousUpdating -> False]
}],
(*--------------------*)
(* Start of controls *)
(*--------------------*)
Grid[{
{
Grid[{
{
Control[{{n, 26, Style["n", 11]}, 1, maxNumberOfAngles, 1,
ControlType -> Trigger, DisplayAllSteps -> True,
ImageSize -> Tiny, AnimationRate -> Automatic,
AppearanceElements -> {"ProgressSlider", "ResetPlayButton",
"PauseButton", "StepLeftButton", "StepRightButton",
"ResetButton"}}]
},
{Control[{{cutOffFrequency, 0.50,
Text@Row[{Subscript[Style["f", Italic, 11],
Style["c", Italic, 11]]}]}, .01, 1, 0.01,
ImageSize -> Small, Appearance -> "Labeled"}]},
{Control[{ {method, "Radon",
Style["Radon", 11]}, (# -> Style[#, 11]) & /@ {"Radon",
"Hough"}, ControlType -> PopupMenu, ImageSize -> All}]},
{Control[{ {inverseMethod, # &, 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}]}
}, Alignment -> Left, Spacings -> {0, .4}
]
},
{
Grid[{
{
Control[{ {imageName, "head CT",
Style["image", 10]}, (# -> Style[#, 10]) & /@ {"head CT",
"SheppLogan", "ellipse", "boxed", "Lena", "Mandrill",
"ResolutionChart", "2 white spots", "Moon", "small dot",
"Numbers", "Clock", "Bricks", "Bubbles2", "Wall",
"vertical bar", "noisy image"},
ControlType -> PopupMenu, ImageSize -> All}
],
Control[{ {keepColor, False, Style["color", 10]}, {True,
False}, ControlType -> Checkbox }]
},
{
Dynamic[Show[If[originalImage === 0,
{
originalImage =
getImage[imageName, imsize, images, keepColor];
nRowsForRadon =
Round[Sqrt[(#[[1]]^2 + #[[2]]^2)]] & @
ImageDimensions[originalImage];
lastRadonImage =
Radon[originalImage, {n, nRowsForRadon}, {-Pi/2, Pi/2},
Method -> method];
originalImageFFT2 =
fft2[originalImage, fftOn3D, True,
fftOn3DOriginalImageScale, fftOn3DInverseImageScale,
imsizeForDisplay];
originalImage
},
originalImage
], ImageSize -> 180], SynchronousUpdating -> False],
SpanFromLeft
}
}, Alignment -> Center, Spacings -> {.5, .4}]
},
{
Grid[{
{
Control[{ {showSpectrum, False, Style["show FFT", 10]}, {True,
False}, ControlType -> Checkbox }]
,
Control[{ {fftOn3D, False, Style["3D view", 10]}, {True,
False}, ControlType -> Checkbox ,
Enabled -> Dynamic[showSpectrum == True]}]
}
}, Spacings -> {4, 0}
]
},
{
Grid[{
{
Style["original image spectrum y scale", 11]
},
{
Control[{ {fftOn3DOriginalImageScale, .8, ""}, 0.01, 1, .01 ,
ImageSize -> Small, Enabled -> Dynamic[showSpectrum == True],
Appearance -> "Labeled"}]
}
}, Spacings -> .5, Alignment -> Left
]
},
{
Grid[{
{
Style["inverse radon spectrum y scale", 11]
},
{
Control[{ {fftOn3DInverseImageScale, .8, ""}, 0.01, 1, .01 ,
ImageSize -> Small, Enabled -> Dynamic[showSpectrum == True],
Appearance -> "Labeled"}]
}
}, Spacings -> .5, Alignment -> Left
]
}
}, Spacings -> {1, 1}, Frame -> All,
FrameStyle -> Directive[Thickness[.001], Gray]],
{{lastRadonImage, 0}, ControlType -> None},
{{originalImage, 0}, ControlType -> None},
{{event, "image"}, ControlType -> None},
{{originalImageFFT2, 0}, ControlType -> None},
{{maxNumberOfAngles, 128}, ControlType -> None},
{{imsize, {256, 256}}, ControlType -> None},
{{imsizeForDisplay, {200, 200}}, ControlType -> None},
{{imsizeForDisplayOneImage, {412, 450}}, ControlType -> None},
{{nRowsForRadon, 0}, ControlType -> None},
SynchronousUpdating -> False,
TrackedSymbols -> {None},
Alignment -> Center,
ImageMargins -> 0,
ControlPlacement -> Left,
AutorunSequencing -> {{1, 30}},
SynchronousInitialization -> False,
ImageMargins -> 0,
FrameMargins -> 1,
Initialization :>
(
images = {\!\(\*
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}}]\), \!\(\*
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}}]\), \!\(\*
GraphicsBox[
TagBox[RasterBox[CompressedData["
vDAbbUWy4oVggSUQpRw45vnj2t9sGf3CivzYcmme8/i/IoEzDQ==
"], {{0, 235}, {
235, 0}}, {0, 255},
ColorFunction->RGBColor],
BoxForm`ImageTag["Byte", ColorSpace -> "RGB", Interleaving -> True],
Selectable->False],
BaseStyle->"ImageGraphics",
ImageSize->Automatic,
ImageSizeRaw->{235, 235},
PlotRange->{{0, 235}, {0, 235}}]\), \!\(\*
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}}]\), \!\(\*
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}}]\), \!\(\*
GraphicsBox[{
{GrayLevel[1], RectangleBox[{-4, -10}, {4, 10}]},
RectangleBox[{-1, -10}, {1, 10}]}]\), \!\(\*
GraphicsBox[{
{GrayLevel[0], RectangleBox[{-20, -20}, {20, 20}]},
{GrayLevel[1], RectangleBox[{-10, -10}, {10, 10}]},
{GrayLevel[0.5], RectangleBox[{-5, -2}, {5, 2}]}},
ImageSize->{64., Automatic}]\), \!\(\*
GraphicsBox[
TagBox[RasterBox[CompressedData["
Zd/0xs0fR4ERWcpudTHoS/Pzp2LGkeD/AUyacgw=
"], {{0, 160}, {160, 0}}, {
0., 1.},
ColorFunction->RGBColor],
BoxForm`ImageTag["Real", ColorSpace -> "RGB", Interleaving -> False],
Selectable->False],
BaseStyle->"ImageGraphics",
ImageSize->{76., Automatic},
ImageSizeRaw->{160, 160},
PlotRange->{{0, 160}, {0, 160}}]\)};
(*--------------------*)
(* read image *)
(*--------------------*)
getImage[imageName_String, imsize_, images_, keepColor_] :=
Module[{returnedImage},
Which[imageName == "2 white spots", returnedImage = images[[1]],
imageName == "head CT", returnedImage = images[[2]],
imageName == "SheppLogan", returnedImage = images[[3]],
imageName == "ellipse", returnedImage = images[[4]],
imageName == "small dot", returnedImage = images[[5]],
imageName == "vertical bar", returnedImage = images[[6]],
imageName == "boxed", returnedImage = images[[7]],
imageName == "noisy image", returnedImage = images[[8]],
imageName == "Bricks",
returnedImage = ExampleData[{"Texture", imageName}],
imageName == "Bubbles2",
returnedImage = ExampleData[{"Texture", imageName}],
imageName == "Wall",
returnedImage = ExampleData[{"Texture", imageName}],
True, returnedImage = ExampleData[{"TestImage", imageName}]
];
(*Only use one channel to reduce memory on radon/
inverse radon use later on*)
(*unless user wants color*)
If[ ImageChannels[returnedImage] == 3 && Not[keepColor],
returnedImage = Image[ImageData[returnedImage][[All, All, 1]]]
];
(*reduce the size to reduce memory need for future operations*)
ImageResize[returnedImage, imsize]
];
(*--------------------*)
(* find FFT2 *)
(*--------------------*)
fft2[theImage_, fftOn3D_, isOriginal_, yForOriginal_,
yForRadon_, imsizeForDisplay_] :=
Module[{data, i, j, nRow, nCol, fw, tb, scale, abs},
data =
If[ImageChannels[theImage] == 3,
ImageData[theImage][[All, All, 1]],
ImageData[theImage][[All, All]]];
(*center image before fft*)
{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[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]]
]
];
(*--------------------*)
(* displayResult *)
(*--------------------*)
displayResult[showSpectrum_, iradonImage_, originalImageFFT2_,
imsizeForDisplay_, lastRadonImage_, imsizeForDisplayOneImage_,
fftOn3D_, fftOn3DOriginalImageScale_, fftOn3DInverseImageScale_,
n_] := Module[{},
If[showSpectrum,
Grid[{
{
Text@
Row[{Style["number of projection angles = ", 12],
Style[n, 12]}], SpanFromLeft
},
{
Grid[{
{
Show[ImageAdjust[iradonImage],
ImageSize -> imsizeForDisplay],
Show[ImageAdjust[
ImageResize[lastRadonImage, 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[
fft2[iradonImage, fftOn3D, False,
fftOn3DOriginalImageScale, fftOn3DInverseImageScale,
imsizeForDisplay], 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}
],
Grid[{
{
Text@
Row[{Style["number of projection angles = ", 12],
Style[n, 12]}]
},
{
Show[ImageAdjust[iradonImage],
ImageSize -> imsizeForDisplayOneImage]
},
{
Text[Style["inverse Radon image", 12]]
}
}, Alignment -> Center, Spacings -> {0.6, 0.3}
]
]
]
)
]