Exemple #1
0
def particle_to_points(dpmp, x, i):
    idx = dpmp.particleIdx[i]
    Zp = x[[idx['zPoseIdx']]]
    Zs = x[[idx['zShapeIdx']]]
    T = x[[idx['OIdx']]]
    P = dpmp.body.get_part_mesh(i, Zp, Zs)
    r_abs = x[[idx['rIdx']]]
    R, J = cv2.Rodrigues(r_abs)
    Pw = ba.object_to_world(P, R, T)
    return Pw
Exemple #2
0
def get_sample(this,
               nB_torso,
               nB_pose,
               nB_shape,
               fixedShape=True,
               add_global_rotation=True,
               init_torso_rotation=np.zeros((3))):
    """
    Returns the set of points of a model sample obtained with the specified number of basis components.
    The number of basis components can be a vector of dimension number of parts, or a single value for each part.
    Also returns the model parameters.
    @params: nB_torso, integer, the number of PCA components for the pose-dependent deformation model for the torso 
    @params: nB, integer or array, the number of PCA components for the pose-dependent deformation model for the parts 
    @params: fixedShape, boolean, if to use the mean intrinsic shape
    @params: add_global_rotation, boolean, if to sample a random rotation around the vertical axis for the torso
    @params: init_torso_rotation, 3-dim array, is the orientation of the sample
    """

    torso = this.parts['torso']
    Zp = [None] * this.nParts
    # If the number of PCA components for the pose-dependent model is not specified, we consider a fixed pose
    # (this is only used to visualize the model without deformations)
    if nB_torso is not None and nB_pose is not None:
        if np.size(nB_pose) == 1:
            nB_p = nB_pose * np.ones((this.nParts), dtype=np.int)
        else:
            nB_p = nB_pose
        nB_p[torso] = nB_torso
        fixedPose = False
    else:
        fixedPose = True

    if fixedPose:
        for b in this.partSet:
            Zp[b] = np.zeros((this.nPoseBasis[b]))
    else:
        for b in this.partSet:
            if b == this.parts['torso']:
                idx = np.arange(0, nB_p[torso])
                Zp[b] = npr.normal(np.zeros((nB_p[b])),
                                   this.posePCA[torso]['sigma'][idx])
            else:
                a = this.parent[b]
                x = Zp[a]
                cInd = np.arange(0, nB_p[a])
                rInd = np.arange(this.nPoseBasis[a],
                                 this.nPoseBasis[a] + nB_p[b])
                mu = this.poseDefModelA2B[a][b]['mu']
                C = this.poseDefModelA2B[a][b]['C']
                mu_ab, C_ab = ba.compute_conditioned_gaussian(
                    this, rInd, cInd, mu, C, x)
                Zp[b] = mu_ab
    if fixedShape:
        zs = np.zeros((this.nShapeBasis[b]))
    else:
        zs = npr.normal(this.shapePCA[torso]['M'][0:nB_shape],
                        this.shapePCA[torso]['sigma'][0:nB_shape])

    # Generate the mesh
    Pw = [None] * this.nParts
    r_abs = np.zeros((this.nParts, 3))

    t = np.zeros((this.nParts, 3))
    for part in this.partSet:

        parent = this.parent[part]
        P = ba.get_part_mesh(this, part, Zp[part], zs)
        if parent >= 0:
            R = None
            R, T, cost = ba.align_to_parent(this, part, parent, P, Pw[parent],
                                            R)
        else:
            # Add a global rotation to the torso
            b = this.parts['torso']

            if add_global_rotation:
                alpha = npr.rand(1)
                r_abs[b, 1] = -np.pi + alpha * 2.0 * np.pi
            else:
                r_abs[b, :] = 0.0

            R1, _ = cv2.Rodrigues(r_abs[b, :])
            R2, _ = cv2.Rodrigues(init_torso_rotation)
            R = np.matrix(R2) * np.matrix(R1)
            r, _ = cv2.Rodrigues(R)
            r_abs[b, :] = r[:, 0]
            T = np.zeros((3))
        Pw[part] = ba.object_to_world(P, R, T)
        r, _ = cv2.Rodrigues(R)
        r_abs[part, :] = r.flatten()
        t[part, :] = T.flatten()

    return Pw, r_abs, t, Zp, zs
