我们能否在Mathematica中生成“凹陷图像”?

15

"凹点成像是一种数字图像处理技术,其中图像分辨率或细节根据一个或多个“凝视点”在整个图像上变化。凝视点表示图像中分辨率最高的区域,并对应于眼睛视网膜的中心,即黄斑部。"

enter image description here

我想使用这样的图片来说明人类的视觉敏锐度,下图显示了左眼(水平截面)相对于黄斑部的视力敏锐度(来源于维基百科):

enter image description here

是否有一种方法可以使用Mathematica的图像处理功能创建一个凹点成像呢?

3个回答

10

以下内容可能适合您使用。过滤细节应根据您的喜好进行调整。

lena = ExampleData[{"TestImage", "Lena"}]

lena


(该段落包含一张名为“lena”的图片,图片地址为 https://istack.dev59.com/Veo3t.webp)
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]

mask


(这是一张图片,名称为“mask”,请见谅本AI无法提供更多信息)
Show[ImageFilter[Mean[Flatten[#]] &, lena, 20, Masking -> mask], ImageSize -> 512]

在这里输入图片描述


非常感谢,我就知道这个会来自您! - 500
Sjoerd,我需要一个漂亮的二维视网膜光感受器密度图,类似于:http://www.oculist.net/downaton502/prof/ebook/duanes/pages/v3/ch001/008f.html 你知道有更高质量的类似图吗?或者有什么技巧可以使用这些图来制作出更好的图形?无论如何,感谢您的关注! - 500
请注意,这种技术只是伪造了一个位置相关的模糊效果。模糊本身在任何地方都是恒定的,但是与位置相关的alpha混合在一起。至少我认为Masking是这样工作的。因此,我认为没有必要尝试设计非常精确的密度图,因为它们不能真正用于使用此方法进行视力敏锐度的准确表示。您需要的是一个位置相关的滤波器,而我在mma的图像处理函数集中没有找到一个。我不认为编写一个自己的程序太难了。它会慢一些。 - Sjoerd C. de Vries

9

继Sjoerd的回答后,您可以使用Fold[]来进行半径相关的模糊处理,如下所示。

一个视力敏锐度的模型(非常粗略的模型):

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]

视网膜黄斑区模型

这张图片是一个视网膜黄斑区的模型。

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}]

一些例子:

Acuity例子1

Acuity例子2


非常感谢!定位器很棒! - 500
1
非常聪明的扩展!我是否错误地得出结论,外部区域被模糊了多次?这不会比视力所规定的更加模糊吗?也许可以调整锐度函数来纠正这个问题?顺便说一下,{"TestImage", "ResolutionChart"} 也是一个很好的测试图像。 - Sjoerd C. de Vries
确实,模糊的重叠是存在的;如果您从外向内工作,即使用Range[size,10,-5]替换Range[10,size,5],则不会那么明显。但是它确实需要被考虑到。 - JxB
或者,Sjoerd,可以使用环形掩模以避免重叠。 - JxB
那我可以问一下,我应该如何调整其中一个代码以获得带有定位器的Sjoerd渲染呢?很抱歉,我尝试调整JxB的一些参数但没有成功。 - 500
显示剩余2条评论

2
< p > WaveletMapIndexed 可以提供空间变化的模糊效果,如 Mathematica 文档中所示 (WaveletMapIndexed->Examples->Applications->Image Processing)。下面是一个实现了 foveatedBlur 的例子,使用了另一个答案中的 acuity 函数的编译版本:

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}]]

编译后的敏锐度存放位置

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]}]];

距离参数设置了视力锐度的衰减速率。聚焦点{cx,cy}和盲点半径是不言自明的。下面是一个使用Manipulate的例子,直接看着Lena的右眼:

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}]

具有盲点的凹凸图像示例

注意到盲点了吗?


我认为基本技术与ImageFilter足够不同,以至于需要单独回答。 - JxB

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接