2013-08-30 29 views
11

'daki 3D noktalar için mutlak rengi belirtin points3d sınıfını kullanarak 3d noktaları çizmek için MayaVi Python kitaplığını kullanıyorum. The documentation her noktanın renk, dördüncü bir bağımsız değişken ile s belirtilen belirtir:MichaelVi

Buna ek olarak, dördüncü bir dizi s x, y ve z ilişkili bir skaler değeri veren ile aynı şekilde geçebilir Her bir nokta için veya skaler değeri döndüren bir f (x, y, z) fonksiyonu. Bu skaler değer, noktaların rengini ve boyutunu değiştirmek için kullanılabilir.

Bu colourmap 'ın eşler her bir nokta, bir skaler değerini belirtir, örneğin copper, jet veya hsv. Örneğin. bunların belgelere:

import numpy 
from mayavi.mlab import * 

def test_points3d(): 
    t = numpy.linspace(0, 4*numpy.pi, 20) 
    cos = numpy.cos 
    sin = numpy.sin 

    x = sin(2*t) 
    y = cos(t) 
    z = cos(2*t) 
    s = 2+sin(t) 

    return points3d(x, y, z, s, colormap="copper", scale_factor=.25) 

verir:

enter image description here

Bunun yerine, bir (R, G, B) başlığın olarak her bir nokta için, gerçek değerini belirtmek istiyoruz. Bu MayaVi'de mümkün mü? s'u bir dizi tuple değiştirmeyi denedim, ancak bir hata atıldı.

cevap

1

Bu artık sadece ile yapılabilir: çizmek ve daha sonra endekslerin bir listesi olarak argüman ayarlamak için noktası olduğundan dolayı hile girişlerinin tam olarak aynı sayıda renkli harita tanımlamak için adildir color argüman

from mayavi import mlab 
import numpy as np 

c = np.random.rand(200, 3) 
r = np.random.rand(200)/10. 

mlab.points3d(c[:, 0], c[:, 1], c[:, 2], r, color=(0.2, 0.4, 0.5)) 

mlab.show() 

enter image description here

3

Bir rgb arama tablosu kullanabilir ve rgb değerlerini istediğiniz mantığı kullanarak haritalayabilirsiniz. İşte basit bir örnek:

import numpy, random 
from mayavi.mlab import * 

def cMap(x,y,z): 
    #whatever logic you want for colors 
    return [random.random() for i in x] 

def test_points3d(): 
    t = numpy.linspace(0, 4*numpy.pi, 20) 
    cos = numpy.cos 
    sin = numpy.sin 

    x = sin(2*t) 
    y = cos(t) 
    z = cos(2*t) 
    s = cMap(x,y,z) 

    return points3d(x, y, z, s, colormap="spectral", scale_factor=0.25) 

test_points3d() 

hiçbir fikrim istediğini renk düzeni var ama x, y, z konumlarını değerlendirmek ve aradığınız rgb değere karşılık gelen ne olursa olsun sayıl döndürebilir.

+0

256x256x256 değer içeren benzersiz renk haritası belirtmeden, keyfi bir 0-255 RGB değerini üretmek için bunu yapmanın bir yolu var mı? Çözümünüzde, Spectral() alanının [0,1] ve 0-255,0-255,0 aralığındaki bir işlev olduğu ters Spectral() işlevini karakterize etmenin bir yolu var mı? 255? Bu davranış her zaman bana irked etti ve bazı uygulamalar görüyorlar (örneğin, sahibi bana kaynağı serbest bırakmak reddetti vtk program trackvis, bu yüzden nasıl yaptığını görebilirsiniz). – aestrivex

+0

mayavi.core.lut_manager'ı, özellikle de pyab.lut_manager'i mayavi.core.lut_manager içinde bulabilir ve bunların nasıl yapıldığını görebilirsiniz (ve muhtemelen kendi isteğinizi inşa edip istediğiniz herhangi bir davranışla atayabilirsiniz). – Chrismit

+0

Bunlarla oynadım. İstenilen renk şemasını belirtmek için özel lutlarla çalışmak, bir skaler belirtildiğinde her köşe noktası için benzersiz bir RGB değeri belirtmekten çok daha genel bir çözümdür. Bu doğru olmayan hesaplama, çünkü RGB renk yelpazesini benzersiz olarak tanımlayan 256x256x256 değerleriyle LUT belirtmek mümkündür. Ama aslında bunu yapmak sıra dışı bir acı olur. Bence bu sorunun doğru cevabı "üzgünüm, bunu yapmanın doğru yolu yoktur." – aestrivex

3

Doğrudan renkleri ayarlamanın daha iyi bir yolunu buldum.

Kendi doğrudan LUT'nizi kolayca oluşturabilirsiniz. en biz 256 ** 3 parçalı yapı istediğinizi varsayalım:

#create direct grid as 256**3 x 4 array 
def create_8bit_rgb_lut(): 
    xl = numpy.mgrid[0:256, 0:256, 0:256] 
    lut = numpy.vstack((xl[0].reshape(1, 256**3), 
         xl[1].reshape(1, 256**3), 
         xl[2].reshape(1, 256**3), 
         255 * numpy.ones((1, 256**3)))).T 
    return lut.astype('int32') 

# indexing function to above grid 
def rgb_2_scalar_idx(r, g, b): 
    return 256**2 *r + 256 * g + b 

#N x 3 colors 
colors = numpy.array([_.color for _ in points]) 

#N scalars 
scalars = numpy.zeros((colors.shape[0],)) 

for (kp_idx, kp_c) in enumerate(colors): 
    scalars[kp_idx] = rgb_2_scalar_idx(kp_c[0], kp_c[1], kp_c[2]) 

rgb_lut = create_8bit_rgb_lut() 

points_mlab = mayavi.mlab.points3d(x, y, z 
            keypoint_scalars, 
            mode = 'point') 

#magic to modify lookup table 
points_mlab.module_manager.scalar_lut_manager.lut._vtk_obj.SetTableRange(0, rgb_lut.shape[0]) 
points_mlab.module_manager.scalar_lut_manager.lut.number_of_colors = rgb_lut.shape[0] 
points_mlab.module_manager.scalar_lut_manager.lut.table = rgb_lut 
7

bugün çoğu için bu mücadele sonra ben tam olarak yapmak soru sorar ne nispeten basit bir yolunu buldu - her bir nokta için bir RGB tuple belirtin.

# Imports 
import numpy as np 
from mayavi.mlab import quiver3d, draw 

# Primitives 
N = 200 # Number of points 
ones = np.ones(N) 
scalars = np.arange(N) # Key point: set an integer for each point 

# Define color table (including alpha), which must be uint8 and [0,255] 
colors = (np.random.random((N, 4))*255).astype(np.uint8) 
colors[:,-1] = 255 # No transparency 

# Define coordinates and points 
x, y, z = colors[:,0], colors[:,1], colors[:,2] # Assign x, y, z values to match color 
pts = quiver3d(x, y, z, ones, ones, ones, scalars=scalars, mode='sphere') # Create points 
pts.glyph.color_mode = 'color_by_scalar' # Color by scalar 

# Set look-up table and redraw 
pts.module_manager.scalar_lut_manager.lut.table = colors 
draw() 
+0

this iyi çalışıyor ve en basit cevaptır. – chris

+0

Bunu başka bir türden titizlikle yapmak isteyen herkes için; önemli olan ikinci son satırdır; yani surf.module_manager.scalar_lut_manager.lut.table = colors' da yapabilirsiniz. – RolKau