在 IDL 中创建动画和视频
原文链接: https://www.nv5geospatialsoftware.com/Learn/Blogs/Blog-Details/creating-animations-and-videos-in-idl
13816 文章评分:
3.8
在 IDL 中创建动画和视频
Jim Pendleton 2016年10月13日 星期四
如果我们以视频形式将图像制作成动画,通常更容易察觉到图像中的变化。这些比较可以是在不同时间拍摄的同一主题图像之间,也可以是在同一时间获取但采用不同技术或波长的图像之间。
NV5 定制解决方案团队 经常在我们提供给客户的应用程序和解决方案中包含视频制作和显示工具。
假设您一直在监测 阿贝尔 115 星系团 的光学变化,其图像位于您的 IDL examples/demo/demodata 目录中。
IDL> read_jpeg, filepath('abell115.jpg', subdir = ['examples','demo','demodata']), image1
IDL> i = image(image1)
让我们将感兴趣的区域从一个位置复制到另一个位置,以模拟发现超新星。
IDL> image2[*, 250:260, 250:260] = image2[*, 265:275, 350:360]
IDL> i.setdata, image2
变化相当小,但您应该能在图像中心看到它。

为了使“发现”更加明显,我们可以将变化制作成动画。
一种显示技术涉及淡入淡出操作,即图像随时间逐渐相互融合。每个像素随时间从一种颜色过渡到另一种颜色。我们的人类视觉系统会被动画中的变化区域所吸引。根据希望观众获得的效果,所有像素可能以相同速度并行过渡,或者某些像素可能比其他像素过渡得更慢或更快。
首先,选择发生变化的单个“帧”数量。帧数定义了图像之间过渡的平滑程度。例如,值为2将产生没有插值过渡的闪烁效果。
IDL> nframes = 32
接下来,遍历各帧,在每一步显示根据两个输入图像按比例贡献加权的图像。
IDL> for f = 1., nframes do i.setdata, byte(image2*(f/nframes) + image1*(1-f/nframes))
(为了本示例中代码的简洁性,我使用了浮点值进行循环,但通常不推荐这样做。)
接下来,您可能希望以视频形式与您的同事分享您的“发现”。IDL类 IDLffVideoWrite 允许您以多种不同格式创建视频输出文件。
创建视频将使用三个基本步骤:创建一个与输出文件关联的对象,创建一个具有适当显示帧尺寸和帧率的视频流,然后将每个图像帧添加到流中。
获取图像的尺寸并定义帧率,单位为每秒帧数。
IDL> d = size(image1, /dimensions)
IDL> fps = 30
帧数除以帧率将决定动画的持续时间。
创建一个视频对象。在本示例中,我将把一个文件写入我的临时目录。
IDL> a = filepath(/tmp, 'abell115.avi')
IDL> v = idlffvideowrite(a)
IDLffVideoWrite 对象根据文件扩展名(本例中为“.avi”)确定视频输出的默认格式。有关替代格式,请参阅在线文档。
在视频对象中创建一个视频流,使用 IDLffVideoWrite::AddVideoStream 方法指定每个图像帧的X和Y尺寸以及帧率。
IDL> vs = v.addvideostream(d[1], d[2], fps)
我们不再将动画显示到图形窗口,而是使用 IDLffVideoWrite::Put 方法遍历帧并将数据写入视频流。
IDL> for f = 1., nframes do !null = v.put(vs, byte(image2*(f/nframes) + image1*(1-f/nframes)))
没有显式调用来关闭将帧写入文件的操作。相反,我们通过简单地销毁对象引用来发出写入数据完成的信号。
IDL> obj_destroy, v
视频文件现在已关闭,可供与同事共享。要测试内容,只需 SPAWN 视频文件的路径(假设外壳知道文件扩展名)。
IDL> spawn, a, /hide, /nowait
为了使视频更有趣,您可以考虑向 IMAGE 显示添加注释,例如 TEXT 或 ARROW,然后将显示数据作为帧输入进行复制,而不是直接仅显示原始数据。此外,请参阅下面使用的 IMAGE::CopyWindow 方法的文档。
您可以将以下内容复制并粘贴到您的 IDL 命令行以查看结果。
IDL> v = idlffvideowrite(a)
IDL> vs = v.addvideostream(d[1], d[2], fps)
IDL> i = image(image1, dimensions = d[1:2])
IDL> ar = arrow([200, 250], [200, 250], color='blue', /data, /current)
IDL> t = text(150, 180, 'Eureka!', color = 'green', /data, /current)
IDL> for f = 1., nframes do begin & $
IDL> i.setdata, byte(image2*(f/nframes) + image1*(1-f/nframes)) & $
IDL> !null = v.put(vs, i.copywindow()) & $
IDL> endfor
IDL> obj_destroy, v
IDL> spawn, a, /nowait, /hide
通过这些步骤生成的视频文件可以在此处找到。