magic123 0.1.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (171) hide show
  1. activation.py +21 -0
  2. all_metrics/metric_utils.py +459 -0
  3. dnnultis/__init__.py +1 -0
  4. dnnultis/log/__init__.py +2 -0
  5. dnnultis/log/logger.py +86 -0
  6. dnnultis/log/wandb.py +84 -0
  7. dpt.py +924 -0
  8. encoding.py +89 -0
  9. freqencoder/__init__.py +1 -0
  10. freqencoder/backend.py +42 -0
  11. freqencoder/freq.py +77 -0
  12. freqencoder/setup.py +25 -0
  13. freqencoder/src/bindings.cpp +8 -0
  14. freqencoder/src/freqencoder.cu +129 -0
  15. freqencoder/src/freqencoder.h +10 -0
  16. gradio_app.py +246 -0
  17. gridencoder/__init__.py +1 -0
  18. gridencoder/backend.py +40 -0
  19. gridencoder/grid.py +206 -0
  20. gridencoder/setup.py +24 -0
  21. gridencoder/src/bindings.cpp +10 -0
  22. gridencoder/src/gridencoder.cu +713 -0
  23. gridencoder/src/gridencoder.h +18 -0
  24. guidance/clip_utils.py +52 -0
  25. guidance/if_utils.py +207 -0
  26. guidance/sd_utils.py +707 -0
  27. guidance/shape_utils.py +81 -0
  28. guidance/zero123_utils.py +332 -0
  29. ldm/extras.py +77 -0
  30. ldm/guidance.py +96 -0
  31. ldm/lr_scheduler.py +98 -0
  32. ldm/models/autoencoder.py +443 -0
  33. ldm/models/diffusion/__init__.py +0 -0
  34. ldm/models/diffusion/classifier.py +267 -0
  35. ldm/models/diffusion/ddim.py +328 -0
  36. ldm/models/diffusion/ddpm.py +1994 -0
  37. ldm/models/diffusion/plms.py +259 -0
  38. ldm/models/diffusion/sampling_util.py +50 -0
  39. ldm/modules/attention.py +266 -0
  40. ldm/modules/diffusionmodules/__init__.py +0 -0
  41. ldm/modules/diffusionmodules/model.py +835 -0
  42. ldm/modules/diffusionmodules/openaimodel.py +996 -0
  43. ldm/modules/diffusionmodules/util.py +267 -0
  44. ldm/modules/distributions/__init__.py +0 -0
  45. ldm/modules/distributions/distributions.py +92 -0
  46. ldm/modules/ema.py +76 -0
  47. ldm/modules/encoders/__init__.py +0 -0
  48. ldm/modules/encoders/modules.py +550 -0
  49. ldm/modules/evaluate/adm_evaluator.py +676 -0
  50. ldm/modules/evaluate/evaluate_perceptualsim.py +630 -0
  51. ldm/modules/evaluate/frechet_video_distance.py +147 -0
  52. ldm/modules/evaluate/ssim.py +124 -0
  53. ldm/modules/evaluate/torch_frechet_video_distance.py +294 -0
  54. ldm/modules/image_degradation/__init__.py +2 -0
  55. ldm/modules/image_degradation/bsrgan.py +730 -0
  56. ldm/modules/image_degradation/bsrgan_light.py +650 -0
  57. ldm/modules/image_degradation/utils_image.py +916 -0
  58. ldm/modules/losses/__init__.py +1 -0
  59. ldm/modules/losses/contperceptual.py +111 -0
  60. ldm/modules/losses/vqperceptual.py +167 -0
  61. ldm/modules/x_transformer.py +641 -0
  62. ldm/thirdp/psp/helpers.py +121 -0
  63. ldm/thirdp/psp/id_loss.py +23 -0
  64. ldm/thirdp/psp/model_irse.py +86 -0
  65. ldm/util.py +227 -0
  66. magic123-0.1.0.dist-info/METADATA +426 -0
  67. magic123-0.1.0.dist-info/RECORD +171 -0
  68. magic123-0.1.0.dist-info/WHEEL +5 -0
  69. magic123-0.1.0.dist-info/licenses/LICENSE +201 -0
  70. magic123-0.1.0.dist-info/top_level.txt +22 -0
  71. main.py +630 -0
  72. meshutils.py +117 -0
  73. midas/__init__.py +1 -0
  74. midas/backbones/beit.py +196 -0
  75. midas/backbones/levit.py +106 -0
  76. midas/backbones/next_vit.py +39 -0
  77. midas/backbones/swin.py +13 -0
  78. midas/backbones/swin2.py +34 -0
  79. midas/backbones/swin_common.py +52 -0
  80. midas/backbones/utils.py +249 -0
  81. midas/backbones/vit.py +221 -0
  82. midas/base_model.py +16 -0
  83. midas/blocks.py +439 -0
  84. midas/dpt_depth.py +166 -0
  85. midas/midas_net.py +76 -0
  86. midas/midas_net_custom.py +128 -0
  87. midas/model_loader.py +242 -0
  88. midas/transforms.py +234 -0
  89. nerf/clip.py +127 -0
  90. nerf/gui.py +485 -0
  91. nerf/network.py +238 -0
  92. nerf/network_grid.py +216 -0
  93. nerf/network_grid_taichi.py +161 -0
  94. nerf/network_grid_tcnn.py +178 -0
  95. nerf/provider.py +329 -0
  96. nerf/renderer.py +1575 -0
  97. nerf/utils.py +1599 -0
  98. optimizer.py +325 -0
  99. preprocess_image.py +279 -0
  100. raymarching/__init__.py +1 -0
  101. raymarching/backend.py +41 -0
  102. raymarching/raymarching.py +398 -0
  103. raymarching/setup.py +36 -0
  104. raymarching/src/bindings.cpp +20 -0
  105. raymarching/src/raymarching.cu +934 -0
  106. raymarching/src/raymarching.h +19 -0
  107. render/light.py +158 -0
  108. render/material.py +182 -0
  109. render/mesh.py +241 -0
  110. render/mlptexture.py +111 -0
  111. render/obj.py +179 -0
  112. render/regularizer.py +82 -0
  113. render/render.py +311 -0
  114. render/renderutils/__init__.py +11 -0
  115. render/renderutils/bsdf.py +151 -0
  116. render/renderutils/c_src/bsdf.cu +710 -0
  117. render/renderutils/c_src/bsdf.h +84 -0
  118. render/renderutils/c_src/common.cpp +74 -0
  119. render/renderutils/c_src/common.h +41 -0
  120. render/renderutils/c_src/cubemap.cu +350 -0
  121. render/renderutils/c_src/cubemap.h +38 -0
  122. render/renderutils/c_src/loss.cu +210 -0
  123. render/renderutils/c_src/loss.h +38 -0
  124. render/renderutils/c_src/mesh.cu +94 -0
  125. render/renderutils/c_src/mesh.h +23 -0
  126. render/renderutils/c_src/normal.cu +182 -0
  127. render/renderutils/c_src/normal.h +27 -0
  128. render/renderutils/c_src/tensor.h +92 -0
  129. render/renderutils/c_src/torch_bindings.cpp +1062 -0
  130. render/renderutils/c_src/vec3f.h +109 -0
  131. render/renderutils/c_src/vec4f.h +25 -0
  132. render/renderutils/loss.py +41 -0
  133. render/renderutils/ops.py +554 -0
  134. render/renderutils/tests/test_bsdf.py +296 -0
  135. render/renderutils/tests/test_cubemap.py +47 -0
  136. render/renderutils/tests/test_loss.py +61 -0
  137. render/renderutils/tests/test_mesh.py +90 -0
  138. render/renderutils/tests/test_perf.py +57 -0
  139. render/texture.py +186 -0
  140. render/util.py +465 -0
  141. setup_cuda_ext.py +129 -0
  142. shencoder/__init__.py +1 -0
  143. shencoder/backend.py +41 -0
  144. shencoder/setup.py +24 -0
  145. shencoder/sphere_harmonics.py +87 -0
  146. shencoder/src/bindings.cpp +8 -0
  147. shencoder/src/shencoder.cu +439 -0
  148. shencoder/src/shencoder.h +10 -0
  149. taichi_modules/__init__.py +5 -0
  150. taichi_modules/hash_encoder.py +305 -0
  151. taichi_modules/intersection.py +68 -0
  152. taichi_modules/ray_march.py +340 -0
  153. taichi_modules/utils.py +224 -0
  154. taichi_modules/volume_render_test.py +48 -0
  155. taichi_modules/volume_train.py +239 -0
  156. taming/lr_scheduler.py +34 -0
  157. taming/models/cond_transformer.py +352 -0
  158. taming/models/dummy_cond_stage.py +22 -0
  159. taming/models/vqgan.py +404 -0
  160. taming/modules/diffusionmodules/model.py +776 -0
  161. taming/modules/discriminator/model.py +67 -0
  162. taming/modules/losses/__init__.py +2 -0
  163. taming/modules/losses/lpips.py +123 -0
  164. taming/modules/losses/segmentation.py +22 -0
  165. taming/modules/losses/vqperceptual.py +136 -0
  166. taming/modules/misc/coord.py +31 -0
  167. taming/modules/transformer/mingpt.py +415 -0
  168. taming/modules/transformer/permuter.py +248 -0
  169. taming/modules/util.py +130 -0
  170. taming/modules/vqvae/quantize.py +445 -0
  171. taming/util.py +157 -0
