obj文件有以下参数:
v:顶点,xyz坐标,可带RGB
vt:纹理,uv坐标
vn:法向量,一般有三个顶点代表面法向量和单个顶点面法向量,具体是哪一种要看(f:面)的表示形式
f:面
关于纹理坐标的描述,可以看这一篇OpenGL文档
如果是带有vt坐标,一般会带有mtl文件和texture.png文件
点云顶点着色模式下,v和vt数量相等,有时候需要获得顶点v的RGB值,就需要完成vt与texture.png的转换
关于顶点着色和面着色,可以看GAMES101-现代计算机图形学入门-闫令琪
以下是obj文件纹理坐标vt转换成顶点v的RGB颜色的 python脚本代码:
import cv2
v = []
vt = []
f = []
vt_rgb = []
with open('data/1.obj', mode='r', encoding='utf-8') as file_obj:
line = file_obj.readline()
while line != '' :
if(line.startswith('v ')):
v.append(line.split(' ')[1:])
elif(line.startswith('vt ')):
vt.append(map(float, line.split(' ')[1:]))
elif(line.startswith('f ')):
f.append([i.split('/')[0] for i in line.split(' ')[1:]])
line = file_obj.readline()
if(len(v) != len(vt)):
print('len(v) != len(vt)!!')
img = cv2.imread("data/1.texture.png")
height,width,bgra = img.shape
for i in range(len(vt)):
temp_vt = list(vt[i])
h = temp_vt[0] * height
w = temp_vt[1] * width
#邻近过滤 uv方向需要倒过来
color = img[width - int(w)-1][int(h)-1]
red = color[2]
green = color[1]
blue = color[0]
'''
#线性过滤
color1 = img[width - int(w)-1][int(h)-1]
color2 = ...
color3 = ...
color4 = ...
red = ...
green = ...
blue = ...
'''
vt_rgb.append([red, green, blue])
with open('data/11.obj', mode='w', encoding='utf-8') as file_obj:
for i in range(len(v)):
line = 'v ' + v[i][0] + ' ' + v[i][1] + ' ' + v[i][2][:-1] + ' ' + str(vt_rgb[i][0]) + ' ' + str(vt_rgb[i][1]) + ' ' + str(vt_rgb[i][2]) + '\n'
file_obj.write(line)
for i in range(len(f)):
line = 'f ' + f[i][0] + ' ' + f[i][1] + ' ' + f[i][2] + '\n'
file_obj.write(line)
这样就完成了顶点的贴图,不需要添加上mtl和texture文件了。转换完成后的顶点v是带上RGB颜色的,也可以被geomegic、blender这样的软件读取
v 120 138 297.3843078613281 181 122 91
v 120 140 300.5776062011719 186 127 96
欢迎交流