Denys Rozumnyi commited on
Commit
7258769
·
1 Parent(s): a0cd1aa
Files changed (4) hide show
  1. geom_solver.py +67 -63
  2. helpers.py +2 -3
  3. my_solution.py +1 -5
  4. testing.ipynb +0 -0
geom_solver.py CHANGED
@@ -1,16 +1,15 @@
1
  import numpy as np
2
  from pytorch3d.ops import ball_query
3
  from helpers import *
4
- from handcrafted_solution import *
 
5
  import hoho
6
  import itertools
7
  import torch
8
  from pytorch3d.renderer import PerspectiveCameras
9
-
10
 
11
  def my_empty_solution():
12
- '''Return a minimal valid solution, i.e. 2 vertices and 1 edge.'''
13
- # return np.zeros((1,3)), [(0, 0)]
14
  return np.zeros((18,3)), [(0, 0)]
15
 
16
 
@@ -19,54 +18,28 @@ class GeomSolver(object):
19
  def __init__(self):
20
  self.min_vertices = 18
21
  self.kmeans_th = 150
22
- self.clr_th = 2.5
23
  self.device = 'cuda:0'
24
 
25
- def process_vertices(self):
26
- human_entry = self.human_entry
27
- col_cams = [hoho.Rt_to_eye_target(human_entry['ade20k'][0], to_K(*human_entry['cameras'][1].params), quaternion_to_rotation_matrix(colmap_img.qvec), colmap_img.tvec) for colmap_img in human_entry['images'].values()]
28
- eye, target, up, fov = col_cams[0]
29
-
30
- cameras, images, points3D = human_entry['cameras'], human_entry['images'], human_entry['points3d']
31
- colmap_cameras_tf = list(human_entry['images'].keys())
32
- xyz = np.stack([p.xyz for p in points3D.values()])
33
- color = np.stack([p.rgb for p in points3D.values()])
34
-
35
- gestalt_camcet = np.stack([eye for eye, target, up, fov in itertools.starmap(hoho.Rt_to_eye_target, zip(*[human_entry[k] for k in 'ade20k K R t'.split()]))])
36
- col_camcet = np.stack([eye for eye, target, up, fov in col_cams])
37
- gestalt_to_colmap_cams = [colmap_cameras_tf[np.argmin(((gcam - col_camcet)**2).sum(1)**0.5)] for gcam in gestalt_camcet]
38
- broken_cams = np.array([np.min(((gcam - col_camcet)**2).sum(1)**0.5) for gcam in gestalt_camcet]) > 300
39
 
 
 
 
 
40
 
41
- height = cameras[1].height
42
- width = cameras[1].width
43
- N = len(gestalt_to_colmap_cams)
44
- K = to_K(*human_entry['cameras'][1].params)[None].repeat(N, 0)
45
- R = np.stack([quaternion_to_rotation_matrix(human_entry['images'][gestalt_to_colmap_cams[ind]].qvec) for ind in range(N)])
46
- T = np.stack([human_entry['images'][gestalt_to_colmap_cams[ind]].tvec for ind in range(N)])
47
-
48
- R = np.linalg.inv(R)
49
- image_size = torch.Tensor([height, width]).repeat(N, 1)
50
- pyt_cameras = PerspectiveCameras(device=self.device, R=R, T=T, in_ndc=False, focal_length=K[:, 0, :1], principal_point=K[:, :2, 2], image_size=image_size)
51
-
52
- verts = torch.from_numpy(xyz.astype(np.float32)).to(self.device)
53
-
54
- apex_color = np.array(gestalt_color_mapping['apex'])
55
- eave_end_color = np.array(gestalt_color_mapping['eave_end_point'])
56
-
57
- dist_points = np.zeros((xyz.shape[0], ))
58
- visible_counts = np.zeros((xyz.shape[0], ), dtype=int)
59
  proj_uv = []
60
- for ki in range(N):
61
- if broken_cams[ki]:
62
  proj_uv.append(([], []))
63
  continue
64
- cki = gestalt_to_colmap_cams[ki]
65
 
66
- gest = np.array(human_entry['gestalt'][ki])
67
- apex_mask = cv2.inRange(gest, apex_color-self.clr_th, apex_color+self.clr_th)
68
- eave_end_mask = cv2.inRange(gest, eave_end_color-self.clr_th, eave_end_color+self.clr_th)
69
- vert_mask = apex_mask + eave_end_mask
 