activation.py ADDED
@@ -0,0 +1,21 @@
1
+ import torch
2
+ from torch.autograd import Function
3
+ from torch.cuda.amp import custom_bwd, custom_fwd
4
+
5
+ class _trunc_exp(Function):
6
+ @staticmethod
7
+ @custom_fwd(cast_inputs=torch.float)
8
+ def forward(ctx, x):
9
+ ctx.save_for_backward(x)
10
+ return torch.exp(x)
11
+
12
+ @staticmethod
13
+ @custom_bwd
14
+ def backward(ctx, g):
15
+ x = ctx.saved_tensors[0]
16
+ return g * torch.exp(x.clamp(max=15))
17
+
18
+ trunc_exp = _trunc_exp.apply
19
+
20
+ def biased_softplus(x, bias=0):
21
+ return torch.nn.functional.softplus(x - bias)
@@ -0,0 +1,459 @@
1
+ # * evaluate use laion/CLIP-ViT-H-14-laion2B-s32B-b79K
2
+ # best open source clip so far: laion/CLIP-ViT-bigG-14-laion2B-39B-b160k
3
+ # code adapted from NeuralLift-360
4
+
5
+ import torch
6
+ import torch.nn as nn
7
+ import os
8
+ import torchvision.transforms as T
9
+ import torchvision.transforms.functional as TF
10
+ import matplotlib.pyplot as plt
11
+ # import clip
12
+ from transformers import CLIPFeatureExtractor, CLIPModel, CLIPTokenizer, CLIPProcessor
13
+ from torchvision import transforms
14
+ import numpy as np
15
+ import torch.nn.functional as F
16
+ from tqdm import tqdm
17
+ import cv2
18
+ from PIL import Image
19
+ # import torchvision.transforms as transforms
20
+ import glob
21
+ from skimage.metrics import peak_signal_noise_ratio as compare_psnr
22
+ import lpips
23
+ from os.path import join as osp
24
+ import argparse
25
+ import pandas as pd
26
+
27
+ class CLIP(nn.Module):
28
+
29
+ def __init__(self,
30
+ device,
31
+ clip_name='laion/CLIP-ViT-bigG-14-laion2B-39B-b160k',
32
+ size=224): #'laion/CLIP-ViT-B-32-laion2B-s34B-b79K'):
33
+ super().__init__()
34
+ self.size = size
35
+ self.device = f"cuda:{device}"
36
+
37
+ clip_name = clip_name
38
+
39
+ self.feature_extractor = CLIPFeatureExtractor.from_pretrained(
40
+ clip_name)
41
+ self.clip_model = CLIPModel.from_pretrained(clip_name).to(self.device)
42
+ self.tokenizer = CLIPTokenizer.from_pretrained(
43
+ 'openai/clip-vit-base-patch32')
44
+
45
+ self.normalize = transforms.Normalize(
46
+ mean=self.feature_extractor.image_mean,
47
+ std=self.feature_extractor.image_std)
48
+
49
+ self.resize = transforms.Resize(224)
50
+ self.to_tensor = transforms.ToTensor()
51
+
52
+ # image augmentation
53
+ self.aug = T.Compose([
54
+ T.Resize((224, 224)),
55
+ T.Normalize((0.48145466, 0.4578275, 0.40821073),
56
+ (0.26862954, 0.26130258, 0.27577711)),
57
+ ])
58
+
59
+ # * recommend to use this function for evaluation
60
+ @torch.no_grad()
61
+ def score_gt(self, ref_img_path, novel_views):
62
+ # assert len(novel_views) == 100
63
+ clip_scores = []
64
+ for novel in novel_views:
65
+ clip_scores.append(self.score_from_path(ref_img_path, [novel]))
66
+ return np.mean(clip_scores)
67
+
68
+ # * recommend to use this function for evaluation
69
+ # def score_gt(self, ref_paths, novel_paths):
70
+ # clip_scores = []
71
+ # for img1_path, img2_path in zip(ref_paths, novel_paths):
72
+ # clip_scores.append(self.score_from_path(img1_path, img2_path))
73
+
74
+ # return np.mean(clip_scores)
75
+
76
+ def similarity(self, image1_features: torch.Tensor,
77
+ image2_features: torch.Tensor) -> float:
78
+ with torch.no_grad(), torch.cuda.amp.autocast():
79
+ y = image1_features.T.view(image1_features.T.shape[1],
80
+ image1_features.T.shape[0])
81
+ similarity = torch.matmul(y, image2_features.T)
82
+ # print(similarity)
83
+ return similarity[0][0].item()
84
+
85
+ def get_img_embeds(self, img):
86
+ if img.shape[0] == 4:
87
+ img = img[:3, :, :]
88
+
89
+ img = self.aug(img).to(self.device)
90
+ img = img.unsqueeze(0) # b,c,h,w
91
+
92
+ # plt.imshow(img.cpu().squeeze(0).permute(1, 2, 0).numpy())
93
+ # plt.show()
94
+ # print(img)
95
+
96
+ image_z = self.clip_model.get_image_features(img)
97
+ image_z = image_z / image_z.norm(dim=-1,
98
+ keepdim=True) # normalize features
99
+ return image_z
100
+
101
+ def score_from_feature(self, img1, img2):
102
+ img1_feature, img2_feature = self.get_img_embeds(
103
+ img1), self.get_img_embeds(img2)
104
+ # for debug
105
+ return self.similarity(img1_feature, img2_feature)
106
+
107
+ def read_img_list(self, img_list):
108
+ size = self.size
109
+ images = []
110
+ # white_background = np.ones((size, size, 3), dtype=np.uint8) * 255
111
+
112
+ for img_path in img_list:
113
+ img = cv2.imread(img_path, cv2.IMREAD_UNCHANGED)
114
+ # print(img_path)
115
+ if img.shape[2] == 4: # Handle BGRA images
116
+ alpha = img[:, :, 3] # Extract alpha channel
117
+ img = cv2.cvtColor(img,cv2.COLOR_BGRA2RGB) # Convert BGRA to BGR
118
+ img[np.where(alpha == 0)] = [
119
+ 255, 255, 255
120
+ ] # Set transparent pixels to white
121
+ else: # Handle other image formats like JPG and PNG
122
+ img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
123
+
124
+ img = cv2.resize(img, (size, size), interpolation=cv2.INTER_AREA)
125
+
126
+ # plt.imshow(img)
127
+ # plt.show()
128
+
129
+ images.append(img)
130
+
131
+ images = np.stack(images, axis=0)
132
+ # images[np.where(images == 0)] = 255 # Set black pixels to white
133
+ # images = np.where(images == 0, white_background, images) # Set transparent pixels to white
134
+ # images = images.astype(np.float32)
135
+
136
+ return images
137
+
138
+ def score_from_path(self, img1_path, img2_path):
139
+ img1, img2 = self.read_img_list(img1_path), self.read_img_list(img2_path)
140
+ img1 = np.squeeze(img1)
141
+ img2 = np.squeeze(img2)
142
+ # plt.imshow(img1)
143
+ # plt.show()
144
+ # plt.imshow(img2)
145
+ # plt.show()
146
+
147
+ img1, img2 = self.to_tensor(img1), self.to_tensor(img2)
148
+ # print("img1 to tensor ",img1)
149
+ return self.score_from_feature(img1, img2)
150
+
151
+
152
+ def numpy_to_torch(images):
153
+ images = images * 2.0 - 1.0
154
+ images = torch.from_numpy(images.transpose((0, 3, 1, 2))).float()
155
+ return images.cuda()
156
+
157
+
158
+ class LPIPSMeter:
159
+
160
+ def __init__(self,
161
+ net='alex',
162
+ device=None,
163
+ size=224): # or we can use 'alex', 'vgg' as network
164
+ self.size = size
165
+ self.net = net
166
+ self.results = []
167
+ self.device = device if device is not None else torch.device(
168
+ 'cuda' if torch.cuda.is_available() else 'cpu')
169
+ self.fn = lpips.LPIPS(net=net).eval().to(self.device)
170
+
171
+ def measure(self):
172
+ return np.mean(self.results)
173
+
174
+ def report(self):
175
+ return f'LPIPS ({self.net}) = {self.measure():.6f}'
176
+
177
+ def read_img_list(self, img_list):
178
+ size = self.size
179
+ images = []
180
+ white_background = np.ones((size, size, 3), dtype=np.uint8) * 255
181
+
182
+ for img_path in img_list:
183
+ img = cv2.imread(img_path, cv2.IMREAD_UNCHANGED)
184
+
185
+ if img.shape[2] == 4: # Handle BGRA images
186
+ alpha = img[:, :, 3] # Extract alpha channel
187
+ img = cv2.cvtColor(img,
188
+ cv2.COLOR_BGRA2BGR) # Convert BGRA to BGR
189
+
190
+ img = cv2.cvtColor(img,
191
+ cv2.COLOR_BGR2RGB) # Convert BGR to RGB
192
+ img[np.where(alpha == 0)] = [
193
+ 255, 255, 255
194
+ ] # Set transparent pixels to white
195
+ else: # Handle other image formats like JPG and PNG
196
+ img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
197
+
198
+ img = cv2.resize(img, (size, size), interpolation=cv2.INTER_AREA)
199
+ images.append(img)
200
+
201
+ images = np.stack(images, axis=0)
202
+ # images[np.where(images == 0)] = 255 # Set black pixels to white
203
+ # images = np.where(images == 0, white_background, images) # Set transparent pixels to white
204
+ images = images.astype(np.float32) / 255.0
205
+
206
+ return images
207
+
208
+ # * recommend to use this function for evaluation
209
+ @torch.no_grad()
210
+ def score_gt(self, ref_paths, novel_paths):
211
+ self.results = []
212
+ for path0, path1 in zip(ref_paths, novel_paths):
213
+ # Load images
214
+ # img0 = lpips.im2tensor(lpips.load_image(path0)).cuda() # RGB image from [-1,1]
215
+ # img1 = lpips.im2tensor(lpips.load_image(path1)).cuda()
216
+ img0, img1 = self.read_img_list([path0]), self.read_img_list(
217
+ [path1])
218
+ img0, img1 = numpy_to_torch(img0), numpy_to_torch(img1)
219
+ # print(img0.shape,img1.shape)
220
+ img0 = F.interpolate(img0,
221
+ size=(self.size, self.size),
222
+ mode='area')
223
+ img1 = F.interpolate(img1,
224
+ size=(self.size, self.size),
225
+ mode='area')
226
+
227
+ # for debug vis
228
+ # plt.imshow(img0.cpu().squeeze(0).permute(1, 2, 0).numpy())
229
+ # plt.show()
230
+ # plt.imshow(img1.cpu().squeeze(0).permute(1, 2, 0).numpy())
231
+ # plt.show()
232
+ # equivalent to cv2.resize(rgba, (w, h), interpolation=cv2.INTER_AREA
233
+
234
+ # print(img0.shape,img1.shape)
235
+
236
+ self.results.append(self.fn.forward(img0, img1).cpu().numpy())
237
+
238
+ return self.measure()
239
+
240
+
241
+ class PSNRMeter:
242
+
243
+ def __init__(self, size=800):
244
+ self.results = []
245
+ self.size = size
246
+
247
+ def read_img_list(self, img_list):
248
+ size = self.size
249
+ images = []
250
+ white_background = np.ones((size, size, 3), dtype=np.uint8) * 255
251
+ for img_path in img_list:
252
+ img = cv2.imread(img_path, cv2.IMREAD_UNCHANGED)
253
+
254
+ if img.shape[2] == 4: # Handle BGRA images
255
+ alpha = img[:, :, 3] # Extract alpha channel
256
+ img = cv2.cvtColor(img,
257
+ cv2.COLOR_BGRA2BGR) # Convert BGRA to BGR
258
+
259
+ img = cv2.cvtColor(img,
260
+ cv2.COLOR_BGR2RGB) # Convert BGR to RGB
261
+ img[np.where(alpha == 0)] = [
262
+ 255, 255, 255
263
+ ] # Set transparent pixels to white
264
+ else: # Handle other image formats like JPG and PNG
265
+ img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
266
+
267
+ img = cv2.resize(img, (size, size), interpolation=cv2.INTER_AREA)
268
+ images.append(img)
269
+
270
+ images = np.stack(images, axis=0)
271
+ # images[np.where(images == 0)] = 255 # Set black pixels to white
272
+ # images = np.where(images == 0, white_background, images) # Set transparent pixels to white
273
+ images = images.astype(np.float32) / 255.0
274
+ # print(images.shape)
275
+ return images
276
+
277
+ def update(self, preds, truths):
278
+ # print(preds.shape)
279
+
280
+ psnr_values = []
281
+ # For each pair of images in the batches
282
+ for img1, img2 in zip(preds, truths):
283
+ # Compute the PSNR and add it to the list
284
+ # print(img1.shape,img2.shape)
285
+
286
+ # for debug
287
+ # plt.imshow(img1)
288
+ # plt.show()
289
+ # plt.imshow(img2)
290
+ # plt.show()
291
+
292
+ psnr = compare_psnr(
293
+ img1, img2,
294
+ data_range=1.0) # assuming your images are scaled to [0,1]
295
+ # print(f"temp psnr {psnr}")
296
+ psnr_values.append(psnr)
297
+
298
+ # Convert the list of PSNR values to a numpy array
299
+ self.results = psnr_values
300
+
301
+ def measure(self):
302
+ return np.mean(self.results)
303
+
304
+ def report(self):
305
+ return f'PSNR = {self.measure():.6f}'
306
+
307
+ # * recommend to use this function for evaluation
308
+ def score_gt(self, ref_paths, novel_paths):
309
+ self.results = []
310
+ # [B, N, 3] or [B, H, W, 3], range[0, 1]
311
+ preds = self.read_img_list(ref_paths)
312
+ truths = self.read_img_list(novel_paths)
313
+ self.update(preds, truths)
314
+ return self.measure()
315
+
316
+ all_inputs = 'data'
317
+ nerf_dataset = os.listdir(osp(all_inputs, 'nerf4'))
318
+ realfusion_dataset = os.listdir(osp(all_inputs, 'realfusion15'))
319
+ meta_examples = {
320
+ 'nerf4': nerf_dataset,
321
+ 'realfusion15': realfusion_dataset,
322
+ }
323
+ all_datasets = meta_examples.keys()
324
+
325
+ # organization 1
326
+ def deprecated_score_from_method_for_dataset(my_scorer,
327
+ method,
328
+ dataset,
329
+ input,
330
+ output,
331
+ score_type='clip',
332
+ ): # psnr, lpips
333
+ # print("\n\n\n")
334
+ # print(f"______{method}___{dataset}___{score_type}_________")
335
+ scores = {}
336
+ final_res = 0
337
+ examples = meta_examples[dataset]
338
+ for i in range(len(examples)):
339
+
340
+ # compare entire folder for clip
341
+ if score_type == 'clip':
342
+ novel_view = osp(pred_path, examples[i], 'colors')
343
+ # compare first image for other metrics
344
+ else:
345
+ if method == '3d_fuse': method = '3d_fuse_0'
346
+ novel_view = list(
347
+ glob.glob(
348
+ osp(pred_path, examples[i], 'colors',
349
+ 'step_0000*')))[0]
350
+
351
+ score_i = my_scorer.score_gt(
352
+ [], [novel_view])
353
+ scores[examples[i]] = score_i
354
+ final_res += score_i
355
+ # print(scores, " Avg : ", final_res / len(examples))
356
+ # print("``````````````````````")
357
+ return scores
358
+
359
+ # results organization 2
360
+ def score_from_method_for_dataset(my_scorer,
361
+ input_path,
362
+ pred_path,
363
+ score_type='clip',
364
+ rgb_name='lambertian',
365
+ result_folder='results/images',
366
+ first_str='*0000*'
367
+ ): # psnr, lpips
368
+ scores = {}
369
+ final_res = 0
370
+ examples = os.listdir(input_path)
371
+ for i in range(len(examples)):
372
+ # ref path
373
+ ref_path = osp(input_path, examples[i], 'rgba.png')
374
+ # compare entire folder for clip
375
+ if score_type == 'clip':
376
+ novel_view = glob.glob(osp(pred_path,'*'+examples[i]+'*', result_folder, f'*{rgb_name}*'))
377
+ print(f'[INOF] {score_type} loss for example {examples[i]} between 1 GT and {len(novel_view)} predictions')
378
+ # compare first image for other metrics
379
+ else:
380
+ novel_view = glob.glob(osp(pred_path, '*'+examples[i]+'*/', result_folder, f'{first_str}{rgb_name}*'))
381
+ print(f'[INOF] {score_type} loss for example {examples[i]} between {ref_path} and {novel_view}')
382
+ # breakpoint()
383
+ score_i = my_scorer.score_gt([ref_path], novel_view)
384
+ scores[examples[i]] = score_i
385
+ final_res += score_i
386
+ avg_score = final_res / len(examples)
387
+ scores['average'] = avg_score
388
+ return scores
389
+
390
+
391
+ if __name__ == "__main__":
392
+ parser = argparse.ArgumentParser(
393
+ description="Script to accept three string arguments")
394
+ parser.add_argument("--input_path",
395
+ default=all_inputs,
396
+ help="Specify the input path")
397
+ parser.add_argument("--pred_pattern",
398
+ default="out/magic123*",
399
+ help="Specify the pattern of predition paths")
400
+ parser.add_argument("--results_folder",
401
+ default="results/images",
402
+ help="where are the results under each pred_path")
403
+ parser.add_argument("--rgb_name",
404
+ default="lambertian",
405
+ help="the postfix of the image")
406
+ parser.add_argument("--first_str",
407
+ default="*0000*",
408
+ help="the str to indicate the first view")
409
+ parser.add_argument("--datasets",
410
+ default=all_datasets,
411
+ nargs='*',
412
+ help="Specify the output path")
413
+ parser.add_argument("--device",
414
+ type=int,
415
+ default=0,
416
+ help="Specify the GPU device to be used")
417
+ parser.add_argument("--save_dir", type=str, default='all_metrics/results')
418
+ args = parser.parse_args()
419
+
420
+ clip_scorer = CLIP(args.device)
421
+ lpips_scorer = LPIPSMeter()
422
+ psnr_scorer = PSNRMeter()
423
+
424
+ os.makedirs(args.save_dir, exist_ok=True)
425
+
426
+ for dataset in args.datasets:
427
+ input_path = osp(args.input_path, dataset)
428
+
429
+ # assume the pred_path is organized as: pred_path/methods/dataset
430
+ pred_pattern = osp(args.pred_pattern, dataset)
431
+ pred_paths = glob.glob(pred_pattern)
432
+ print(f"[INFO] Following the pattern {pred_pattern}, find {len(pred_paths)} pred_paths: \n", pred_paths)
433
+ if len(pred_paths) == 0:
434
+ raise IOError
435
+ for pred_path in pred_paths:
436
+ if not os.path.exists(pred_path):
437
+ print(f'[WARN] prediction does not exit for {pred_path}')
438
+ else:
439
+ print(f'[INFO] evaluate {pred_path}')
440
+ results_dict = {}
441
+ results_dict['clip'] = score_from_method_for_dataset(
442
+ clip_scorer, input_path, pred_path, 'clip',
443
+ result_folder=args.results_folder, rgb_name=args.rgb_name, first_str=args.first_str)
444
+
445
+ results_dict['psnr'] = score_from_method_for_dataset(
446
+ psnr_scorer, input_path, pred_path, 'psnr',
447
+ result_folder=args.results_folder, rgb_name=args.rgb_name, first_str=args.first_str)
448
+
449
+ results_dict['lpips'] = score_from_method_for_dataset(
450
+ lpips_scorer, input_path, pred_path, 'lpips',
451
+ result_folder=args.results_folder, rgb_name=args.rgb_name, first_str=args.first_str)
452
+
453
+ df = pd.DataFrame(results_dict)
454
+ method = pred_path.split('/')[-2]
455
+ print(osp(pred_path, args.results_folder))
456
+ results_str = '_'.join(args.results_folder.split('/'))
457
+ print(method+'-'+results_str)
458
+ print(df)
459
+ df.to_csv(f"{args.save_dir}/{method}-{results_str}-{dataset}.csv")
dnnultis/__init__.py ADDED
@@ -0,0 +1 @@
1
+ from .log import *
@@ -0,0 +1,2 @@
1
+ from .logger import *
2
+ from .wandb import *
dnnultis/log/logger.py ADDED
@@ -0,0 +1,86 @@
1
+ import functools
2
+ import logging
3
+ import os, sys
4
+ from termcolor import colored
5
+
6
+
7
+ class _ColorfulFormatter(logging.Formatter):
8
+ def __init__(self, *args, **kwargs):
9
+ self._root_name = kwargs.pop("root_name") + "."
10
+ self._abbrev_name = kwargs.pop("abbrev_name", "")
11
+ if len(self._abbrev_name):
12
+ self._abbrev_name = self._abbrev_name + "."
13
+ super(_ColorfulFormatter, self).__init__(*args, **kwargs)
14
+
15
+ def formatMessage(self, record):
16
+ record.name = record.name.replace(self._root_name, self._abbrev_name)
17
+ log = super(_ColorfulFormatter, self).formatMessage(record)
18
+ if record.levelno == logging.WARNING:
19
+ prefix = colored("WARNING", "red", attrs=["blink"])
20
+ elif record.levelno == logging.ERROR or record.levelno == logging.CRITICAL:
21
+ prefix = colored("ERROR", "red", attrs=["blink", "underline"])
22
+ else:
23
+ return log
24
+ return prefix + " " + log
25
+
26
+
27
+ # so that calling setup_logging.root multiple times won't add many handlers
28
+ @functools.lru_cache()
29
+ def setup_logging(output=None,
30
+ distributed_rank=0,
31
+ default_level=logging.INFO,
32
+ *,
33
+ color=True,
34
+ name=__name__):
35
+ """
36
+ Initialize the detectron2 logging.root and set its verbosity level to "INFO".
37
+ Args:
38
+ output (str): a file name or a directory to save log. If None, will not save log file.
39
+ If ends with ".txt" or ".log", assumed to be a file name.
40
+ Otherwise, logs will be saved to `output/log.txt`.
41
+ name (str): the root module name of this logging.root
42
+ Returns:
43
+ logging.logging.root: a logging.root
44
+ """
45
+ logging.root.setLevel(default_level)
46
+ logging.root.propagate = False
47
+
48
+ plain_formatter = logging.Formatter(
49
+ "[%(asctime)s] %(name)s %(levelname)s: %(message)s",
50
+ datefmt="%y/%m/%d %H:%M:%S")
51
+ # stdout logging: master only
52
+ if distributed_rank == 0:
53
+ ch = logging.StreamHandler(stream=sys.stdout)
54
+ ch.setLevel(default_level)
55
+ if color:
56
+ formatter = _ColorfulFormatter(
57
+ colored("[%(asctime)s %(name)s]: ", "green") + "%(message)s",
58
+ datefmt="%y/%m/%d %H:%M:%S",
59
+ root_name=name,
60
+ )
61
+ else:
62
+ formatter = plain_formatter
63
+ ch.setFormatter(formatter)
64
+ logging.root.addHandler(ch)
65
+
66
+ # file logging: all workers
67
+ if output is not None:
68
+ if output.endswith(".txt") or output.endswith(".log"):
69
+ filename = output
70
+ else:
71
+ filename = os.path.join(output, "log.txt")
72
+ if distributed_rank > 0:
73
+ filename = filename + f".rank{distributed_rank}"
74
+ os.makedirs(os.path.dirname(filename), exist_ok=True)
75
+
76
+ fh = logging.StreamHandler(_cached_log_stream(filename))
77
+ fh.setLevel(default_level)
78
+ fh.setFormatter(plain_formatter)
79
+ logging.root.addHandler(fh)
80
+
81
+
82
+ # cache the opened file object, so that different calls to `setup_logging.root`
83
+ # with the same file name can safely write to the same file.
84
+ @functools.lru_cache(maxsize=None)
85
+ def _cached_log_stream(filename):
86
+ return open(filename, "a")
dnnultis/log/wandb.py ADDED
@@ -0,0 +1,84 @@
1
+ import shutil
2
+ import os
3
+ import subprocess
4
+ import wandb
5
+
6
+
7
+ class WandbUrls:
8
+ def __init__(self, url):
9
+
10
+ hash = url.split("/")[-2]
11
+ project = url.split("/")[-3]
12
+ entity = url.split("/")[-4]
13
+
14
+ self.weight_url = url
15
+ self.log_url = "https://app.wandb.ai/{}/{}/runs/{}/logs".format(entity, project, hash)
16
+ self.chart_url = "https://app.wandb.ai/{}/{}/runs/{}".format(entity, project, hash)
17
+ self.overview_url = "https://app.wandb.ai/{}/{}/runs/{}/overview".format(entity, project, hash)
18
+ self.config_url = "https://app.wandb.ai/{}/{}/runs/{}/files/hydra-config.yaml".format(
19
+ entity, project, hash
20
+ )
21
+ self.overrides_url = "https://app.wandb.ai/{}/{}/runs/{}/files/overrides.yaml".format(entity, project, hash)
22
+
23
+ def __repr__(self):
24
+ msg = "=================================================== WANDB URLS ===================================================================\n"
25
+ for k, v in self.__dict__.items():
26
+ msg += "{}: {}\n".format(k.upper(), v)
27
+ msg += "=================================================================================================================================\n"
28
+ return msg
29
+
30
+
31
+ class Wandb:
32
+ IS_ACTIVE = False
33
+
34
+ @staticmethod
35
+ def set_urls_to_model(model, url):
36
+ wandb_urls = WandbUrls(url)
37
+ model.wandb = wandb_urls
38
+
39
+ @staticmethod
40
+ def _set_to_wandb_args(wandb_args, cfg, name):
41
+ var = getattr(cfg.wandb, name, None)
42
+ if var:
43
+ wandb_args[name] = var
44
+
45
+ @staticmethod
46
+ def launch(cfg, launch: bool):
47
+ if launch:
48
+
49
+ Wandb.IS_ACTIVE = True
50
+
51
+ wandb_args = {}
52
+ wandb_args["resume"] = "allow"
53
+ Wandb._set_to_wandb_args(wandb_args, cfg, "tags")
54
+ Wandb._set_to_wandb_args(wandb_args, cfg, "project")
55
+ Wandb._set_to_wandb_args(wandb_args, cfg, "name")
56
+ Wandb._set_to_wandb_args(wandb_args, cfg, "entity")
57
+ Wandb._set_to_wandb_args(wandb_args, cfg, "notes")
58
+ Wandb._set_to_wandb_args(wandb_args, cfg, "config")
59
+ Wandb._set_to_wandb_args(wandb_args, cfg, "id")
60
+
61
+ try:
62
+ commit_sha = subprocess.check_output(["git", "rev-parse", "HEAD"]).decode("ascii").strip()
63
+ gitdiff = subprocess.check_output(["git", "diff", "--", "':!notebooks'"]).decode()
64
+ except:
65
+ commit_sha = "n/a"
66
+ gitdiff = ""
67
+
68
+ config = wandb_args.get("config", {})
69
+ wandb_args["config"] = {
70
+ **config,
71
+ "run_path": os.getcwd(),
72
+ "commit": commit_sha,
73
+ "gitdiff": gitdiff
74
+ }
75
+ wandb.init(**wandb_args, sync_tensorboard=True)
76
+ wandb.save(os.path.join(os.getcwd(), cfg.cfg_path))
77
+
78
+ @staticmethod
79
+ def add_file(file_path: str):
80
+ if not Wandb.IS_ACTIVE:
81
+ raise RuntimeError("wandb is inactive, please launch first.")
82
+
83
+ filename = os.path.basename(file_path)
84
+ shutil.copyfile(file_path, os.path.join(wandb.run.dir, filename))