Привет Я пытаюсь отобразить текстуру в 3d-сетку, используя привязки майя и Python vtk. Я визуализирую волновой фронт .obj. Этот объект представляет собой трехмерную фотографию лица. Изображение текстуры представляет собой композицию из трех 2D-фотографий.Vtk вставляет неправильный цвет между узлами при сопоставлении текстуры с сеткой
Каждый узел в сетке имеет (УФ) координату в изображении, который определяет его цвет. Различные области сетки рисуют свои цвета с разных участков изображения. Для иллюстрации этого я заменил фактическое изображение текстуры с этим:
И сопоставляюсь это к сетке вместо этого.
Проблема, которую я имею проиллюстрирована вокруг носа. На границе между красным и зеленым есть контур синего. Более тщательное обследование этой области в режиме каркаса показывает, что это не проблема с отображением uv, а с тем, как vtk интерполирует цвет между двумя узлами. По какой-то причине он добавляет кусок синего между двумя узлами, где один красный, а один зеленый.
Это вызывает серьезные проблемы при визуализации с использованием реальной текстуры
Есть ли способ заставить VTK выбрать цвет одного или другие соседние узлы для цвета между их? Я попробовал превратить «крайний зажим», но этого ничего не получилось.
Код, который я использую, находится ниже, и вы можете получить доступ к этим файлам https://www.dropbox.com/sh/ipel0avsdiokr10/AADmUn1-qmsB3vX7BZObrASPa?dl=0 , но я надеюсь, что это простое решение.
from numpy import *
from mayavi import mlab
from tvtk.api import tvtk
import os
from vtk.util import numpy_support
def obj2array(f):
"""function for reading a Wavefront obj"""
if type(f)==str:
if os.path.isfile(f)==False:
raise ValueError('obj2array: unable to locate file ' + str(f))
f =open(f)
vertices = list()
connectivity = list()
uv = list()
vt = list()
fcount = 0
for l in f:
line = l.rstrip('\n')
data = line.split()
if len(data)==0:
pass
else:
if data[0] == 'v':
vertices.append(atleast_2d(array([float(item) for item in data[1:4]])))
elif data[0]=='vt':
uv.append(atleast_2d(array([float(item) for item in data[1:3]])))
elif data[0]=='f':
nverts = len(data)-1 # number of vertices comprising each face
if fcount == 0: #on first face establish face format
fcount = fcount + 1
if data[1].find('/')==-1: #Case 1
case = 1
elif data[1].find('//')==True:
case = 4
elif len(data[1].split('/'))==2:
case = 2
elif len(data[1].split('/'))==3:
case = 3
if case == 1:
f = atleast_2d([int(item) for item in data[1:len(data)]])
connectivity.append(f)
if case == 2:
splitdata = [item.split('/') for item in data[1:len(data)]]
f = atleast_2d([int(item[0]) for item in splitdata])
connectivity.append(f)
if case == 3:
splitdata = [item.split('/') for item in data[1:len(data)]]
f = atleast_2d([int(item[0]) for item in splitdata])
connectivity.append(f)
if case == 4:
splitdata = [item.split('//') for item in data[1:len(data)]]
f = atleast_2d([int(item[0]) for item in splitdata])
connectivity.append(f)
vertices = concatenate(vertices, axis = 0)
if len(uv)==0:
uv=None
else:
uv = concatenate(uv, axis = 0)
if len(connectivity) !=0:
try:
conarray = concatenate(connectivity, axis=0)
except ValueError:
if triangulate==True:
conarray=triangulate_mesh(connectivity,vertices)
else:
raise ValueError('obj2array: not all faces triangles?')
if conarray.shape[1]==4:
if triangulate==True:
conarray=triangulate_mesh(connectivity,vertices)
return vertices, conarray,uv
# load texture image
texture_img = tvtk.Texture(interpolate = 1,edge_clamp=1)
texture_img.input = tvtk.BMPReader(file_name='HM_1_repose.bmp').output
#load obj
verts, triangles, uv = obj2array('HM_1_repose.obj')
# make 0-indexed
triangles = triangles-1
surf = mlab.triangular_mesh(verts[:,0],verts[:,1],verts[:,2],triangles)
tc=numpy_support.numpy_to_vtk(uv)
pd = surf.mlab_source.dataset._vtk_obj.GetPointData()
pd.SetTCoords(tc)
surf.actor.actor.mapper.scalar_visibility=False
surf.actor.enable_texture = True
surf.actor.actor.texture = texture_img
mlab.show(stop=True)
Спасибо Drone. Я хочу сохранить интерполяцию в регионах, где она работает хорошо, поэтому отключить ее - это не вариант. Спасибо за три актера/идею текстурной карты. –
Из-за вашей техники для отображения u-v вы также можете использовать пороговый фильтр VTK для входных полидат каждого участника, чтобы отображались только треугольники, для которых был непрозрачный тексель. Это значительно сократило бы избыточность. – Drone2537
@ Drone2537 Извините, что столкнулся с таким старым вопросом, но это точно та же проблема, что и сейчас. Я попытался отключить интерполяцию, но результат точно такой же - может быть, у вас есть другие идеи, что может вызвать это? Кроме того, как я могу подойти к написанию своего собственного шейдера фрагментов в этом конкретном случае, если я использую 'vtkPainterPolyDataMapper'? Благодаря! –