70
  vert_mask = (vert_mask > 0).astype(np.uint8)
71
 
72
  dist = cv2.distanceTransform(1-vert_mask, cv2.DIST_L2, 3)
@@ -74,11 +47,9 @@ class GeomSolver(object):
74
  ndist = np.zeros_like(dist)
75
  ndist = cv2.normalize(dist, ndist, 0, 1.0, cv2.NORM_MINMAX)
76
 
77
- in_this_image = np.array([cki in p.image_ids for p in points3D.values()])
78
- # tempind = 2103
79
- # print(in_this_image[tempind-1], cki, points3D[tempind].image_ids)
80
- uv = torch.round(pyt_cameras[ki].transform_points(verts)[:, :2]).cpu().numpy().astype(int)
81
- uv_inl = (uv[:, 0] >= 0) * (uv[:, 1] >= 0) * (uv[:, 0] < width) * (uv[:, 1] < height) * in_this_image
82
  proj_uv.append((uv, uv_inl))
83
  uv = uv[uv_inl]
84
 
@@ -88,17 +59,17 @@ class GeomSolver(object):
88
  selected_points = (dist_points / (visible_counts + 1e-6)) <= 10
89
  selected_points[visible_counts < 1] = False
90
 
91
-
92
- pnts = torch.from_numpy(xyz[selected_points].astype(np.float32))[None]
93
  bdists, inds, nn = ball_query(pnts, pnts, K=3, radius=30)
94
  dense_pnts = (bdists[0] > 0).sum(1) == 2
95
 
96
-
97
  criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 200, 0.3)
98
  flags = cv2.KMEANS_RANDOM_CENTERS
99
- centers = None
 
 
100
  for tempi in range(1, 20):
101
- retval, bestLabels, temp_centers = cv2.kmeans(xyz[selected_points][dense_pnts].astype(np.float32), tempi, None, criteria, 200,flags)
102
  cpnts = torch.from_numpy(temp_centers.astype(np.float32))[None]
103
  bdists, inds, nn = ball_query(cpnts, cpnts, K=1, radius=100)
104
  if bdists.max() > 0:
@@ -108,23 +79,56 @@ class GeomSolver(object):
108
  if closest_nn < self.kmeans_th:
109
  break
110
  centers = temp_centers
111
- if centers is None:
112
  centers = temp_centers
113
- # image_ids = np.array([p.id for p in points3D.values()])
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
114
  # pyt_centers = torch.from_numpy(centers).to(device)
115
 
116
- z_th = centers[:,-1].min() - 10
117
- self.wf_center = xyz[xyz[:,-1] > z_th].mean(0)
118
  self.wf_center[-1] = centers[:, -1].mean()
119
- self.with_broken_cams = broken_cams.any()
120
 
121
  self.vertices = centers
122
-
123
- if self.with_broken_cams:
124
- vertices = self.vertices
125
  print("There are broken cams.")
126
  else:
127
- nvert = self.vertices.shape[0]
128
  # added_one = (self.min_vertices * self.wf_center - self.vertices.sum(0)) / (self.min_vertices - nvert)
129
  added_one = self.wf_center
130
  added = added_one[None].repeat(self.min_vertices - nvert,0)
 
1
  import numpy as np
2
  from pytorch3d.ops import ball_query
3
  from helpers import *
4
+ from handcrafted_solution import convert_entry_to_human_readable
5
+ import cv2
6
  import hoho
7
  import itertools
8
  import torch
9
  from pytorch3d.renderer import PerspectiveCameras
10
+ from hoho.color_mappings import gestalt_color_mapping
11
 
12
  def my_empty_solution():
 
 
13
  return np.zeros((18,3)), [(0, 0)]
14
 
15
 
 
18
  def __init__(self):
19
  self.min_vertices = 18
20
  self.kmeans_th = 150
 
21
  self.device = 'cuda:0'
22
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
23
 
24
+ def cluster_points(self, point_types, clr_th = 2.5):
25
+ point_colors = []
26
+ for point_type in point_types:
27
+ point_colors.append(np.array(gestalt_color_mapping[point_type]))
28
 
29
+ dist_points = np.zeros((self.verts.shape[0], ))
30
+ visible_counts = np.zeros((self.verts.shape[0], ), dtype=int)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
31
  proj_uv = []
32
+ for ki in range(len(self.gestalt_to_colmap_cams)):
33
+ if self.broken_cams[ki]:
34
  proj_uv.append(([], []))
