如何在mayavi中绘制彩色图像(imshow)
可以用mayavi画一个有三个颜色通道的图像吗?根据mayavi的说明,mayavi.mlab.imshow
只能处理形状为 (n x m) 的图像。
2 个回答
2
load_lut_from_file
这个功能在使用 imshow
时似乎没有按预期工作。只有直接在演员中设置颜色这个方法对我有效。
import pylab as pl
import numpy as np
from mayavi import mlab
from urllib import urlopen
from tvtk.api import tvtk
def test_mlab_imshowColor():
"""
Test if mlab_imshowColor displays correctly by plotting the wikipedia png example image
"""
#load a png with a scale 0->1 and four color channels (an extra alpha channel for transparency).
url = 'http://upload.wikimedia.org/wikipedia/commons/4/47/PNG_transparency_demonstration_1.png'
im = pl.imread(urlopen(url), format='png') * 255
colors = tvtk.UnsignedCharArray()
colors.from_array(im.transpose((1,0,2)).reshape(-1, 4))
m_image = mlab.imshow(np.ones(im.shape[:2]))
m_image.actor.input.point_data.scalars = colors
mlab.points3d([-200, 300, -200, 300],
[-200, 300, 200, -300],
[300, 300, 300, 300])
mlab.draw()
mlab.show()
if __name__ == "__main__":
test_mlab_imshowColor()
5
方法
我需要使用mayavi的自定义颜色映射,可以参考这个链接:http://docs.enthought.com/mayavi/mayavi/auto/example_custom_colormap.html。
我制作了一个颜色映射,它包含了原始图像中所有的像素,排列成行,原始图像的格式是(n x m x 3)。我还加入了一个透明度通道,这样透明的PNG图片就能正确显示。接下来,我使用了一张灰度图像作为查找表,像素值作为索引,指向存储在颜色映射中的原始像素。我创建了一个imshow对象,并用查找表作为输入图像,同时把imshow对象的颜色映射替换成我自定义的颜色映射。
代码
这里有一些可以运行的代码和一个测试案例,供感兴趣的人参考。Pylab可以在除了测试案例的pl.imread(...)之外的地方都用Numpy替代(Pylab是Numpy的一个封装)。这段代码是在Windows 7上用Python2.7和Mayavi 4.3.0测试的。(不幸的是,我必须先修复Windows上的一个mayavi错误,具体可以查看这个链接:https://github.com/enthought/mayavi/pull/96/files。)
import pylab as pl
from mayavi import mlab
def mlab_imshowColor(im, alpha=255, **kwargs):
"""
Plot a color image with mayavi.mlab.imshow.
im is a ndarray with dim (n, m, 3) and scale (0->255]
alpha is a single number or a ndarray with dim (n*m) and scale (0->255]
**kwargs is passed onto mayavi.mlab.imshow(..., **kwargs)
"""
try:
alpha[0]
except:
alpha = pl.ones(im.shape[0] * im.shape[1]) * alpha
if len(alpha.shape) != 1:
alpha = alpha.flatten()
# The lut is a Nx4 array, with the columns representing RGBA
# (red, green, blue, alpha) coded with integers going from 0 to 255,
# we create it by stacking all the pixles (r,g,b,alpha) as rows.
myLut = pl.c_[im.reshape(-1, 3), alpha]
myLutLookupArray = pl.arange(im.shape[0] * im.shape[1]).reshape(im.shape[0], im.shape[1])
#We can display an color image by using mlab.imshow, a lut color list and a lut lookup table.
theImshow = mlab.imshow(myLutLookupArray, colormap='binary', **kwargs) #temporary colormap
theImshow.module_manager.scalar_lut_manager.lut.table = myLut
mlab.draw()
return theImshow
def test_mlab_imshowColor():
"""
Test if mlab_imshowColor displays correctly by plotting the wikipedia png example image
"""
#load a png with a scale 0->1 and four color channels (an extra alpha channel for transparency).
from urllib import urlopen
url = 'http://upload.wikimedia.org/wikipedia/commons/4/47/PNG_transparency_demonstration_1.png'
im = pl.imread(urlopen(url), format='png')
im *= 255
mlab_imshowColor(im[:, :, :3], im[:, :, -1])
mlab.points3d([-200, 300, -200, 300],
[-200, 300, 200, -300],
[300, 300, 300, 300])
mlab.show()
if __name__ == "__main__":
test_mlab_imshowColor()
结果