底部的编辑版本
我有一个360度相机的影片素材,我想将其映射到一个球体上。将场景另存为等角投影在MP4文件中。
我发现this example解释了如何将图像映射到球体上,并且能够使用mayavi.animate装饰器包装示例中的代码,从MP4文件中读取连续的帧并将纹理映射到球形(使用从mayavi示例节中摘录的代码将numpy数组转换为tvtk.ImageData对象)。
但是,我遇到一个问题,使我怀疑自己可能使用的是完全错误的... 奇怪的圆形工件: Movie frame on sphere
当我将链接的示例与电影中的JPG快照一起使用时,投影看起来应该是应该的(上部看起来像是错误的,但这是视频的一部分): Image on sphere
代码如下:
'''
Altered version of Andras Deak's
on https://stackoverflow.com/questions/53074908/map-an-image-onto-a-sphere-and-plot-3d-trajectories
'''
import imageio
from mayavi import mlab
from tvtk.api import tvtk # python wrappers for the C++ vtk ecosystem
from tvtk.tools import visual
from tvtk.common import configure_input_data, is_old_pipeline
def image_from_array(ary):
""" Create a VTK image object that references the data in ary.
The array is either 2D or 3D with. The last dimension
is always the number of channels. It is only tested
with 3 (RGB) or 4 (RGBA) channel images.
Note: This works no matter what the ary type is (accept
probably complex...). uint8 gives results that make since
to me. Int32 and Float types give colors that I am not
so sure about. Need to look into this...
"""
sz = ary.shape
dims = len(sz)
# create the vtk image data
img = tvtk.ImageData()
if dims == 2:
# 1D array of pixels.
img.whole_extent = (0, sz[0]-1, 0, 0, 0, 0)
img.dimensions = sz[0], 1, 1
img.point_data.scalars = ary
elif dims == 3:
# 2D array of pixels.
if is_old_pipeline():
img.whole_extent = (0, sz[0]-1, 0, sz[1]-1, 0, 0)
else:
img.extent = (0, sz[0]-1, 0, sz[1]-1, 0, 0)
img.dimensions = sz[0], sz[1], 1
# create a 2d view of the array
ary_2d = ary[:]
ary_2d.shape = sz[0]*sz[1],sz[2]
img.point_data.scalars = ary_2d
else:
raise ValueError("ary must be 3 dimensional.")
return img
# create a figure window (and scene)
fig = mlab.figure(size=(600, 600))
visual.set_viewer(fig)
# load video
vid = imageio.get_reader('movie.mp4', 'ffmpeg')
# use a TexturedSphereSource, a.k.a. getting our hands dirty
R = 1
Nrad = 180
# create the sphere source with a given radius and angular resolution
sphere = tvtk.TexturedSphereSource(radius=R, theta_resolution=Nrad, phi_resolution=Nrad)
# assemble rest of the pipeline, assign texture
sphere_mapper = tvtk.PolyDataMapper(input_connection=sphere.output_port)
sphere_actor = tvtk.Actor(mapper=sphere_mapper)
@mlab.show
@mlab.animate(delay=50)
def auto_sphere():
for i in range(1,600):
image = vid.get_data(i)
img = image_from_array(image)
texture = tvtk.Texture(interpolate=1)
configure_input_data(texture, img)
sphere_actor.texture = texture
fig.scene.add_actor(sphere_actor)
yield
auto_sphere()
我是这个话题的新手。如何正确完成?
编辑:
所以我认为我设法确定了实际问题。但是我还不知道如何解决。 问题似乎与读取MP4文件的方式有关。在此修改后的版本中-使用了mp4中各个帧的jpeg文件-vtk管道和生成的渲染电影看起来正确:< / p>
from mayavi import mlab
from tvtk.api import tvtk # python wrappers for the C++ vtk ecosystem
# create a figure
fig = mlab.figure(size=(600, 600))
# sphere source
R = 1
Nrad = 180
sphere = tvtk.TexturedSphereSource(radius=R, theta_resolution=Nrad, phi_resolution=Nrad)
# sphere mapper
sphere_mapper = tvtk.PolyDataMapper(input_connection=sphere.output_port)
# actor
sphere_actor = tvtk.Actor(mapper=sphere_mapper)
# image reader
image = tvtk.JPEGReader()
image.file_name = 'testdata/frame001.jpg'
# texture
texture = tvtk.Texture(input_connection=image.output_port, interpolate=1)
sphere_actor.texture = texture
# add actor to scene
fig.scene.add_actor(sphere_actor)
@mlab.show
@mlab.animate(delay=50)
def auto_sphere():
for i in range(2,101):
num = str(i)
filepath = 'testdata/frame%s.jpg' % num.zfill(3)
image.file_name = filepath
# render current texture
fig.scene.render()
yield
auto_sphere()
我想我现在的新问题是: 可以实现自定义vtkImageReader2类或python中类似的类,从而允许我读取mp4的连续帧吗?如果是这样,那么如何才能正确完成呢? 不幸的是,我找不到任何有关此操作方法的教程。