\"Foveated imaging is a digital image processing technique in which the image resolution, or amount of detail, varies across the image according to one or more \"fixation po
Following on Sjoerd's answer, you can Fold[]
a radius-dependent blur as follows.
A model for the acuity (very rough model):
Clear[acuity];
acuity[distance_, x_, y_, blindspotradius_] :=
With[{\[Theta] = ArcTan[distance, Sqrt[x^2 + y^2]]},
Clip[(Chop@Exp[-Abs[\[Theta]]/(15. Degree)] - .05)/.95,
{0,1}] (1. - Boole[(x + 100.)^2 + y^2 <= blindspotradius^2])]
Plot3D[acuity[250., x, y, 25], {x, -256, 256}, {y, -256, 256},
PlotRange -> All, PlotPoints -> 40, ExclusionsStyle -> Automatic]
The example image:
size = 100;
lena = ImageResize[ExampleData[{"TestImage", "Lena"}], size];
Manipulate[
ImageResize[
Fold[Function[{ima, r},
ImageFilter[(Mean[Flatten[#]] &), ima,
7*(1 - acuity[size*5, r, 0, 0]),
Masking -> Graphics[Disk[p/2, r],
PlotRange -> {{0, size}, {0, size}}]
]],
lena, Range[10, size, 5]],
200],
{{p, {size, size}}, Locator}]
Some examples:
Something along the following lines may work for you. The filtering details should be adjusted to your tastes.
lena = ExampleData[{"TestImage", "Lena"}]
ImageDimensions[lena]
==> {512, 512}
mask = DensityPlot[-Exp[-(x^2 + y^2)/5], {x, -4, 4}, {y, -4, 4},
Axes -> None, Frame -> None, Method -> {"ShrinkWrap" -> True},
ColorFunction -> GrayLevel, ImageSize -> 512]
Show[ImageFilter[Mean[Flatten[#]] &, lena, 20, Masking -> mask], ImageSize -> 512]
WaveletMapIndexed
can give a spatially-varying blur, as shown in the Mathematica documentation (WaveletMapIndexed->Examples->Applications->Image Processing). Here is an implementation of a foveatedBlur
, using a compiled version of the acuity
function from the other answer:
Clear[foveatedBlur];
foveatedBlur[image_, d_, cx_, cy_, blindspotradius_] :=
Module[{sx, sy},
{sy, sx} = ImageDimensions@image;
InverseWaveletTransform@WaveletMapIndexed[ImageMultiply[#,
Image[acuityC[d, sx, sy, -cy + sy/2, cx - sx/2, blindspotradius]]] &,
StationaryWaveletTransform[image, Automatic, 6], {___, 1 | 2 | 3 | 4 | 5 | 6}]]
where the compiled acuity is
Clear[acuityC];
acuityC = Compile[{{distance, _Real}, {sx, _Integer}, {sy, _Integer}, {x0, _Real},
{y0, _Real}, {blindspotradius, _Real}},
Table[With[{\[Theta] = ArcTan[distance, Sqrt[(x - x0)^2 + (y - y0)^2]]},
(Exp[-Abs[\[Theta]]/(15 Degree)] - .05)/.95
*(1. - Boole[(x - x0)^2 + (y - y0 + 0.25 sy)^2 <= blindspotradius^2])],
{x, Floor[-sx/2], Floor[sx/2 - 1]}, {y, Floor[-sy/2], Floor[sy/2 - 1]}]];
The distance parameter sets the rate of falloff of the acuity. Focusing point {cx,cy}
, and blind-spot radius are self-explanatory. Here is an example using Manipulate
, looking right at Lena's right eye:
size = 256;
lena = ImageResize[ExampleData[{"TestImage", "Lena"}], size];
Manipulate[foveatedBlur[lena, d, p[[1]], p[[2]], 20], {{d, 250}, 50,
500}, {{p, ImageDimensions@lena/2}, Locator, Appearance -> None}]
See the blind spot?