【计算机视觉】如何将obj文件中的纹理坐标vt转换成顶点v的RGB颜色

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

欢迎交流

你可能感兴趣的:(计算机视觉,python,计算机视觉,opencv)