Python torch.cross() Examples

The following are 30 code examples of torch.cross(). You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may also want to check out all available functions/classes of the module torch , or try the search function .
Example #1
Source File: quaternion.py    From RelativePose with BSD 3-Clause "New" or "Revised" License 6 votes vote down vote up
def qrot(q, v):
    """
    Rotate vector(s) v about the rotation described by quaternion(s) q.
    Expects a tensor of shape (*, 4) for q and a tensor of shape (*, 3) for v,
    where * denotes any number of dimensions.
    Returns a tensor of shape (*, 3).
    """
    assert q.shape[-1] == 4
    assert v.shape[-1] == 3
    assert q.shape[:-1] == v.shape[:-1]
    
    original_shape = list(v.shape)
    q = q.view(-1, 4)
    v = v.view(-1, 3)
    
    qvec = q[:, 1:]
    uv = torch.cross(qvec, v, dim=1)
    uuv = torch.cross(qvec, uv, dim=1)
    return (v + 2 * (q[:, :1] * uv + uuv)).view(original_shape) 
Example #2
Source File: mesh_fitter_pytorch.py    From DEODR with BSD 2-Clause "Simplified" License 5 votes vote down vote up
def qrot(q, v):
    qr = q[None, :].repeat(v.shape[0], 1)
    qvec = qr[:, :-1]
    uv = torch.cross(qvec, v, dim=1)
    uuv = torch.cross(qvec, uv, dim=1)
    return v + 2 * (qr[:, [3]] * uv + uuv) 
Example #3
Source File: so3.py    From pointnet-registration-framework with MIT License 5 votes vote down vote up
def cross_prod(x, y):
    z = torch.cross(x.view(-1, 3), y.view(-1, 3), dim=1).view_as(x)
    return z 
Example #4
Source File: utils_torch_filter.py    From ai-imu-dr with MIT License 5 votes vote down vote up
def rot_from_2_vectors(v1, v2):
        """ Returns a Rotation matrix between vectors 'v1' and 'v2'    """
        v1 = v1/torch.norm(v1)
        v2 = v2/torch.norm(v2)
        v = torch.cross(v1, v2)
        cosang = v1.matmul(v2)
        sinang = torch.norm(v)
        Rot = TORCHIEKF.Id3 + TORCHIEKF.skew(v) + \
              TORCHIEKF.skew(v).mm(TORCHIEKF.skew(v))*(1-cosang)/(sinang**2)
        return Rot 
Example #5
Source File: so3.py    From PointNetLK with MIT License 5 votes vote down vote up
def cross_prod(x, y):
    z = torch.cross(x.view(-1, 3), y.view(-1, 3), dim=1).view_as(x)
    return z 
Example #6
Source File: lie_tools.py    From cryodrgn with GNU General Public License v3.0 5 votes vote down vote up
def s2s2_to_SO3(v1, v2=None):
    '''Normalize 2 3-vectors. Project second to orthogonal component.
    Take cross product for third. Stack to form SO matrix.'''
    if v2 is None:
        assert v1.shape[-1] == 6
        v2 = v1[...,3:]
        v1 = v1[...,0:3]
    u1 = v1
    e1 = u1 / u1.norm(p=2, dim=-1, keepdim=True).clamp(min=1E-5)
    u2 = v2 - (e1 * v2).sum(-1, keepdim=True) * e1
    e2 = u2 / u2.norm(p=2, dim=-1, keepdim=True).clamp(min=1E-5)
    e3 = torch.cross(e1, e2)
    return torch.stack([e1, e2, e3], 1) 
Example #7
Source File: normals.py    From DeepDepthDenoising with MIT License 5 votes vote down vote up
def calculate_normals(points , policy = "upright"):
    if policy is "upright":
        points_temp = F.pad(points, (0, 1, 0, 0), mode="replicate")
        dx = points_temp[:, :, :, :-1] - points_temp[:, :, :, 1:]  # NCHW
        points_temp = F.pad(points, (0, 0, 0, 1), mode="replicate")
        dy = points_temp[:, :, :-1, :] - points_temp[:, :, 1:, :]  # NCHW
        normals = torch.cross(dy,dx)
        #mask = (points[:,2,:,:] == 0).float()
        #normals /= torch.sqrt(torch.sum(normals*normals, 1) + mask)        
        #return normals
        return torch.nn.functional.normalize(normals) 
