Image processing 如何使ImageTransformation生成图像的变形版本

Image processing 如何使ImageTransformation生成图像的变形版本,image-processing,wolfram-mathematica,Image Processing,Wolfram Mathematica,我正在使用ImageTransformation函数进行实验,试图制作图像的变形版本,但到目前为止进展有限。我的目标是使用柱面镜反射的图像得到的结果,在柱面镜中,图像围绕中心镜弯曲约270度。这本书有几个简洁的例子(我也从他们那里借用了霍尔宾的头骨) 但是我无法说服Mathematica给我看整个图像,或者正确地弯曲它。变形图像应该环绕放置在图像中心“内部”的镜子,但不会。我通过将常数放入操纵中(并将分辨率调低:)找到了合适的常数值。我使用的公式是: x1 = a(y + b) cos(kx

我正在使用ImageTransformation函数进行实验,试图制作图像的变形版本,但到目前为止进展有限。我的目标是使用柱面镜反射的图像得到的结果,在柱面镜中,图像围绕中心镜弯曲约270度。这本书有几个简洁的例子(我也从他们那里借用了霍尔宾的头骨)

但是我无法说服Mathematica给我看整个图像,或者正确地弯曲它。变形图像应该环绕放置在图像中心“内部”的镜子,但不会。我通过将常数放入操纵中(并将分辨率调低:)找到了合适的常数值。我使用的公式是:

x1 = a(y + b) cos(kx)
y1 = a(y + b) sin(kx)

任何能产生更好结果的帮助都将不胜感激

ImageTransformation[f,img]
中,函数
f
使得结果图像中的点
{x,y}
对应于
img
中的
f[{x,y}]
。由于生成的图像基本上是
img
的极坐标变换,
f
应该是逆极坐标变换,因此您可以执行以下操作

anamorphic[img_, angle_: 270 Degree] :=
  Module[{dim = ImageDimensions[img], rInner = 1, rOuter},
    rOuter = rInner (1 + angle dim[[2]]/dim[[1]]);
    ImageTransformation[img,
      Function[{pt}, {ArcTan[-#2, #1] & @@ pt, Norm[pt]}],
      DataRange -> {{-angle/2, angle/2}, {rInner, rOuter}},
      PlotRange -> {{-rOuter, rOuter}, {-rOuter, rOuter}},
      Padding -> White
    ]
  ]
anamorphic[ExampleData[{"TestImage", "Lena"}]]
anamorph3[img_, angle_: 270 Degree, imgWidth_: 512] :=
 Module[{data, f, matrix, dim, rOuter, rInner = 1.},
  dim = ImageDimensions[img];
  rOuter = rInner (1 + angle #2/#1 & @@ dim);
  data = Table[
      ListInterpolation[#[[All, All, i]], 
        {{rOuter, rInner}, {-angle/2, angle/2}}], {i, 3}] &@ImageData[img];
  f[i_, j_] := If[Abs[j] <= angle/2 && rInner <= i <= rOuter, 
    Through[data[i, j]], {1., 1., 1.}];
  Image@Table[f[Sqrt[i^2 + j^2], ArcTan[i, -j]], 
   {i, -rOuter, rOuter, 2 rOuter/(imgWidth - 1)},
   {j, -rOuter, rOuter, 2 rOuter/(imgWidth - 1)}]]
生成的图像看起来像

anamorphic[img_, angle_: 270 Degree] :=
  Module[{dim = ImageDimensions[img], rInner = 1, rOuter},
    rOuter = rInner (1 + angle dim[[2]]/dim[[1]]);
    ImageTransformation[img,
      Function[{pt}, {ArcTan[-#2, #1] & @@ pt, Norm[pt]}],
      DataRange -> {{-angle/2, angle/2}, {rInner, rOuter}},
      PlotRange -> {{-rOuter, rOuter}, {-rOuter, rOuter}},
      Padding -> White
    ]
  ]
anamorphic[ExampleData[{"TestImage", "Lena"}]]
anamorph3[img_, angle_: 270 Degree, imgWidth_: 512] :=
 Module[{data, f, matrix, dim, rOuter, rInner = 1.},
  dim = ImageDimensions[img];
  rOuter = rInner (1 + angle #2/#1 & @@ dim);
  data = Table[
      ListInterpolation[#[[All, All, i]], 
        {{rOuter, rInner}, {-angle/2, angle/2}}], {i, 3}] &@ImageData[img];
  f[i_, j_] := If[Abs[j] <= angle/2 && rInner <= i <= rOuter, 
    Through[data[i, j]], {1., 1., 1.}];
  Image@Table[f[Sqrt[i^2 + j^2], ArcTan[i, -j]], 
   {i, -rOuter, rOuter, 2 rOuter/(imgWidth - 1)},
   {j, -rOuter, rOuter, 2 rOuter/(imgWidth - 1)}]]

请注意,您可以使用
ParametericPlot
TextureCoordination函数
获得类似的结果,例如:

anamorphic2[img_Image, angle_: 270 Degree] := 
  Module[{rInner = 1,rOuter},
    rOuter = rInner (1 + angle #2/#1 & @@ ImageDimensions[img]);
    ParametricPlot[{r Sin[t], -r Cos[t]}, {t, -angle/2, angle/2}, 
      {r, rInner, rOuter}, 
      TextureCoordinateFunction -> ({#3, #4} &),
      PlotStyle -> {Opacity[1], Texture[img]},
      Mesh -> None, Axes -> False,
      BoundaryStyle -> None,
      Frame -> False
    ]
  ]
anamorphic2[ExampleData[{"TestImage", "Lena"}]]
编辑

在回答Wizard先生的问题时,如果您没有访问
ImageTransformation
Texture
的权限,您可以通过以下操作手动转换图像数据

anamorphic[img_, angle_: 270 Degree] :=
  Module[{dim = ImageDimensions[img], rInner = 1, rOuter},
    rOuter = rInner (1 + angle dim[[2]]/dim[[1]]);
    ImageTransformation[img,
      Function[{pt}, {ArcTan[-#2, #1] & @@ pt, Norm[pt]}],
      DataRange -> {{-angle/2, angle/2}, {rInner, rOuter}},
      PlotRange -> {{-rOuter, rOuter}, {-rOuter, rOuter}},
      Padding -> White
    ]
  ]
anamorphic[ExampleData[{"TestImage", "Lena"}]]
anamorph3[img_, angle_: 270 Degree, imgWidth_: 512] :=
 Module[{data, f, matrix, dim, rOuter, rInner = 1.},
  dim = ImageDimensions[img];
  rOuter = rInner (1 + angle #2/#1 & @@ dim);
  data = Table[
      ListInterpolation[#[[All, All, i]], 
        {{rOuter, rInner}, {-angle/2, angle/2}}], {i, 3}] &@ImageData[img];
  f[i_, j_] := If[Abs[j] <= angle/2 && rInner <= i <= rOuter, 
    Through[data[i, j]], {1., 1., 1.}];
  Image@Table[f[Sqrt[i^2 + j^2], ArcTan[i, -j]], 
   {i, -rOuter, rOuter, 2 rOuter/(imgWidth - 1)},
   {j, -rOuter, rOuter, 2 rOuter/(imgWidth - 1)}]]
anamorp3[img,角度:270度,imgWidth:512]:=
模块[{data,f,matrix,dim,rOuter,rInner=1.},
dim=图像尺寸[img];
路由器=rInner(1+角度#2/#1&@@dim);
数据=表格[
ListInterpolation[#[[All,All,i]],
{{rOuter,rInner},{-angle/2,angle/2}}],{i,3}]&@ImageData[img];

f[i_uu,j_uu]:=如果[Abs[j]像OP描述的那样,这(一个)图像如何反映在柱面镜中?我并不是说这是错误的,只是我不理解它。@Wizard先生-你将柱面镜粘贴在中心,反射正确地显示图像,即使扭曲的变形图像是正确的(或者,除非是数学家)无法识别。@cormullion我明白了。FWIW,Lena(有时是Lenna)图像的使用范围远远超出了Mathematica社区。请稍后搜索…;-)海克,没有v7中没有的
ImageTransformation
,有没有一种简单的方法可以做到这一点?哦,现在你出现了,就在贝里萨利斯怂恿我在另一个帖子中发布那场悲剧之后。这是一个阴谋!(说真的,谢谢你给我展示了一个更好的方法。)