(normal_pil, rgb_pil, is_back=False, clamp_min=-1, scale=0.3, init_type="std", offset=0)
| 80 | return (w_max - w_min) / (h_max - h_min) |
| 81 | |
| 82 | def build_mesh(normal_pil, rgb_pil, is_back=False, clamp_min=-1, scale=0.3, init_type="std", offset=0): |
| 83 | if is_back: |
| 84 | normal_pil = transform_back_normal_to_front(normal_pil) |
| 85 | normal_img = np.array(normal_pil) |
| 86 | rgb_img = np.array(rgb_pil) |
| 87 | if normal_img.shape[-1] == 4: |
| 88 | valid_HWC = normal_img[..., [3]] / 255 |
| 89 | elif rgb_img.shape[-1] == 4: |
| 90 | valid_HWC = rgb_img[..., [3]] / 255 |
| 91 | else: |
| 92 | raise ValueError("invalid input, either normal or rgb should have alpha channel") |
| 93 | |
| 94 | real_height_pix = np.max(np.where(valid_HWC>0.5)[0]) - np.min(np.where(valid_HWC>0.5)[0]) |
| 95 | |
| 96 | heights = normalmap_to_depthmap(normal_img) |
| 97 | rgb_BCHW = torch.from_numpy(rgb_img[..., :3] / 255.).permute((2,0,1))[None] |
| 98 | valid_HWC[valid_HWC < 0.5] = 0 |
| 99 | valid_HWC[valid_HWC >= 0.5] = 1 |
| 100 | valid_HWC = torch.from_numpy(valid_HWC).bool() |
| 101 | if init_type == "std": |
| 102 | # accurate but not stable |
| 103 | pred_HWC = torch.from_numpy(heights / heights.max() * (real_height_pix / heights.shape[0]) * scale * 2).float()[..., None] |
| 104 | elif init_type == "thin": |
| 105 | heights = heights - heights.min() |
| 106 | heights = (heights / heights.max() * 0.2) |
| 107 | pred_HWC = torch.from_numpy(heights * scale).float()[..., None] |
| 108 | else: |
| 109 | # stable but not accurate |
| 110 | heights = heights - heights.min() |
| 111 | heights = (heights / heights.max() * (1-offset)) + offset # to [0.2, 1] |
| 112 | pred_HWC = torch.from_numpy(heights * scale).float()[..., None] |
| 113 | |
| 114 | # set the boarder pixels to 0 height |
| 115 | import cv2 |
| 116 | # edge filter |
| 117 | edge = cv2.Canny((valid_HWC[..., 0] * 255).numpy().astype(np.uint8), 0, 255) |
| 118 | edge = torch.from_numpy(edge).bool()[..., None] |
| 119 | pred_HWC[edge] = 0 |
| 120 | |
| 121 | valid_HWC[pred_HWC < clamp_min] = False |
| 122 | return depth_and_color_to_mesh(rgb_BCHW.cuda(), pred_HWC.cuda(), valid_HWC.cuda(), is_back) |
| 123 | |
| 124 | def fix_border_with_pymeshlab_fast(meshes: Meshes, poissson_depth=6, simplification=0): |
| 125 | ms = pymeshlab.MeshSet() |
no test coverage detected