-
Depth_Render.pyBase Line/python 기초 코드 2022. 3. 16. 08:23
##Depth_Render.py """ 무수한 주석처리 양해좀 ㅎㅎ """ import torch.nn as nn import torch #from engineer.render.PIFuhd import gl # 기본으로 해줘야됨 from .Base_Render import _Base_Render # 노말 체크 from .registry import NORMAL_RENDER # face3D from engineer.render.face3d import mesh import numpy as np from PIL import Image ######check from math import cos, sin def similarity_transform(vertices, s, R, t3d): ''' similarity transform. dof = 7. 3D: s*R.dot(X) + t Homo: M = [[sR, t],[0^T, 1]]. M.dot(X) Args:(float32) vertices: [nver, 3]. s: [1,]. scale factor. R: [3,3]. rotation matrix. t3d: [3,]. 3d translation vector. Returns: transformed vertices: [nver, 3] ''' t3d = np.squeeze(np.array(t3d, dtype = np.float32)) transformed_vertices = s * vertices.dot(R.T) + t3d[np.newaxis, :] return transformed_vertices def to_image(vertices, h, w, is_perspective = False): ''' change vertices to image coord system 3d system: XYZ, center(0, 0, 0) 2d image: x(u), y(v). center(w/2, h/2), flip y-axis. Args: vertices: [nver, 3] h: height of the rendering w : width of the rendering Returns: projected_vertices: [nver, 3] ''' image_vertices = vertices.copy() if is_perspective: # if perspective, the projected vertices are normalized to [-1, 1]. so change it to image size first. image_vertices[:,0] = image_vertices[:,0]*w/2 image_vertices[:,1] = image_vertices[:,1]*h/2 # move to center of image image_vertices[:,0] = image_vertices[:,0] + w/2 image_vertices[:,1] = image_vertices[:,1] + h/2 # flip vertices along y-axis. image_vertices[:,1] = h - image_vertices[:,1] - 1 return image_vertices def angle2matrix(angles): ''' get rotation matrix from three rotation angles(degree). right-handed. Args: angles: [3,]. x, y, z angles x: pitch. positive for looking down. y: yaw. positive for looking left. z: roll. positive for tilting head right. Returns: R: [3, 3]. rotation matrix. ''' x, y, z = np.deg2rad(angles[0]), np.deg2rad(angles[1]), np.deg2rad(angles[2]) # x Rx=np.array([[1, 0, 0], [0, cos(x), -sin(x)], [0, sin(x), cos(x)]]) # y Ry=np.array([[ cos(y), 0, sin(y)], [ 0, 1, 0], [-sin(y), 0, cos(y)]]) # z Rz=np.array([[cos(z), -sin(z), 0], [sin(z), cos(z), 0], [ 0, 0, 1]]) R=Rz.dot(Ry.dot(Rx)) return R.astype(np.float32) @NORMAL_RENDER.register_module class Noraml_Render(_Base_Render): """Render class for getting normal map here attribute is based on vertex normal we normalized value of them into [0,1] Note that trimesh.verts_normals normal always from [-1, 1] """ def __init__(self, width: int, height: int, render_lib="face3d", flip=False): super(Noraml_Render, self).__init__(width, height, render_lib) self.__render = self.render_lib self.name = "Normal_render" self.flip_normal = flip self.input_para["flip_normal"] = flip self.render_image = None self.render_mask = None def set_attribute(self): """attribute you want to set when you render For normal render class, we only need normal information, which means """ # vertices = self.render_mesh.vertices # # [-1,1] # render_mesh !!! #self.z = self.render_mesh.vertices[:, 2:] h,w=self.height,self.width R=angle2matrix([0,0,0]) t=[0,0,0] self.vertices = self.render_mesh.vertices[:,:] s=180/(np.max(self.vertices[:,1])-np.min(self.vertices[:,1])) transformed_vertices = similarity_transform(self.vertices,s,R,t) image_vertices = to_image(transformed_vertices,h,w) self.z = image_vertices[:,2:] self.z = self.z - np.min(self.z) self.z = self.z / (np.max(self.z)-np.min(self.z)) self.z=self.z-1 #self.z=get_z_value(self.z) self.attribute = self.z #### def get_render(self): """capture render images Parameters: None return: render_image [H, W, C = 3] render_mask [H, W] ---> 0 means background else frontground """ assert self.render_image is not None, "you need call draw method, previously" assert self.render_mask is not None, "you need call draw method, previously" return self.render_image, self.render_mask def draw(self): """draw render image, it needs you set_mesh, previously. after call draw method, you will get two attribute, render image and render mask """ #####face3d 노말 랜더링 사용 부분 if self.render_lib == "face3d": attribute = self.attribute #attribute = np.concatenate( # [self.attribute, np.ones([self.attribute.shape[0], 1])], axis=1 #) # render_colors face에서 컬러 합치는 부분 attribute => 노말 # normal_map = mesh.render.render_colors(self.render_mesh.vertices, self.render_mesh.faces, attribute, self.height, self.width, c=4) depth_image = mesh.render.render_colors( self.render_mesh.vertices, self.render_mesh.faces, attribute, self.height, self.width, c=1, ) #mask = depth_image[..., 3] mask = depth_image[...] print(np.shape(depth_image)) #print(1111111111) depth_image = depth_image[...] #depth_image = depth_image[... 2:] #depth_image = (depth_image + 1) / 2 # 배열 이미지로 변환 255는 정규화? 0~255 맞추기 depth_image=np.squeeze(depth_image,axis=2) self.render_image = Image.fromarray((depth_image * 255).astype(np.uint8)) self.render_mask = mask else: raise NotImplementedError
Thank you for pifuhd & open-pifuhd
'Base Line > python 기초 코드' 카테고리의 다른 글
pillow 이미지 rotation, flip (1) 2022.04.18 data_loader (0) 2022.04.04 open3d extract depth map from mesh (2) 2022.03.14 path & os (0) 2022.03.09 Numpy (0) 2022.02.21