feifeifeiliu's picture
first version
865fd8a
raw
history blame
4.27 kB
#!/usr/bin/env python
# encoding: utf-8
# Copyright (c) 2013 Max Planck Society. All rights reserved.
# Created by Matthew Loper on 2013-02-20.
import numpy as np
"""
texture.py
"""
__all__ = ['texture_coordinates_by_vertex', ]
def texture_coordinates_by_vertex(self):
texture_coordinates_by_vertex = [[] for i in range(len(self.v))]
for i, face in enumerate(self.f):
for j in [0, 1, 2]:
texture_coordinates_by_vertex[face[j]].append(self.vt[self.ft[i][j]])
return texture_coordinates_by_vertex
def reload_texture_image(self):
import cv2
# image is loaded as image_height-by-image_width-by-3 array in BGR color order.
self._texture_image = cv2.imread(self.texture_filepath) if self.texture_filepath else None
texture_sizes = [32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384]
if self._texture_image is not None and (self._texture_image.shape[0] != self._texture_image.shape[1] or
self._texture_image.shape[0] not in texture_sizes or
self._texture_image.shape[0] not in texture_sizes):
closest_texture_size_idx = (np.abs(np.array(texture_sizes) - max(self._texture_image.shape))).argmin()
sz = texture_sizes[closest_texture_size_idx]
self._texture_image = cv2.resize(self._texture_image, (sz, sz))
def load_texture(self, texture_version):
'''
Expect a texture version number as an integer, load the texture version from 'texture_path' (global variable to the
package).
Currently there are versions [0,1,2,3] available.
'''
import os
from . import texture_path
lowres_tex_template = os.path.join(texture_path, 'textured_template_low_v%d.obj' % texture_version)
highres_tex_template = os.path.join(texture_path, 'textured_template_high_v%d.obj' % texture_version)
from .mesh import Mesh
mesh_with_texture = Mesh(filename=lowres_tex_template)
if not np.all(mesh_with_texture.f.shape == self.f.shape):
mesh_with_texture = Mesh(filename=highres_tex_template)
self.transfer_texture(mesh_with_texture)
def transfer_texture(self, mesh_with_texture):
if not np.all(mesh_with_texture.f.shape == self.f.shape):
raise Exception('Mesh topology mismatch')
self.vt = mesh_with_texture.vt.copy()
self.ft = mesh_with_texture.ft.copy()
if not np.all(mesh_with_texture.f == self.f):
if np.all(mesh_with_texture.f == np.fliplr(self.f)):
self.ft = np.fliplr(self.ft)
else:
# Same shape; let's see if it's face ordering; this could be a bit faster...
face_mapping = {}
for f, ii in zip(self.f, range(len(self.f))):
face_mapping[" ".join([str(x) for x in sorted(f)])] = ii
self.ft = np.zeros(self.f.shape, dtype=np.uint32)
for f, ft in zip(mesh_with_texture.f, mesh_with_texture.ft):
k = " ".join([str(x) for x in sorted(f)])
if k not in face_mapping:
raise Exception('Mesh topology mismatch')
# the vertex order can be arbitrary...
ids = []
for f_id in f:
ids.append(np.where(self.f[face_mapping[k]] == f_id)[0][0])
ids = np.array(ids)
self.ft[face_mapping[k]] = np.array(ft[ids])
self.texture_filepath = mesh_with_texture.texture_filepath
self._texture_image = None
def set_texture_image(self, path_to_texture):
self.texture_filepath = path_to_texture
def texture_rgb(self, texture_coordinate):
h, w = np.array(self.texture_image.shape[:2]) - 1
return np.double(self.texture_image[int(h * (1.0 - texture_coordinate[1]))][int(w * (texture_coordinate[0]))])[::-1]
def texture_rgb_vec(self, texture_coordinates):
h, w = np.array(self.texture_image.shape[:2]) - 1
n_ch = self.texture_image.shape[2]
# XXX texture_coordinates can be lower than 0! clip needed!
d1 = (h * (1.0 - np.clip(texture_coordinates[:, 1], 0, 1))).astype(np.int)
d0 = (w * (np.clip(texture_coordinates[:, 0], 0, 1))).astype(np.int)
flat_texture = self.texture_image.flatten()
indices = np.hstack([((d1 * (w + 1) * n_ch) + (d0 * n_ch) + (2 - i)).reshape(-1, 1) for i in range(n_ch)])
return flat_texture[indices]