Example #8
Source File: trainD.py    From DeepLiDAR with MIT License 5 votes vote down vote up
def nomal_loss(pred, targetN,params,depthI,depthJ):
    depthI = depthI.permute(0, 2, 3, 1)
    depthJ = depthJ.permute(0, 2, 3, 1)

    predN_1 = torch.zeros_like(targetN)
    predN_2 = torch.zeros_like(targetN)

    f = params[:, :, :, 0]
    cx = params[:, :, :, 1]
    cy = params[:, :, :, 2]

    z1 = depthJ - pred
    z1 = torch.squeeze(z1)
    depthJ = torch.squeeze(depthJ)
    predN_1[:, :, :, 0] = ((MatJ - cx) * z1 + depthJ) * 1.0 / f
    predN_1[:, :, :, 1] = (MatI - cy) * z1 * 1.0 / f
    predN_1[:, :, :, 2] = z1

    z2 = depthI - pred
    z2 = torch.squeeze(z2)
    depthI = torch.squeeze(depthI)
    predN_2[:, :, :, 0] = (MatJ - cx) * z2  * 1.0 / f
    predN_2[:, :, :, 1] = ((MatI - cy) * z2 + depthI) * 1.0 / f
    predN_2[:, :, :, 2] = z2

    predN = torch.cross(predN_1, predN_2)
    pred_n = F.normalize(predN)
    pred_n = pred_n.contiguous().view(-1, 3)
    target_n = targetN.contiguous().view(-1, 3)

    loss_function = nn.CosineEmbeddingLoss()
    loss = loss_function(pred_n, target_n, Variable(torch.Tensor(pred_n.size(0)).cuda().fill_(1.0)))
    return loss 
Example #9
Source File: train.py    From DeepLiDAR with MIT License 5 votes vote down vote up
def nomal_loss(pred, targetN,params,depthI,depthJ):
    depthI = depthI.permute(0, 2, 3, 1)
    depthJ = depthJ.permute(0, 2, 3, 1)

    predN_1 = torch.zeros_like(targetN)
    predN_2 = torch.zeros_like(targetN)

    f = params[:, :, :, 0]
    cx = params[:, :, :, 1]
    cy = params[:, :, :, 2]

    z1 = depthJ - pred
    z1 = torch.squeeze(z1)
    depthJ = torch.squeeze(depthJ)
    predN_1[:, :, :, 0] = ((MatJ - cx) * z1 + depthJ) * 1.0 / f
    predN_1[:, :, :, 1] = (MatI - cy) * z1 * 1.0 / f
    predN_1[:, :, :, 2] = z1

    z2 = depthI - pred
    z2 = torch.squeeze(z2)
    depthI = torch.squeeze(depthI)
    predN_2[:, :, :, 0] = (MatJ - cx) * z2  * 1.0 / f
    predN_2[:, :, :, 1] = ((MatI - cy) * z2 + depthI) * 1.0 / f
    predN_2[:, :, :, 2] = z2

    predN = torch.cross(predN_1, predN_2)
    pred_n = F.normalize(predN)
    pred_n = pred_n.contiguous().view(-1, 3)
    target_n = targetN.contiguous().view(-1, 3)

    loss_function = nn.CosineEmbeddingLoss()
    loss = loss_function(pred_n, target_n, Variable(torch.Tensor(pred_n.size(0)).cuda().fill_(1.0)))
    return loss 
Example #10
Source File: triangulated_mesh_pytorch.py    From DEODR with BSD 2-Clause "Simplified" License 5 votes vote down vote up
def compute_face_normals(self, vertices):
        triangles = vertices[self.faces_torch, :]
        u = triangles[::, 1] - triangles[::, 0]
        v = triangles[::, 2] - triangles[::, 0]
        if self.clockwise:
            n = -torch.cross(u, v)
        else:
            n = torch.cross(u, v)
        l2 = (n ** 2).sum(dim=1)
        norm = l2.sqrt()
        nn = n / norm[:, None]
        return nn 
Example #11
Source File: mesh.py    From SoftRas with MIT License 5 votes vote down vote up
def surface_normals(self):
        if self._surface_normals_update:
            v10 = self.face_vertices[:, :, 0] - self.face_vertices[:, :, 1]
            v12 = self.face_vertices[:, :, 2] - self.face_vertices[:, :, 1]
            self._surface_normals = F.normalize(torch.cross(v12, v10), p=2, dim=2, eps=1e-6)
            self._surface_normals_update = False
        return self._surface_normals 