def get_sample(this, nB_torso, nB_pose, nB_shape, fixedShape=True, add_global_rotation=True, init_torso_rotation=np.zeros((3))):
    """
    Returns the set of points of a model sample obtained with the specified number of basis components.
    The number of basis components can be a vector of dimension number of parts, or a single value for each part.
    Also returns the model parameters.
    @params: nB_torso, integer, the number of PCA components for the pose-dependent deformation model for the torso 
    @params: nB, integer or array, the number of PCA components for the pose-dependent deformation model for the parts 
    @params: fixedShape, boolean, if to use the mean intrinsic shape
    @params: add_global_rotation, boolean, if to sample a random rotation around the vertical axis for the torso
    @params: init_torso_rotation, 3-dim array, is the orientation of the sample
    """

    torso = this.parts['torso']
    Zp = [None] * this.nParts
    # If the number of PCA components for the pose-dependent model is not specified, we consider a fixed pose
    # (this is only used to visualize the model without deformations)
    if nB_torso is not None and nB_pose is not None:
        if np.size(nB_pose) == 1:
            nB_p = nB_pose*np.ones((this.nParts), dtype=np.int)
        else:
            nB_p = nB_pose
        nB_p[torso] = nB_torso
        fixedPose = False
    else:
        fixedPose = True

    if fixedPose:
        for b in this.partSet:
            Zp[b] = np.zeros((this.nPoseBasis[b]))
    else:
        for b in this.partSet:
            if b == this.parts['torso']:
                idx = np.arange(0, nB_p[torso])
                Zp[b] = npr.normal(np.zeros((nB_p[b])), this.posePCA[torso]['sigma'][idx])
            else:
                a = this.parent[b]
                x = Zp[a]
                cInd = np.arange(0,nB_p[a])
                rInd = np.arange(this.nPoseBasis[a],this.nPoseBasis[a]+nB_p[b])
                mu = this.poseDefModelA2B[a][b]['mu']
                C = this.poseDefModelA2B[a][b]['C']
                mu_ab, C_ab = ba.compute_conditioned_gaussian(this, rInd, cInd, mu, C, x)
                Zp[b] = mu_ab
    if fixedShape:
        zs = np.zeros((this.nShapeBasis[b]))
    else:
        zs = npr.normal(this.shapePCA[torso]['M'][0:nB_shape], this.shapePCA[torso]['sigma'][0:nB_shape])

    # Generate the mesh
    Pw  = [None]*this.nParts
    r_abs = np.zeros((this.nParts, 3))

    t = np.zeros((this.nParts, 3))
    for part in this.partSet:

        parent = this.parent[part]
        P = ba.get_part_mesh(this, part, Zp[part], zs)
        if parent >= 0:
            R = None
            R, T, cost = ba.align_to_parent(this, part, parent, P, Pw[parent], R)
        else:
            # Add a global rotation to the torso
            b = this.parts['torso']

            if add_global_rotation:
                alpha = npr.rand(1)
                r_abs[b,1] = -np.pi + alpha * 2.0*np.pi
            else:
                r_abs[b,:] = 0.0

            R1, _ = cv2.Rodrigues(r_abs[b,:])
            R2, _ = cv2.Rodrigues(init_torso_rotation)
            R = np.matrix(R2)*np.matrix(R1)
            r, _ = cv2.Rodrigues(R)
            r_abs[b,:] = r[:,0]
            T = np.zeros((3))
        Pw[part] = ba.object_to_world(P, R, T)
        r, _ = cv2.Rodrigues(R)
        r_abs[part, :] = r.flatten()
        t[part,:] = T.flatten()

    return Pw, r_abs, t, Zp, zs
Exemple #4
0
def compute_pairwise_stitch_potential(this, a, b, xSrc, xDst):
    """
    Computes the pairwise stitch cost for two connected parts
    @params a: parent part
    @params b: child part
    @params xSrc: set of Na particles of the parent
    @params xDst: set of Nb particle of the child
    Return negative cost(Na x Nb) matrix
    """

    Na = xSrc.shape[1]
    Nb = xDst.shape[1]

    # Computes the vertexes of the part a in global coordinates
    [ra, ta, za, zsa ] = particles.get_part_params(this.particleIdx[a], xSrc)

    Pa = ba.get_part_meshes(this.body, a, za, zsa)
    Ra = np.zeros((3,3,Na))
    for i in xrange(Na):
        Ra[:,:,i], J  = cv2.Rodrigues(ra[:,i])
    Paw = ba.object_to_world(Pa, Ra, ta)

    # Computes the vertexes of the part b in global coordinates
    [rb, tb, zb, zsb ] = particles.get_part_params(this.particleIdx[b], xDst)

    Pb = ba.get_part_meshes(this.body, b, zb, zsb)
    Rb = np.zeros((3,3,Nb))
    for i in xrange(Nb):
        Rb[:,:,i], J  = cv2.Rodrigues(rb[:,i])
    Pbw = ba.object_to_world(Pb, Rb, tb)

    cl = this.body.interfacePointsFromTo[b][a]
    clp = this.body.interfacePointsFromTo[a][b]
    clf = this.body.interfacePointsFlex[a][b]
    if len(Pbw.shape) == 3:
        p2 = Pbw[cl,:,:]
        p1 = Paw[clp,:,:]
        n1 = p1.shape[2]
        n2 = p2.shape[2]
        cost = np.zeros((n1,n2))

        P1 = np.dstack([p1[:,0,:]] * n2)
        P2 = np.dstack([p2[:,0,:]] * n1)
        dx = np.transpose(P1, [0, 2, 1]) - P2

        P1 = np.dstack([p1[:,1,:]] * n2)
        P2 = np.dstack([p2[:,1,:]] * n1)
        dy = np.transpose(P1, [0, 2, 1]) - P2

        P1 = np.dstack([p1[:,2,:]] * n2)
        P2 = np.dstack([p2[:,2,:]] * n1)
        dz = np.transpose(P1, [0, 2, 1]) - P2

        Ta = np.array([ta,]*n2).T
        Tb = np.array([tb,]*n1)
        dT = (Ta - Tb)**2
        St = np.sqrt(np.sum(dT, axis=1))

    else:
        p2 = Pbw[cl,:]
        p1 = Paw[clp,:]
        dx = p1[:,0] - p2[:,0]
        dy = p1[:,1] - p2[:,1]
        dz = p1[:,2] - p2[:,2]
        dT = (ta - tb)**2
        St = np.sqrt(np.sum(dT, axis=0))

    # Setting a penalty for part centers to be close penalizes interpenetration but only for parts that have similar length (arms, legs)
    S = np.array(St < 0.05, dtype=int)
    dsq = (dx**2) + (dy**2) + (dz**2)
    weights = np.ones((dsq.shape))
    N = np.sum(weights)
    weights[clf] = 0.8
    Nw = np.sum(weights)
    weights = weights * N / Nw 
    dsq = dsq * weights
    cost = np.mean(dsq, axis=0)

    # Add a penalty for a total reflection of the parts, that would have a low cost, but
    # we should penalize for inter-penetration
    
    return -this.stitchAlpha[a,b] *( cost.T + S )