Mathematica图像处理
- MD Document:2/25/2016 4:05:56 AM by Jimbowhy
- CSDN PuBlISheD: http://blog.csdn.net/WinsenJiansbomber/article/details/50769511
当我听着大佑的歌《將進酒》,写着《Make自动化编译工具》,想着自己的存在,感觉很好。突发想法觉得音量是不太小了?就要去调大点音量,然而立刻有个声音告诉我,好吧,其实音量刚刚好,因为刚刚感觉好就是证明啊!—— by Jimbowhy 2/29/2016 8:46:50 AM
Mathematica 和 Matlab 一样,是世界上数一数二的科学数值编程软件,最先接触到 Mathematica 是在2000的时候,那时计算机还讲486的年代,Mathematica 的版本好像还是 3.0 的时候,但是它的程序界面先出来一个像分形一样带有尖刺的球体留下了深刻的印象。它就像是一个童话里的世界,永远都忘不了,童话世界?对我就是这么说的。可惜当年不会用它,因为还没有什么数学常识,后来正式使用它的时候已经是10年后了,直到上了大学参加数学建模的时候需要。《Mathematica全书》就是在那时看完的,它就是 Mathematica 的帮助文档的中文版,有英文基础可以直接上文档,现在使用的 Mathematica 9.0 中文版已经包含中文帮助文档。
基本功能
MM的功能十分强大,可以上图,也可以玩音乐,比如说这个 fur elise:
BPM = 70; W = 60/BPM; O == W/8; Q = W/4; H = W/2;
Sound[{SoundNote["E6", Q], SoundNote["Eb6", Q],
SoundNote["E6", Q, "Violin"], SoundNote["Eb6", Q],
SoundNote["E6", Q],
SoundNote["B5", Q], SoundNote["D6", Q], SoundNote["C6", Q],
SoundNote["A5", H],
SoundNote["A3", Q], SoundNote["E4", Q], SoundNote["A4", Q],
SoundNote["C5", Q], SoundNote["E5", Q], SoundNote["A5", Q],
SoundNote["B5", Q],
SoundNote["E3", Q], SoundNote["E4", Q], SoundNote["Ab4", Q],
SoundNote["E5", Q], SoundNote["C6", Q], SoundNote["B5", Q],
SoundNote[{"E5", "A3"}, Q], SoundNote["A5", Q],
SoundNote["B5", Q], SoundNote["C6", Q], SoundNote["D6", Q],
SoundNote[{"C4", "E6"}, H], SoundNote["C5", Q],
SoundNote["G5", Q], SoundNote["F6", Q], SoundNote["E6", Q],
SoundNote["D6", H],
SoundNote["F5", Q], SoundNote["E6", Q], SoundNote["D6", Q],
SoundNote["C6", H],
SoundNote["E5", Q], SoundNote["D6", Q], SoundNote["C6", Q],
SoundNote["B5", H],
SoundNote["E5", Q], SoundNote["E5", Q]
}]
Export["C:\\writing\\Mathica\\fur_elise.mid", %, "Sound"]
毕竟不是传做音乐的货啊,在时值不同的音符组合时就没有办法处理,还是使用 javax.sound.midi 包实现MDI播放的,开发人员有点懒。
这里就主要介绍它的图片处理功能。通过 Import/Export 命令可以导入导出各种图片格式文件,当然这两个命令还有其它更多的用途。新建一个作业本,输入以下命令,通过 Shift+Enter 执行它,就可以加载自带的 Lena 人物图片,同时将文件导出到我正在写作的文件夹。
i = Import["ExampleData/lena.tif"]
Export["C:\\writing\\Mathica\\lena.png", i]
然后就可以用能MD写作工具将图片文件放到MD文档中,像这样,这就是去Office时代的便利:
![Girl Lena][100]
[100]: lena.png "Girl Lena"
Import还支持HTTP协议,可以从网络上加载图片数据、音频、视频等等,在导入时,可以通过 Elements 来查询支持的导入元素,例如查询AVI文件支持的导入元素就是有 ImageList,这个在后面制作 GIF 图片时有用处。也可以导入视频的指定帧:
In[59]:= Import[ "C:\writing\Mathica\a.avi", "Elements"]
Out[59]= {"Animation", "BitDepth", "ColorSpace", "Data", "Duration", "FrameCount", "FrameRate",
"Frames", "GraphicsList", "ImageList", "ImageSize", "VideoEncoding"}
In[65]:= Import[ "C:\writing\Mathica\a.avi", {"Frames", {3, 5, 9}}]
Mathematica 每次执行命令时都会产生一个输出,有一个数字号码即 In2 方括号提示的数值,通过 % 可以引用给其它需要输入数据的函数。
Mathematica 可以生成动画序列,表达式中的 /. 表示正则替换,用它来更新画圆的位置,设置旋转的角度:
ani = Animate[Graphics[{
EdgeForm[Directive[Dashed, Red]],
Black, Disk[{0, 0}, 2, {0, Pi}],
EdgeForm[Directive[Dashed, Red]],
White, Disk[{0, 0}, 2, {Pi, 2 Pi}],
EdgeForm[None],
Black, Disk[{-1, 0}, 1],
White, Disk[{1, 0}, 1],
Red, Disk[{-1, 0}, 0.3],
Red, Disk[{1, 0}, 0.3],},
PlotRange -> 2.1, ImageSize -> 150
] /. Disk[x__] :> Rotate[Disk[x], d Degree, {0, 0}], {d, 0, 360}]
也可以生成的序列图片保存为GIF动画文件,Animate 生成 gif 需要点技巧,先保存为动画视频再导入视频的帧,最后将序列帧导出为gif。哦,很抱歉,写到这里得到一条消息,外公去世了,老人家卧床多年,活动不便,可说得上是久经折磨,我想这算是个好消息吧。虽说病痛不能分担,但可以爱惜健康减少病痛,而对于生老却是无能为力的事,如果人生得意就尽欢吧,幸福的事就动画一样可以重复播放。
Ani2Gif[ani_, name_String, step_Integer] :=
Export[name,
Import[ Export[
name <> If[$OperatingSystem, "MacOSX", ".mov", ".avi"], ani],
"ImageList"][[1 ;; -1 ;; step]]]
Ani2Gif[ani, "C:\\writing\\Mathica\\the_eight_diagrams.gif",1]
表达式中的 [[1 ;; -1 ;; step]]] 是将图片序列元素重新按 step 间隔提出来组成新的序列,它的语法结构如下:
expr[[m;;n;;s]] 给出从第 m 个元素到第 n 个元素且步长为 s 组成的子列表
通常导出的图片带有控件,如果不想要控件部分可以通过 ImageCrop 函数进行修剪,小边10像素,大边52像素就差不多了:
$gif = "C:\\writing\\Mathica\\the_eight_diagrams.gif"
size = Import[$gif, "ImageSize"]
img = Import[$gif, "ImageList"][[1 ;; 30 ;; 1]]
ImageCrop[ ImageCrop[ img, size + {-10, -10}, {Right, Bottom}],
size + {-20, -62}, {Left, Top}]
另外 Animate 动画导出时是带有正反向双重图片的,所以一为了节省内存,去掉一半就可以了。
gif = "C:\\writing\\Mathica\\the_eight_diagrams.gif";
size = Import[gif, "ImageSize"];
frames = Import[gif, "ImageCount"]
img = Import[gif, "ImageList"][[1 ;; frames/2 ;; 1]];
F[x_] := ImageCrop[ImageCrop[x, size + {-10, -10}, {Right, Bottom}],
size + {-20, -62}, {Left, Top}]
croped = Map[F, img]
Export[StringReplace[gif, ".gif" -> "-crop.gif"], %]
有些时候,在编写语句的时候需要将语句中的某些内容进行预处理,如果因为这样而定义一个函数显得有点繁琐,可以使用 Function 来定义内联的函数。MM 还提供了一个参数传递占位功能 Slot,可以在语句中设置参数点位符,在后面再接收参数传递。如下例子中,StringJoin 函数放置了一个参数占位 #,在函数结束方括号后使用了 & 来接收参数列表,这样在执行时参数就会流入 # 号的位置。#还可以带序号,用来引用参数列表中指定序号的参数。
Map[StringJoin[#, "o"] &, {"x", "y", "z"}]
分号在MM系统中是列表求值的意思,