Example #12
Source File: quaternion.py    From DSD-SATN with Apache License 2.0 5 votes vote down vote up
def qrot(q, v):
    """
    Rotate vector(s) v about the rotation described by quaternion(s) q.
    Expects a tensor of shape (*, 4) for q and a tensor of shape (*, 3) for v,
    where * denotes any number of dimensions.
    Returns a tensor of shape (*, 3).
    """
    assert q.shape[-1] == 4
    assert v.shape[-1] == 3
    assert q.shape[:-1] == v.shape[:-1]

    qvec = q[..., 1:]
    uv = torch.cross(qvec, v, dim=len(q.shape)-1)
    uuv = torch.cross(qvec, uv, dim=len(q.shape)-1)
    return (v + 2 * (q[..., :1] * uv + uuv)) 
Example #13
Source File: utils.py    From GEOMetrics with MIT License 5 votes vote down vote up
def batch_camera_info(param):
	
	theta = (np.pi*param[:,0]/180.) % 360.
	phi = (np.pi*param[:,1]/180.) % 360.

	camY = param[:,2]*torch.sin(phi)
	temp = param[:,2]*torch.cos(phi)
	
	camX = temp * torch.cos(theta)    
	camZ = temp * torch.sin(theta)    

	cam_pos = torch.cat((camX.unsqueeze(1), camY.unsqueeze(1), camZ.unsqueeze(1)), dim = 1 )    
	
	axisZ = cam_pos.clone()
	axisY = torch.FloatTensor([0,1,0]).cuda().unsqueeze(0).expand(axisZ.shape[0], 3)

	axisX = torch.cross(axisY, axisZ)
	axisY = torch.cross(axisZ, axisX)



	axisX = axisX / torch.sqrt(torch.sum(axisX**2, dim = 1)).unsqueeze(-1)
	axisY = axisY / torch.sqrt(torch.sum(axisY**2, dim = 1)).unsqueeze(-1) 
	axisZ = axisZ / torch.sqrt(torch.sum(axisZ**2, dim = 1)).unsqueeze(-1) 

	cam_mat = torch.cat((axisX.unsqueeze(1), axisY.unsqueeze(1), axisZ.unsqueeze(1)), dim = 1 )
	
	return cam_mat, cam_pos 
Example #14
Source File: util.py    From occupancy_networks with MIT License 5 votes vote down vote up
def offset_to_normal(offset, x, y, z, location):
    """get normal vector of all triangles"""
    p = offset_to_vertices(offset, x, y, z)
    # get unique triangles from all topologies
    triangles, classes = get_unique_triangles(symmetry=0)

    # get normal vector of each triangle
    # assign a dummy normal vector to the unconnected ones

    # the vertices we care on the specific face
    vertices = []
    if location<6:
        vertices = vertices_on_location()[location]

    normal = []
    if offset.is_cuda:
        dtype = torch.cuda.FloatTensor
    else:
        dtype = torch.FloatTensor
    for tri in triangles:
        # if the triangle doesn't has a line on the face we care about 
        # simply assign a dummy normal vector
        intersection = [xx for xx in vertices if xx in tri]
        #print tri, intersection
        if location < 6 and len(intersection)!=2:
            normal.append(Variable(torch.ones(3, 1).type(dtype)))
        else:
	    ### when inside/outside is considered
            a=tri[0]
            b=tri[1]
            c=tri[2]
            normal.append(torch.cross(torch.cat(p[b])-torch.cat(p[a]), torch.cat(p[c])-torch.cat(p[a])).view(3, 1))
    return torch.cat(normal).view(-1,3) 
Example #15
Source File: fast_inverse.py    From Visual-Template-Free-Form-Parsing with GNU General Public License v3.0 5 votes vote down vote up
def adjoint(A):
    """compute inverse without division by det; ...xv3xc3 input, or array of matrices assumed"""
    AI = np.empty_like(A)
    for i in xrange(3):
        AI[...,i,:] = np.cross(A[...,i-2,:], A[...,i-1,:])
    return AI 
Example #16
Source File: fast_inverse.py    From Visual-Template-Free-Form-Parsing with GNU General Public License v3.0 5 votes vote down vote up
def adjoint_torch(A):
    AI = A.clone()
    for i in xrange(3):
        AI[...,i,:] = torch.cross(A[...,i-2,:], A[...,i-1,:])
    return AI 
