2016-08-25 6 views
1

Привет Я пытаюсь отобразить текстуру в 3d-сетку, используя привязки майя и Python vtk. Я визуализирую волновой фронт .obj. Этот объект представляет собой трехмерную фотографию лица. Изображение текстуры представляет собой композицию из трех 2D-фотографий.Vtk вставляет неправильный цвет между узлами при сопоставлении текстуры с сеткой

enter image description here

Каждый узел в сетке имеет (УФ) координату в изображении, который определяет его цвет. Различные области сетки рисуют свои цвета с разных участков изображения. Для иллюстрации этого я заменил фактическое изображение текстуры с этим:

enter image description here

И сопоставляюсь это к сетке вместо этого.

enter image description here

Проблема, которую я имею проиллюстрирована вокруг носа. На границе между красным и зеленым есть контур синего. Более тщательное обследование этой области в режиме каркаса показывает, что это не проблема с отображением uv, а с тем, как vtk интерполирует цвет между двумя узлами. По какой-то причине он добавляет кусок синего между двумя узлами, где один красный, а один зеленый.

enter image description here

Это вызывает серьезные проблемы при визуализации с использованием реальной текстуры

enter image description here

Есть ли способ заставить 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) 

ответ

1

Вы можете отключить все интерполяции (изменение interpolate = 1 к interpolate = 0 в вашем примере), но это не способ отключить интерполяцию как раз в тех местах, где он будет интерполировать по подгруппам изображения текстуры - на по крайней мере, не без написания собственного фрагментарного шейдера. Вероятно, это выглядит грубо.

Другим решением будет создание 3 текстурных изображений с прозрачными текселями в каждом месте, которое не является частью лица актера. Затем визуализируйте одну и ту же геометрию с одинаковыми координатами текстуры, но с другим изображением каждый раз (т. Е. Имеют 3 актера с одной и той же полидатой, но с другим изображением текстуры).

+0

Спасибо Drone. Я хочу сохранить интерполяцию в регионах, где она работает хорошо, поэтому отключить ее - это не вариант. Спасибо за три актера/идею текстурной карты. –

+0

Из-за вашей техники для отображения u-v вы также можете использовать пороговый фильтр VTK для входных полидат каждого участника, чтобы отображались только треугольники, для которых был непрозрачный тексель. Это значительно сократило бы избыточность. – Drone2537

+0

@ Drone2537 Извините, что столкнулся с таким старым вопросом, но это точно та же проблема, что и сейчас. Я попытался отключить интерполяцию, но результат точно такой же - может быть, у вас есть другие идеи, что может вызвать это? Кроме того, как я могу подойти к написанию своего собственного шейдера фрагментов в этом конкретном случае, если я использую 'vtkPainterPolyDataMapper'? Благодаря! –

 Смежные вопросы

  • Нет связанных вопросов^_^