python vtk 画线_关于python:Vtk在将纹理映射到网格时在节点之间插入不正确的颜色...

嗨,我正在尝试使用Mayavi和vtk的Python绑定将纹理映射到3d网格。我正在可视化.obj波前。该obj是一张脸的3D照片。纹理图像是三张2D照片的合成。

网格中的每个节点在图像中都有一个(uv)坐标,以定义其颜色。网格的不同区域从图像的不同部分绘制其颜色。为了说明这一点,我用此图像替换了实际的纹理图像:

并将其映射到网格。

我的问题在鼻子周围被说明。在红色和绿色之间的边界处有蓝色的轮廓。线框模式下对该区域的仔细检查表明,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('

')

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)

您可以关闭所有插值(在您的示例中将interpolate = 1更改为interpolate = 0),但是没有一种方法可以仅在将对纹理的子图像进行插值的位置处关闭插值–至少没有编写自己的片段着色器。这看起来可能很粗糙。

另一个解决方案是在不属于演员脸部的每个位置创建3个带有透明纹理像素的纹理图像。然后使用相同的纹理坐标渲染相同的几何体,但每次渲染不同的图像(即,让3个actor每个具有相同的多数据但纹理图像不同)。

谢谢无人机。我想将插值保留在效果良好的区域,因此将其关闭实际上不是一个选择。感谢三个参与者/纹理贴图的想法。

由于使用了u-v映射的技术,因此您还可以在每个参与者输入多数据上使用VTK阈值过滤器,以便仅渲染存在非透明纹理像素的三角形。这将大大减少透支。

@ Drone2537很抱歉碰到这样一个老问题,但是那是我现在遇到的完全相同的问题。香港专业教育学院试图关闭插值,但输出是完全相同的-也许您还有其他想法可能导致这种情况吗?另外,如果使用vtkPainterPolyDataMapper,在这种特殊情况下如何处理自己的片段着色器?谢谢!

@ the-lay这些伪影是由于以下两种情况之一而导致的:(1)纹理图像不平滑,因为您正在获取到达图像边界的纹理像素,或者(2)您的几何图元跨越了纹理图集的接缝。

@ the-lay我建议像我之前做的那样来修复问题……通过将几何体划分为不交叉接缝的区域并填充每块渲染的纹理图像,因此不会出现边界钳制问题。如果打算编写着色器,请查看VTKRenderingOpenGL2glslvtkPolyDataFS.glsl。 VTK::...位由特定于OpenGL的渲染器中的glsl源替换,具体取决于要渲染的多数据中存在哪些数组。

@ Drone2537您说得很对,我的情况是后一种-三角形遍布UV,而不是"一块"。不幸的是,网格和纹理的参数化是由没有精细控制的黑盒应用程序自动生成的,有时多达200个三角形"块",范围从一个三角形到所有模型三角形的90%(我需要以专门使用此参数化和纹理)。我认为为每个三角形"块"分割几何体的开销可能太大,但是我会尝试一下。非常感谢您的宝贵时间!

我也碰到了这个确切的问题,发现发生这种情况的原因是因为VTK假定渲染角色和相关的vtkTexture时,多数据中的点与uv坐标之间存在一对一的关系。但是,就我和OP而言,有相邻的三角形映射到图像的不同部分,因此它们具有非常不同的uv坐标。共享这些相邻面的点只能具有一个uv坐标(或Tcoord)关联,但实际上它们需要2个(或更多,取决于您的情况)。

我的解决方案是遍历并复制位于接缝/边界上的这些点,并使用带有这些重复的pointId的三角形创建一个新的vtkCellArray。然后,我只是用新的三角形替换了vtkPolyData Polys()列表。复制点并为每个需要它的三角形更新现有的pointIds会容易得多,但是我找不到合适的方式来更新单元格。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值