Example #17
Source File: quaternion.py    From video-to-pose3D with MIT License 5 votes vote down vote up
def qrot(q, v):
    """
    Rotate vector(s) v about the rotation described by 四元数quaternion(s) q.
    Expects a tensor of shape (*, 4) for q and a tensor of shape (*, 3) for v,
    where * denotes any number of dimensions.
    Returns a tensor of shape (*, 3).
    """
    assert q.shape[-1] == 4
    assert v.shape[-1] == 3
    assert q.shape[:-1] == v.shape[:-1]

    qvec = q[..., 1:]
    uv = torch.cross(qvec, v, dim=len(q.shape) - 1)
    uuv = torch.cross(qvec, uv, dim=len(q.shape) - 1)
    return (v + 2 * (q[..., :1] * uv + uuv)) 
Example #18
Source File: vertex_normals.py    From SoftRas with MIT License 5 votes vote down vote up
def vertex_normals(vertices, faces):
    """
    :param vertices: [batch size, number of vertices, 3]
    :param faces: [batch size, number of faces, 3]
    :return: [batch size, number of vertices, 3]
    """
    assert (vertices.ndimension() == 3)
    assert (faces.ndimension() == 3)
    assert (vertices.shape[0] == faces.shape[0])
    assert (vertices.shape[2] == 3)
    assert (faces.shape[2] == 3)

    bs, nv = vertices.shape[:2]
    bs, nf = faces.shape[:2]
    device = vertices.device
    normals = torch.zeros(bs * nv, 3).to(device)

    faces = faces + (torch.arange(bs, dtype=torch.int32).to(device) * nv)[:, None, None] # expanded faces
    vertices_faces = vertices.reshape((bs * nv, 3))[faces.long()]

    faces = faces.view(-1, 3)
    vertices_faces = vertices_faces.view(-1, 3, 3)

    normals.index_add_(0, faces[:, 1].long(), 
                       torch.cross(vertices_faces[:, 2] - vertices_faces[:, 1], vertices_faces[:, 0] - vertices_faces[:, 1]))
    normals.index_add_(0, faces[:, 2].long(), 
                       torch.cross(vertices_faces[:, 0] - vertices_faces[:, 2], vertices_faces[:, 1] - vertices_faces[:, 2]))
    normals.index_add_(0, faces[:, 0].long(),
                       torch.cross(vertices_faces[:, 1] - vertices_faces[:, 0], vertices_faces[:, 2] - vertices_faces[:, 0]))

    normals = F.normalize(normals, eps=1e-6, dim=1)
    normals = normals.reshape((bs, nv, 3))
    # pytorch only supports long and byte tensors for indexing
    return normals 
Example #19
Source File: dimenet.py    From pytorch_geometric with MIT License 5 votes vote down vote up
def forward(self, z, pos, batch=None):
        """"""
        edge_index = radius_graph(pos, r=self.cutoff, batch=batch)

        i, j, idx_i, idx_j, idx_k, idx_kj, idx_ji = self.triplets(
            edge_index, num_nodes=z.size(0))

        # Calculate distances.
        dist = (pos[i] - pos[j]).pow(2).sum(dim=-1).sqrt()

        # Calculate angles.
        pos_i = pos[idx_i]
        pos_ji, pos_ki = pos[idx_j] - pos_i, pos[idx_k] - pos_i
        a = (pos_ji * pos_ki).sum(dim=-1)
        b = torch.cross(pos_ji, pos_ki).norm(dim=-1)
        angle = torch.atan2(b, a)

        rbf = self.rbf(dist)
        sbf = self.sbf(dist, angle, idx_kj)

        # Embedding block.
        x = self.emb(z, rbf, i, j)
        P = self.output_blocks[0](x, rbf, i, num_nodes=pos.size(0))

        # Interaction blocks.
        for interaction_block, output_block in zip(self.interaction_blocks,
                                                   self.output_blocks[1:]):
            x = interaction_block(x, rbf, sbf, idx_kj, idx_ji)
            P += output_block(x, rbf, i)

        return P.sum(dim=0) if batch is None else scatter(P, batch, dim=0) 
Example #20
Source File: quaternion.py    From SemGCN with Apache License 2.0 5 votes vote down vote up
def qrot(q, v):
    """
    Rotate vector(s) v about the rotation described by quaternion(s) q.
    Expects a tensor of shape (*, 4) for q and a tensor of shape (*, 3) for v,
    where * denotes any number of dimensions.
    Returns a tensor of shape (*, 3).
    """
    assert q.shape[-1] == 4
    assert v.shape[-1] == 3
    assert q.shape[:-1] == v.shape[:-1]

    qvec = q[..., 1:]
    uv = torch.cross(qvec, v, dim=len(q.shape) - 1)
    uuv = torch.cross(qvec, uv, dim=len(q.shape) - 1)
    return v + 2 * (q[..., :1] * uv + uuv) 