35
  continue
36
+ cki = self.gestalt_to_colmap_cams[ki]
37
 
38
+ gest = self.gests[ki]
39
+ vert_mask = 0
40
+ for point_color in point_colors:
41
+ my_mask = cv2.inRange(gest, point_color-clr_th, point_color+clr_th)
42
+ vert_mask = vert_mask + my_mask
43
  vert_mask = (vert_mask > 0).astype(np.uint8)
44
 
45
  dist = cv2.distanceTransform(1-vert_mask, cv2.DIST_L2, 3)
 
47
  ndist = np.zeros_like(dist)
48
  ndist = cv2.normalize(dist, ndist, 0, 1.0, cv2.NORM_MINMAX)
49
 
50
+ in_this_image = np.array([cki in p.image_ids for p in self.points3D.values()])
51
+ uv = torch.round(self.pyt_cameras[ki].transform_points(self.verts)[:, :2]).cpu().numpy().astype(int)
52
+ uv_inl = (uv[:, 0] >= 0) * (uv[:, 1] >= 0) * (uv[:, 0] < self.width) * (uv[:, 1] < self.height) * in_this_image
 
 
53
  proj_uv.append((uv, uv_inl))
54
  uv = uv[uv_inl]
55
 
 
59
  selected_points = (dist_points / (visible_counts + 1e-6)) <= 10
60
  selected_points[visible_counts < 1] = False
61
 
62
+ pnts = torch.from_numpy(self.xyz[selected_points].astype(np.float32))[None]
 
63
  bdists, inds, nn = ball_query(pnts, pnts, K=3, radius=30)
64
  dense_pnts = (bdists[0] > 0).sum(1) == 2
65
 
 
66
  criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 200, 0.3)
67
  flags = cv2.KMEANS_RANDOM_CENTERS
68
+ centers = np.zeros((0, 3))
69
+ if len(self.xyz[selected_points][dense_pnts]) == 0:
70
+ return centers
71
  for tempi in range(1, 20):
72
+ retval, bestLabels, temp_centers = cv2.kmeans(self.xyz[selected_points][dense_pnts].astype(np.float32), tempi, None, criteria, 200,flags)
73
  cpnts = torch.from_numpy(temp_centers.astype(np.float32))[None]
74
  bdists, inds, nn = ball_query(cpnts, cpnts, K=1, radius=100)
75
  if bdists.max() > 0:
 
79
  if closest_nn < self.kmeans_th:
80
  break
81
  centers = temp_centers
82
+ if centers.shape[0] == 0:
83
  centers = temp_centers
84
+
85
+ return centers
86
+
87
+
88
+ def process_vertices(self):
89
+ human_entry = self.human_entry
90
+ col_cams = [hoho.Rt_to_eye_target(human_entry['ade20k'][0], to_K(*human_entry['cameras'][1].params), quaternion_to_rotation_matrix(colmap_img.qvec), colmap_img.tvec) for colmap_img in human_entry['images'].values()]
91
+ eye, target, up, fov = col_cams[0]
92
+
93
+ cameras, images, self.points3D = human_entry['cameras'], human_entry['images'], human_entry['points3d']
94
+ colmap_cameras_tf = list(human_entry['images'].keys())
95
+ self.xyz = np.stack([p.xyz for p in self.points3D.values()])
96
+ color = np.stack([p.rgb for p in self.points3D.values()])
97
+ self.gests = [np.array(gest0) for gest0 in human_entry['gestalt']]
98
+
99
+ gestalt_camcet = np.stack([eye for eye, target, up, fov in itertools.starmap(hoho.Rt_to_eye_target, zip(*[human_entry[k] for k in 'ade20k K R t'.split()]))])
100
+ col_camcet = np.stack([eye for eye, target, up, fov in col_cams])
101
+ self.gestalt_to_colmap_cams = [colmap_cameras_tf[np.argmin(((gcam - col_camcet)**2).sum(1)**0.5)] for gcam in gestalt_camcet]
102
+ self.broken_cams = np.array([np.min(((gcam - col_camcet)**2).sum(1)**0.5) for gcam in gestalt_camcet]) > 300
103
+
104
+ self.height, self.width = cameras[1].height, cameras[1].width
105
+ N = len(self.gestalt_to_colmap_cams)
106
+ K = to_K(*human_entry['cameras'][1].params)[None].repeat(N, 0)
107
+ R = np.stack([quaternion_to_rotation_matrix(human_entry['images'][self.gestalt_to_colmap_cams[ind]].qvec) for ind in range(N)])
108
+ T = np.stack([human_entry['images'][self.gestalt_to_colmap_cams[ind]].tvec for ind in range(N)])
109
+
110
+ R = np.linalg.inv(R)
111
+ image_size = torch.Tensor([self.height, self.width]).repeat(N, 1)
112
+ self.pyt_cameras = PerspectiveCameras(device=self.device, R=R, T=T, in_ndc=False, focal_length=K[:, 0, :1], principal_point=K[:, :2, 2], image_size=image_size)
113
+ self.verts = torch.from_numpy(self.xyz.astype(np.float32)).to(self.device)
114
+
115
+ centers_apex = self.cluster_points(['apex'])
116
+ centers_eave = self.cluster_points(['eave_end_point'])
117
+ centers = np.concatenate((centers_apex, centers_eave))
118
+
119
+ # image_ids = np.array([p.id for p in self.points3D.values()])
120
  # pyt_centers = torch.from_numpy(centers).to(device)
