def compute_dr_wrt(self, wrt): if wrt not in (self.v, self.rt, self.t): return if wrt is self.t: if not hasattr(self, '_drt') or self._drt.shape[0] != self.v.r.size: IS = np.arange(self.v.r.size) JS = IS % 3 data = np.ones(len(IS)) self._drt = sp.csc_matrix((data, (IS, JS))) return self._drt if wrt is self.rt: rot, rot_dr = cv2.Rodrigues(self.rt.r) rot_dr = rot_dr.reshape((3, 3, 3)) dr = np.einsum('abc, zc -> zba', rot_dr, self.v.r).reshape((-1, 3)) return dr if wrt is self.v: rot = cv2.Rodrigues(self.rt.r)[0] IS = np.repeat(np.arange(self.v.r.size), 3) JS = np.repeat(np.arange(self.v.r.size).reshape((-1, 3)), 3, axis=0) data = np.vstack([rot for i in range(self.v.r.size / 3)]) result = sp.csc_matrix((data.ravel(), (IS.ravel(), JS.ravel()))) return result
def draw_boundary_images(glf, glb, v, f, vpe, fpe, camera): """Assumes camera is set up correctly, and that glf has any texmapping on necessary.""" glf.Clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) glb.Clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) # Figure out which edges are on pairs of differently visible triangles from opendr.geometry import TriNormals tn = TriNormals(v, f).r.reshape((-1, 3)) campos = -cv2.Rodrigues(camera.rt.r)[0].T.dot(camera.t.r) rays_to_verts = v.reshape((-1, 3)) - row(campos) rays_to_faces = rays_to_verts[f[:, 0]] + rays_to_verts[ f[:, 1]] + rays_to_verts[f[:, 2]] dps = np.sum(rays_to_faces * tn, axis=1) dps = dps[fpe[:, 0]] * dps[fpe[:, 1]] silhouette_edges = np.asarray(np.nonzero(dps <= 0)[0], np.uint32) non_silhouette_edges = np.nonzero(dps > 0)[0] lines_e = vpe[silhouette_edges] lines_v = v visibility = draw_edge_visibility(glb, lines_v, lines_e, f, hidden_wireframe=True) shape = visibility.shape visibility = visibility.ravel() visible = np.nonzero(visibility.ravel() != 4294967295)[0] visibility[visible] = silhouette_edges[visibility[visible]] result = visibility.reshape(shape) return result
def compute_r(self): #return self.r_and_derivatives[0].squeeze() #return self.get_r_and_derivatives(self.v.r, self.rt.r, self.t.r, self.f.r, self.c.r, self.k.r)[0].squeeze() # method self.r_and_derivatives will compute derivatives as well #see http://docs.opencv.org/modules/calib3d/doc/camera_calibration_and_3d_reconstruction.html v_t = self.v.r.reshape((-1, 3)).copy() if np.any(self.rt.r != 0.): v_t = (v_t).dot(cv2.Rodrigues(self.rt.r)[0].T) if np.any(self.t.r != 0.): v_t += self.t.r x_y = v_t[:, :2] / v_t[:, [2]] uv = x_y if np.any(self.k.r != 0.): k = self.k.r # According to this link: http://docs.opencv.org/modules/calib3d/doc/camera_calibration_and_3d_reconstruction.html # k can have three lengths: (k_1, k_2, p_1, p_2[, k_3[, k_4, k_5, k_6]]) if len(k) == 4: k1, k2, p1, p2 = k elif len(k) == 5: k1, k2, p1, p2, k3 = k elif len(k) == 8: k1, k2, p1, p2, k3, k4, k5, k6 = k else: raise AttributeError( 'k has wrong length, got %d, expect 4, 5 or 8' % len(k)) x2_y2 = x_y**2. r2 = x2_y2.sum(axis=1) r4 = r2**2. xy = x_y.prod(axis=1) uv = x_y * (1 + k1 * r2 + k2 * r4 + k3 * r2 * r4)[:, np.newaxis] uv += 2 * np.vstack([p1 * xy, p2 * xy]).T uv += np.array([p2, p1]) * (r2[:, np.newaxis] + 2 * x2_y2) uv = self.f.r * uv + self.c.r return uv.squeeze()
def compute_dr_wrt(self, wrt): if wrt not in [self.v, self.rt, self.t, self.f, self.c, self.k]: return None j = self.r_and_derivatives[1] if wrt is self.rt: return j[:, :3] elif wrt is self.t: return j[:, 3:6] elif wrt is self.f: return j[:, 6:8] elif wrt is self.c: return j[:, 8:10] elif wrt is self.k: return j[:, 10:10 + self.k.size] elif wrt is self.v: rot = cv2.Rodrigues(self.rt.r)[0] data = np.asarray(j[:, 3:6].dot(rot), order='C').ravel() IS = np.repeat(np.arange(self.v.r.size * 2 / 3), 3) JS = np.asarray(np.repeat(np.arange(self.v.r.size).reshape( (-1, 3)), 2, axis=0), order='C').ravel() result = sp.csc_matrix((data, (IS, JS))) return result
def get_earthmesh(trans, rotation): from serialization import load_mesh from copy import deepcopy if not hasattr(get_earthmesh, 'm'): def wg(url): dest = join('/tmp', split(url)[1]) if not exists(dest): wget(url, dest) wg('http://files.is.tue.mpg.de/mloper/opendr/images/nasa_earth.obj') wg('http://files.is.tue.mpg.de/mloper/opendr/images/nasa_earth.mtl') wg('http://files.is.tue.mpg.de/mloper/opendr/images/nasa_earth.jpg') fname = join('/tmp', 'nasa_earth.obj') mesh = load_mesh(fname) mesh.v = np.asarray(mesh.v, order='C') mesh.vc = mesh.v * 0 + 1 mesh.v -= row(np.mean(mesh.v, axis=0)) mesh.v /= np.max(mesh.v) mesh.v *= 2.0 get_earthmesh.mesh = mesh mesh = deepcopy(get_earthmesh.mesh) mesh.v = mesh.v.dot( cv2.Rodrigues(np.asarray(np.array(rotation), np.float64))[0]) mesh.v = mesh.v + row(np.asarray(trans)) return mesh
def compute_vpe_boundary_idxs(v, f, camera, fpe): # Figure out which edges are on pairs of differently visible triangles from geometry import TriNormals tn = TriNormals(v, f).r.reshape((-1,3)) #ray = cv2.Rodrigues(camera.rt.r)[0].T[:,2] campos = -cv2.Rodrigues(camera.rt.r)[0].T.dot(camera.t.r) rays_to_verts = v.reshape((-1,3)) - row(campos) rays_to_faces = rays_to_verts[f[:,0]] + rays_to_verts[f[:,1]] + rays_to_verts[f[:,2]] faces_invisible = np.sum(rays_to_faces * tn, axis=1) dps = faces_invisible[fpe[:,0]] * faces_invisible[fpe[:,1]] silhouette_edges = np.asarray(np.nonzero(dps<=0)[0], np.uint32) return silhouette_edges, faces_invisible < 0
def compute_dr_wrt(self, wrt): if wrt is self.rt: return cv2.Rodrigues(self.rt.r)[1].T
def compute_r(self): return cv2.Rodrigues(self.rt.r)[0]
def compute_r(self): return (cv2.Rodrigues(self.rt.r)[0].dot(self.v.r.T) + col(self.t.r)).T.copy()
def view_matrix(self): R = cv2.Rodrigues(self.rt.r)[0] return np.hstack((R, col(self.t.r)))