Example #21
Source File: ppf_conv.py    From pytorch_geometric with MIT License 5 votes vote down vote up
def get_angle(v1: Tensor, v2: Tensor) -> Tensor:
    return torch.atan2(
        torch.cross(v1, v2, dim=1).norm(p=2, dim=1), (v1 * v2).sum(dim=1)) 
Example #22
Source File: operations.py    From USIP with GNU General Public License v3.0 5 votes vote down vote up
def get_angles(a, b):
    '''
    calculate the angle between vector a and b
    :param a: Bx3xMxK tensor
    :param b: Bx3xMxK tensor
    :return: Bx1xMxK tensor
    '''
    axb = torch.cross(a, b, dim=1)  # Bx3xMxK
    a_1x3 = a.permute(0, 2, 3, 1).contiguous().unsqueeze(3)  # BxMxKx3 -> BxMxKx1x3
    b_3x1 = b.permute(0, 2, 3, 1).contiguous().unsqueeze(4)  # BxMxKx3 -> BxMxKx3x1
    ab = torch.matmul(a_1x3, b_3x1).squeeze(3).squeeze(3)  # BxMxKx1x1

    angle = torch.atan2(torch.norm(axb, dim=1, keepdim=False), ab).unsqueeze(1)
    return angle 
Example #23
Source File: util.py    From photometric-mesh-optim with MIT License 5 votes vote down vote up
def get_normal_map(opt,index,vertices,faces):
	face_vertices = vertices[faces.long()]
	v1,v2,v3 = torch.unbind(face_vertices,dim=1)
	normal = F.normalize(torch.cross(v2-v1,v3-v2),dim=1)
	# face normals towards camera
	normal[normal[:,2]<0] *= -1
	normal_color = (normal+1)/2
	normal_color = torch.cat([torch.zeros(1,3,device=opt.device),normal_color],dim=0)
	normal_color[0] = 0
	normal_map = normal_color[index.long()+1].permute(2,0,1)
	return normal_map 
Example #24
Source File: geometry.py    From scene-representation-networks with MIT License 5 votes vote down vote up
def compute_normal_map(x_img, y_img, z, intrinsics):
    cam_coords = lift(x_img, y_img, z, intrinsics)
    cam_coords = util.lin2img(cam_coords)

    shift_left = cam_coords[:, :, 2:, :]
    shift_right = cam_coords[:, :, :-2, :]

    shift_up = cam_coords[:, :, :, 2:]
    shift_down = cam_coords[:, :, :, :-2]

    diff_hor = F.normalize(shift_right - shift_left, dim=1)[:, :, :, 1:-1]
    diff_ver = F.normalize(shift_up - shift_down, dim=1)[:, :, 1:-1, :]

    cross = torch.cross(diff_hor, diff_ver, dim=1)
    return cross 
Example #25
Source File: renderfunc_cluster.py    From DIB-R with MIT License 4 votes vote down vote up
def p2f(points_bxpx3, faces_fx3, cameras):
    # perspective, use just one camera
    camera_rot_bx3x3, camera_pos_bx3, camera_proj_3x1 = cameras
    cameratrans_rot_bx3x3 = camera_rot_bx3x3.permute(0, 2, 1)
    
    # follow pixel2mesh!!!
    # new_p = cam_mat * (old_p - cam_pos)
    points_bxpx3 = points_bxpx3 - camera_pos_bx3.view(-1, 1, 3)
    points_bxpx3 = torch.matmul(points_bxpx3, cameratrans_rot_bx3x3)
    
    camera_proj_bx1x3 = camera_proj_3x1.view(-1, 1, 3)
    xy_bxpx3 = points_bxpx3 * camera_proj_bx1x3
    xy_bxpx2 = xy_bxpx3[:, :, :2] / xy_bxpx3[:, :, 2:3]

    ##########################################################
    # 1 points
    pf0_bxfx3 = points_bxpx3[:, faces_fx3[:, 0], :]
    pf1_bxfx3 = points_bxpx3[:, faces_fx3[:, 1], :]
    pf2_bxfx3 = points_bxpx3[:, faces_fx3[:, 2], :]
    points3d_bxfx9 = torch.cat((pf0_bxfx3, pf1_bxfx3, pf2_bxfx3), dim=2)
    
    xy_f0 = xy_bxpx2[:, faces_fx3[:, 0], :]
    xy_f1 = xy_bxpx2[:, faces_fx3[:, 1], :]
    xy_f2 = xy_bxpx2[:, faces_fx3[:, 2], :]
    points2d_bxfx6 = torch.cat((xy_f0, xy_f1, xy_f2), dim=2)
    
    ######################################################
    # 2 normals
    v01_bxfx3 = pf1_bxfx3 - pf0_bxfx3
    v02_bxfx3 = pf2_bxfx3 - pf0_bxfx3
    
    # bs cannot be 3, if it is 3, we must specify dim
    normal_bxfx3 = torch.cross(v01_bxfx3, v02_bxfx3, dim=2)
    normalz_bxfx1 = normal_bxfx3[:, :, 2:3]
    # normalz_bxfx1 = torch.abs(normalz_bxfx1)
    
    normallen_bxfx1 = torch.sqrt(torch.sum(normal_bxfx3 ** 2, dim=2, keepdim=True))
    normal1_bxfx3 = normal_bxfx3 / (normallen_bxfx1 + 1e-15)
    
    return points3d_bxfx9, points2d_bxfx6, normalz_bxfx1, normal1_bxfx3