121
 
122
+ z_th = centers[:,-1].min() - 50
123
+ self.wf_center = self.xyz[self.xyz[:,-1] > z_th].mean(0)
124
  self.wf_center[-1] = centers[:, -1].mean()
 
125
 
126
  self.vertices = centers
127
+ if self.broken_cams.any():
128
+ vertices = centers
 
129
  print("There are broken cams.")
130
  else:
131
+ nvert = centers.shape[0]
132
  # added_one = (self.min_vertices * self.wf_center - self.vertices.sum(0)) / (self.min_vertices - nvert)
133
  added_one = self.wf_center
134
  added = added_one[None].repeat(self.min_vertices - nvert,0)
helpers.py CHANGED
@@ -1,6 +1,8 @@
1
  import numpy as np
2
  from PIL import Image as PImage
3
  import io
 
 
4
 
5
 
6
  def to_K(f, cx, cy):
@@ -21,9 +23,6 @@ def quaternion_to_rotation_matrix(qvec):
21
  return R
22
 
23
 
24
- from scipy.spatial.distance import cdist
25
- from scipy.optimize import linear_sum_assignment
26
-
27
  def preregister_mean_std(verts_to_transform, target_verts, single_scale=True):
28
  mu_target = target_verts.mean(axis=0)
29
  mu_in = verts_to_transform.mean(axis=0)
 
1
  import numpy as np
2
  from PIL import Image as PImage
3
  import io
4
+ from scipy.spatial.distance import cdist
5
+ from scipy.optimize import linear_sum_assignment
6
 
7
 
8
  def to_K(f, cx, cy):
 
23
  return R
24
 
25
 
 
 
 
26
  def preregister_mean_std(verts_to_transform, target_verts, single_scale=True):
27
  mu_target = target_verts.mean(axis=0)
28
  mu_in = verts_to_transform.mean(axis=0)
my_solution.py CHANGED
@@ -39,6 +39,7 @@ def predict(entry, visualize=False) -> Tuple[np.ndarray, List[int]]:
39
  vertices = GeomSolver().solve(entry)
40
  edges = edges0
41
  except:
 
42
  vertices, edges = vertices0, edges0
43
 
44
  if vertices.shape[0] < vertices0.shape[0]:
@@ -46,11 +47,6 @@ def predict(entry, visualize=False) -> Tuple[np.ndarray, List[int]]:
46
  verts_new[:vertices.shape[0]] = vertices
47
  vertices = verts_new
48
 
49
- # if len(vertices) == 1:
50
- # # print("Added one more vertex")
51
- # vertices = np.concatenate((vertices, np.zeros((1,3))))
52
- # edges = [(0,0)]
53
-
54
  if (len(edges) < 1) and (len(vertices) >= 2):
55
  # print("Added only edges")
56
  edges = edges0
 
39
  vertices = GeomSolver().solve(entry)
40
  edges = edges0
41
  except:
42
+ print('ERROR')
43
  vertices, edges = vertices0, edges0
44
 
45
  if vertices.shape[0] < vertices0.shape[0]:
 
47
  verts_new[:vertices.shape[0]] = vertices
48
  vertices = verts_new
49
 
 
 
 
 
 
50
  if (len(edges) < 1) and (len(vertices) >= 2):
51
  # print("Added only edges")
52
  edges = edges0
testing.ipynb CHANGED
The diff for this file is too large to render. See raw diff