################################################################### 
Example #26
Source File: look_at.py    From SoftRas with MIT License 4 votes vote down vote up
def look_at(vertices, eye, at=[0, 0, 0], up=[0, 1, 0]):
    """
    "Look at" transformation of vertices.
    """
    if (vertices.ndimension() != 3):
        raise ValueError('vertices Tensor should have 3 dimensions')

    device = vertices.device

    # if list or tuple convert to numpy array
    if isinstance(at, list) or isinstance(at, tuple):
        at = torch.tensor(at, dtype=torch.float32, device=device)
    # if numpy array convert to tensor
    elif isinstance(at, np.ndarray):
        at = torch.from_numpy(at).to(device)
    elif torch.is_tensor(at):
        at.to(device)

    if isinstance(up, list) or isinstance(up, tuple):
        up = torch.tensor(up, dtype=torch.float32, device=device)
    elif isinstance(up, np.ndarray):
        up = torch.from_numpy(up).to(device)
    elif torch.is_tensor(up):
        up.to(device)

    if isinstance(eye, list) or isinstance(eye, tuple):
        eye = torch.tensor(eye, dtype=torch.float32, device=device)
    elif isinstance(eye, np.ndarray):
        eye = torch.from_numpy(eye).to(device)
    elif torch.is_tensor(eye):
        eye = eye.to(device)

    batch_size = vertices.shape[0]
    if eye.ndimension() == 1:
        eye = eye[None, :].repeat(batch_size, 1)
    if at.ndimension() == 1:
        at = at[None, :].repeat(batch_size, 1)
    if up.ndimension() == 1:
        up = up[None, :].repeat(batch_size, 1)

    # create new axes
    # eps is chosen as 1e-5 to match the chainer version
    z_axis = F.normalize(at - eye, eps=1e-5)
    x_axis = F.normalize(torch.cross(up, z_axis), eps=1e-5)
    y_axis = F.normalize(torch.cross(z_axis, x_axis), eps=1e-5)

    # create rotation matrix: [bs, 3, 3]
    r = torch.cat((x_axis[:, None, :], y_axis[:, None, :], z_axis[:, None, :]), dim=1)

    # apply
    # [bs, nv, 3] -> [bs, nv, 3] -> [bs, nv, 3]
    if vertices.shape != eye.shape:
        eye = eye[:, None, :]
    vertices = vertices - eye
    vertices = torch.matmul(vertices, r.transpose(1,2))

    return vertices 
Example #27
Source File: projection.py    From Pointnet2.ScanNet with MIT License 4 votes vote down vote up
def compute_frustum_normals(self, corner_coords):
        """
        Computes the normal vectors (pointing inwards) to the 6 planes that bound the viewing frustum

        :param corner_coords: torch tensor of shape (8, 4), coordinates of the corner points of the viewing frustum
        :return: normals: torch tensor of shape (6, 3)
        """

        normals = corner_coords.new(6, 3)

        # compute plane normals
        # front plane
        plane_vec1 = corner_coords[3][:3] - corner_coords[0][:3]
        plane_vec2 = corner_coords[1][:3] - corner_coords[0][:3]
        normals[0] = torch.cross(plane_vec1.view(-1), plane_vec2.view(-1))

        # right side plane
        plane_vec1 = corner_coords[2][:3] - corner_coords[1][:3]
        plane_vec2 = corner_coords[5][:3] - corner_coords[1][:3]
        normals[1] = torch.cross(plane_vec1.view(-1), plane_vec2.view(-1))

        # roof plane
        plane_vec1 = corner_coords[3][:3] - corner_coords[2][:3]
        plane_vec2 = corner_coords[6][:3] - corner_coords[2][:3]
        normals[2] = torch.cross(plane_vec1.view(-1), plane_vec2.view(-1))

        # left side plane
        plane_vec1 = corner_coords[0][:3] - corner_coords[3][:3]
        plane_vec2 = corner_coords[7][:3] - corner_coords[3][:3]
        normals[3] = torch.cross(plane_vec1.view(-1), plane_vec2.view(-1))

        # bottom plane
        plane_vec1 = corner_coords[1][:3] - corner_coords[0][:3]
        plane_vec2 = corner_coords[4][:3] - corner_coords[0][:3]
        normals[4] = torch.cross(plane_vec1.view(-1), plane_vec2.view(-1))

        # back plane
        plane_vec1 = corner_coords[6][:3] - corner_coords[5][:3]
        plane_vec2 = corner_coords[4][:3] - corner_coords[5][:3]
        normals[5] = torch.cross(plane_vec1.view(-1), plane_vec2.view(-1))

        return normals 
Example #28
Source File: box_3d.py    From Stereo-RCNN with MIT License 4 votes vote down vote up
def __init__(self, poses):
        super(Box3d, self).__init__()
        self.T_c_o = poses[0:3]
        self.size = poses[3:6]
        self.R_c_o = torch.FloatTensor([[ m.cos(poses[6]), 0 ,m.sin(poses[6])],
                                        [ 0,         1 ,     0],
                                        [-m.sin(poses[6]), 0 ,m.cos(poses[6])]]).type_as(self.T_c_o)

        self.P_o = poses.new(8,3).zero_()
        self.P_o[0,0],self.P_o[0,1], self.P_o[0,2] = -self.size[0]/2, 0, -self.size[2]/2.0
        self.P_o[1,0],self.P_o[1,1], self.P_o[1,2] = -self.size[0]/2, 0, self.size[2]/2.0
        self.P_o[2,0],self.P_o[2,1], self.P_o[2,2] = self.size[0]/2, 0, self.size[2]/2.0         #max
        self.P_o[3,0],self.P_o[3,1], self.P_o[3,2] = self.size[0]/2, 0, -self.size[2]/2.0

        self.P_o[4,0],self.P_o[4,1], self.P_o[4,2] = -self.size[0]/2, -self.size[1], -self.size[2]/2.0 # min
        self.P_o[5,0],self.P_o[5,1], self.P_o[5,2] = -self.size[0]/2, -self.size[1], self.size[2]/2.0
        self.P_o[6,0],self.P_o[6,1], self.P_o[6,2] = self.size[0]/2, -self.size[1], self.size[2]/2.0
        self.P_o[7,0],self.P_o[7,1], self.P_o[7,2] = self.size[0]/2, -self.size[1], -self.size[2]/2.0

        P_c = poses.new(8,3).zero_()
        for i in range(8):
            P_c[i] = torch.mm(self.R_c_o, self.P_o[i].unsqueeze(1)).squeeze(1) + self.T_c_o

        def creatPlane(p1, p2, p3):
            arrow1 = p2 - p1
            arrow2 = p3 - p1
            normal = torch.cross(arrow1, arrow2)
            plane = p1.new((4)).zero_()
            plane[0] = normal[0]
            plane[1] = normal[1]
            plane[2] = normal[2]
            plane[3] = -normal[0] * p1[0] - normal[1] * p1[1] - normal[2] * p1[2]
            return plane

        self.planes_c = poses.new(6,4).zero_()
        self.planes_c[0] = creatPlane(P_c[0], P_c[3], P_c[4])  #front 0 
        self.planes_c[1] = creatPlane(P_c[2], P_c[3], P_c[6])  #right 1
        self.planes_c[2] = creatPlane(P_c[1], P_c[2], P_c[5])  #back 2
        self.planes_c[3] = creatPlane(P_c[0], P_c[1], P_c[4])  #left 3
        self.planes_c[4] = creatPlane(P_c[0], P_c[1], P_c[2])  #botom 4
        self.planes_c[5] = creatPlane(P_c[4], P_c[5], P_c[6])  #top 5

        # compute the nearest vertex
        self.nearest_dist = 100000000
        for i in range(P_c.size()[0]):
            if torch.norm(P_c[i]) < self.nearest_dist:
                self.nearest_dist = torch.norm(P_c[i])
                self.nearest_vertex = i  # find the nearest vertex with camera canter 
Example #29
Source File: utils.py    From GEOMetrics with MIT License 4 votes vote down vote up
def calc_point_to_line(p, triangles, point_options): 
	a, b, c = triangles
	counter_p = torch.zeros(p.shape).cuda()
	
	EdgeAb = edge( a, b )
	EdgeBc = edge( b, c )
	EdgeCa = edge( c, a )

	uab = EdgeAb.Project( p )
	uca = EdgeCa.Project( p )
	ubc = EdgeBc.Project( p )

	TriNorm = torch.cross(a - b, a - c)
	TriPlane = Plane(EdgeAb.A, TriNorm);

	# type 1 
	cond = (point_options == 1)
	counter_p[cond] = EdgeAb.A[cond]

	# type 2 
	cond = (point_options == 2)
	counter_p[cond] = EdgeBc.A[cond]

	# type 3 
	cond = (point_options == 3)
	counter_p[cond] = EdgeCa.A[cond]

	# type 4 
	cond = (point_options == 4)
	counter_p[cond] = EdgeAb.PointAt( uab )[cond]

	# type 5
	cond = (point_options == 5)
	counter_p[cond] = EdgeBc.PointAt( ubc )[cond]

	# type 6
	cond = (point_options == 6)
	counter_p[cond] = EdgeCa.PointAt( uca )[cond]

	# type 0
	cond = (point_options == 0)
	counter_p[cond] = TriPlane.Project( p )[cond]
	
	distances = torch.mean(torch.sum((counter_p - p)**2, dim = -1))
	return distances 
Example #30
Source File: utils.py    From GEOMetrics with MIT License 4 votes vote down vote up
def calc_curve( verts, info, angle = 70): 
	eps = .00001

	# extract vertex coordinated for each vertex in face 
	faces = torch.LongTensor(info['faces']).cuda()
	face_list = torch.LongTensor(info['face_list']).cuda()
	p1 = torch.index_select(verts, 0,faces[:,1])
	p2 = torch.index_select(verts, 0,faces[:,0])
	p3 = torch.index_select(verts, 0,faces[:,2])
 
 	# cauculate normals of each face 
	e1 = p2-p1
	e2 = p3-p1
	face_normals = torch.cross(e1, e2)
	qn = torch.norm(face_normals, p=2, dim=1).detach().view(-1,1)
	face_normals = face_normals.div(qn.expand_as(face_normals))
	main_face_normals = torch.index_select(face_normals, 0, face_list[:,0,2])

	# cauculate the curvature with the 3 nighbor faces 
	#1
	face_1_normals = torch.index_select(face_normals, 0, face_list[:,0,0])
	curvature_proxi_rad = torch.sum(main_face_normals*face_1_normals, dim = 1).clamp(-1.0 + eps, 1.0 - eps).acos()
	curvature_proxi_1 = (curvature_proxi_rad).view(-1,1)
	#2
	face_2_normals = torch.index_select(face_normals, 0, face_list[:,1,0])
	curvature_proxi_rad = torch.sum(main_face_normals*face_2_normals, dim = 1).clamp(-1.0 + eps, 1.0 - eps).acos()
	curvature_proxi_2 = (curvature_proxi_rad).view(-1,1)
	#3
	face_3_normals = torch.index_select(face_normals, 0, face_list[:,2,0])
	curvature_proxi_rad = torch.sum(main_face_normals*face_3_normals, dim = 1).clamp(-1.0 + eps, 1.0 - eps).acos()
	curvature_proxi_3 = (curvature_proxi_rad).view(-1,1)
	
	# get average over neighbors 
	curvature_proxi_full = torch.cat( (curvature_proxi_1, curvature_proxi_2, curvature_proxi_3), dim = 1)
	curvature_proxi = torch.mean(curvature_proxi_full, dim = 1)

	#select faces with high curvature and return their index
	splitting_faces  = np.where(curvature_proxi*180/np.pi  > angle )[0]
	if splitting_faces.shape[0] <3:
		splitting_faces  = curvature_proxi.topk(3, sorted = False)[1] 
	else:
		splitting_faces  = torch.LongTensor(splitting_faces).cuda()
	return splitting_faces


# this function take the faces feature vectors defined on the graph and splits indicated faces by:
	# adding a new vertex to the center of the face, with features equal to the averge of the 3 verts around it 
	# deleteing the previous face, ie removing from face list 
	# adding 3 new faces by connecting old verts to the new vert 
# second grossest function in this file