Esempio n. 1
0
    def write(self):
        """
        Writes stable pose data for meshes in the input directory to an stp file.

        path -- path to directory containing meshes to be converted to .stp
        """

        min_prob_str = sys.argv[1]
        min_prob = float(min_prob_str)
        mesh_index = 1

        mesh_files = [filename for filename in os.listdir(sys.argv[2]) if filename[-4:] == ".obj"]
        for filename in mesh_files:
            print "Writing file: " + sys.argv[2] + "/" + filename
            ob = obj_file.ObjFile(sys.argv[2] + "/" + filename)
            mesh = ob.read()
            mesh.remove_unreferenced_vertices()

            prob_mapping, cv_hull = st.compute_stable_poses(mesh), mesh.convex_hull()
            R_list = []
            for face, p in prob_mapping.items():
                if p >= min_prob:
                    vertices = [cv_hull.vertices()[i] for i in face]
                    basis = st.compute_basis(vertices, cv_hull)
                    R_list.append([p, basis])
            self.write_mesh_stable_poses(mesh, filename, min_prob)
Esempio n. 2
0
    def write_mesh_stable_poses(self, mesh, filename, min_prob=0, vis=False):
        prob_mapping, cv_hull = st.compute_stable_poses(mesh), mesh.convex_hull()

        R_list = []
        for face, p in prob_mapping.items():
            if p >= min_prob:
                x0 = np.array(cv_hull.vertices()[face[0]])
                R_list.append([p, st.compute_basis([cv_hull.vertices()[i] for i in face], cv_hull), x0])

        if vis:
            print 'P', R_list[0][0]
            mv.figure()
            mesh.visualize()
            mv.axes()

            mv.figure()
            cv_hull_tf = cv_hull.transform(stf.SimilarityTransform3D(tfx.transform(R_list[0][1], np.zeros(3))))
            cv_hull_tf.visualize()
            mv.axes()
            mv.show()

        f = open(filename[:-4] + ".stp", "w")
        f.write("#############################################################\n")
        f.write("# STP file generated by UC Berkeley Automation Sciences Lab #\n")
        f.write("#                                                           #\n")
        f.write("# Num Poses: %d" %len(R_list))
        for _ in range(46 - len(str(len(R_list)))):
            f.write(" ")
        f.write(" #\n")
        f.write("# Min Probability: %s" %str(min_prob))
        for _ in range(40 - len(str(min_prob))):
            f.write(" ")
        f.write(" #\n")
        f.write("#                                                           #\n")
        f.write("#############################################################\n")
        f.write("\n")

        # adding R matrices to .stp file
        pose_index = 1
        for i in range(len(R_list)):
            f.write("p %f\n" %R_list[i][0])
            f.write("r %f %f %f\n" %(R_list[i][1][0][0], R_list[i][1][0][1], R_list[i][1][0][2]))
            f.write("  %f %f %f\n" %(R_list[i][1][1][0], R_list[i][1][1][1], R_list[i][1][1][2]))
            f.write("  %f %f %f\n" %(R_list[i][1][2][0], R_list[i][1][2][1], R_list[i][1][2][2]))
            f.write("x0 %f %f %f\n" %(R_list[i][2][0], R_list[i][2][1], R_list[i][2][2]))
        f.write("\n\n")
def transform_meshes(path):
    """
    Transforms meshes in the directory given by path based on their highest probability stable poses.

    path -- path leading to directory containing meshes
    num_poses -- variable denoting number of desired poses per object
    """
    f = open()

    # write header
    f.write('###########################################################\n')
    f.write('# POSE TRANSFORM DATA file generated by UC Berkeley Automation Sciences Lab\n')
    f.write('#\n')
    
    min_prob = sys.argv[1]
    for filename in os.listdir(path):
        if filename[-4:] == ".obj":
            ob = obj_file.ObjFile(path + "/" + filename)
            mesh = ob.read()
            mesh.remove_unreferenced_vertices()
            prob_mapping, cv_hull = compute_stable_poses(mesh), mesh.convex_hull()

            R_list = []
            for face, p in prob_mapping.items():
                if p >= min_prob:
                    R_list.append([p, compute_basis([cv_hull.vertices()[i] for i in face])])

            # write necessary data to compute each pose (R and pose probability)
            for i in range(len(R_list)):
                f.write('# Pose ' + str(i + 1) + ':\n')
                f.write('# Probability: ' + str(R_list[i][0]) + '\n')
                for p in range(3):
                    f.write(str(R_list[i][1][p][0]) + ' ' + str(R_list[i][1][p][1]) + ' ' + str(R_list[i][1][p][2]) + '\n')
                f.write('#\n')

    f.write('###########################################################\n')
    f.write('\n')
Esempio n. 4
0
def transform_meshes(path):
    """
    Transforms meshes in the directory given by path based on their highest probability stable poses.

    path -- path leading to directory containing meshes
    num_poses -- variable denoting number of desired poses per object
    """
    f = open()

    # write header
    f.write('###########################################################\n')
    f.write('# POSE TRANSFORM DATA file generated by UC Berkeley Automation Sciences Lab\n')
    f.write('#\n')
    
    min_prob = sys.argv[1]
    for filename in os.listdir(path):
        if filename[-4:] == ".obj":
            ob = obj_file.ObjFile(path + "/" + filename)
            mesh = ob.read()
            mesh.remove_unreferenced_vertices()
            prob_mapping, cv_hull = compute_stable_poses(mesh), mesh.convex_hull()

            R_list = []
            for face, p in prob_mapping.items():
                if p >= min_prob:
                    R_list.append([p, compute_basis([cv_hull.vertices()[i] for i in face])])

            # write necessary data to compute each pose (R and pose probability)
            for i in range(len(R_list)):
                f.write('# Pose ' + str(i + 1) + ':\n')
                f.write('# Probability: ' + str(R_list[i][0]) + '\n')
                for p in range(3):
                    f.write(str(R_list[i][1][p][0]) + ' ' + str(R_list[i][1][p][1]) + ' ' + str(R_list[i][1][p][2]) + '\n')
                f.write('#\n')

    f.write('###########################################################\n')
    f.write('\n')
def compute_stable_poses(mesh):
    """
    Computes convex hull of the input mesh and returns stable final faces along with 
    corresponding probabilities.

    mesh -- a 3D Mesh object
    """
    convex_hull = mesh.convex_hull()
    cm = mesh.center_of_mass

    # mapping each edge in the convex hull to the two faces it borders
    triangles, vertices, edge_to_faces, triangle_to_vertex = convex_hull.triangles(), convex_hull.vertices(), {}, {}

    max_tri = None
    max_area = 0
    i = 0

    for triangle in triangles:
        triangle_vertices = [vertices[i] for i in triangle]
        e1, e2, e3 = Segment(triangle_vertices[0], triangle_vertices[1]), Segment(triangle_vertices[0], triangle_vertices[2]), Segment(triangle_vertices[1], triangle_vertices[2])
        for edge in [e1, e2, e3]:
            # order vertices for consistent hashing
            p_1, p_2 = tuple(edge.endpoint_1), tuple(edge.endpoint_2)
            k = (p_1, p_2)
            if p_1[0] < p_2[0]:
                k = (p_2, p_1)
            elif p_1[0] == p_2[0] and p_1[1] < p_2[1]:
                k = (p_2, p_1)
            elif p_1[0] == p_2[0] and p_1[1] == p_2[1] and p_1[2] < p_2[2]:
                k = (p_2, p_1)                
 
            if k in edge_to_faces:
                edge_to_faces[k] += [triangle]
            else:
                edge_to_faces[k] = [triangle]

        v = np.array(triangle_vertices)
        n = np.cross(v[1,:] - v[0,:],  v[2,:] - v[0,:])
        n = n / np.linalg.norm(n)
        t1 = np.array([n[1], -n[0], 0])
        t1 = t1 / np.linalg.norm(t1)
        t2 = np.cross(t1, n)
        A = np.c_[t1, t2]
        x = v.dot(A)
        x = np.c_[x, np.ones(3)]
        area = abs(np.linalg.norm(x))
        if area > max_area:
            max_area = area
            max_tri = [triangle[0], triangle[1], triangle[2]]

        p_i = compute_projected_area(triangle_vertices, cm) / (4 * math.pi)
        vt = Vertex(p_i, triangle)
        triangle_to_vertex[tuple(triangle)] = vt

        """
        print p_i
        print triangle[0], triangle[1], triangle[2]
        if abs(n.dot(np.array([0,0,1]))) > 0.95:
            mv.figure()
            convex_hull.visualize()
            mv.points3d(cm[0], cm[1], cm[2], scale_factor=0.005, color=(1,0,0))
            mv.points3d(v[:,0], v[:,1], v[:,2], scale_factor=0.005)
            mv.axes()
            mv.show()
        """

    # determining if landing on a given face implies toppling, and initializes a directed acyclic graph
    # a directed edge between two graph nodes implies that landing on one face will lead to toppling onto its successor
    # an outdegree of 0 for any graph node implies it is a sink (the object will come to rest if it topples to this face)
    for triangle in triangles:
        triangle_vertices = [vertices[i] for i in triangle]

        # computation of projection of cm onto plane of face
        v_0 = np.subtract(triangle_vertices[2], triangle_vertices[0])
        v_1 = np.subtract(triangle_vertices[1], triangle_vertices[0])
        w = np.array(triangle_vertices).T

        v_0 = v_0 / np.linalg.norm(v_0)
        v_1 = v_1 / np.linalg.norm(v_1)
        normal_vector = np.cross(v_0, v_1)
        
        origin_point = np.array(triangle_vertices[0])
        normal_vector = normal_vector / np.linalg.norm(normal_vector)

        proj_vector = np.subtract(cm, origin_point)
        dist = np.dot(normal_vector, proj_vector)
        proj_cm = np.subtract(cm, dist*normal_vector)

        # barycentric coordinates/minimum distance analysis (adapted from implementation provided at http://www.blackpawn.com/texts/pointinpoly/)
        dim = 3
        P = cvx.matrix(2 * w.T.dot(w))
        q = cvx.matrix(-2 * proj_cm.T.dot(w))
        G = cvx.matrix(-np.eye(dim))
        h = cvx.matrix(np.zeros(dim))
        A = cvx.matrix(np.ones((1, dim)))
        b = cvx.matrix(np.ones(1))
        sol = cvx.solvers.qp(P, q, G, h, A, b)

        u = np.array(sol['x'])
        norm_diff = np.sqrt(sol['primal objective'] + proj_cm.T.dot(proj_cm))
        p = w.dot(u)

        proj_cm_in_triangle = norm_diff < 1e-4
        
        """
        if triangle[0] == 807 and triangle[1] == 742 and triangle[2] == 739:
            mv.figure()
            convex_hull.visualize()
            mv.points3d(cm[0], cm[1], cm[2], scale_factor=0.005, color=(1,0,0))
            mv.points3d(proj_cm[0], proj_cm[1], proj_cm[2], scale_factor=0.005, color=(0,1,0))
            mv.points3d(w[0,:], w[1,:], w[2,:], scale_factor=0.005)
            mv.points3d(p[0], p[1], p[2], scale_factor=0.005, color=(0,0,1))
            mv.axes()
            mv.show()
            IPython.embed()
        """

        # update list of top vertices, add edges between vertices as needed
        if not proj_cm_in_triangle:
            s1, s2, s3 = Segment(triangle_vertices[0], triangle_vertices[1]), Segment(triangle_vertices[0], triangle_vertices[2]), Segment(triangle_vertices[1], triangle_vertices[2])
            closest_edges, common_endpoint = closest_segment(proj_cm, [s1, s2, s3])
            if len(closest_edges) > 1:
                index = triangle_vertices.index(common_endpoint)
                if index == len(triangle_vertices) - 1:
                    index = 0
                else:
                    index = index + 1
                closest_edge = Segment(common_endpoint, triangle_vertices[index])

            else:
                closest_edge = closest_edges[0]

            # order vertices for consistent hashing
            p_1, p_2 = tuple(closest_edge.endpoint_1), tuple(closest_edge.endpoint_2)
            k = (p_1, p_2)
            if p_1[0] < p_2[0]:
                k = (p_2, p_1)
            elif p_1[0] == p_2[0] and p_1[1] < p_2[1]:
                k = (p_2, p_1)
            elif p_1[0] == p_2[0] and p_1[1] == p_2[1] and p_1[2] < p_2[2]:
                k = (p_2, p_1)

            for face in edge_to_faces[k]:
                if list(face) != list(triangle):
                    topple_face = face
            #if triangle[0] == 807 and triangle[1] == 742 and triangle[2] == 739:
            #    IPython.embed()
            predecessor, successor = triangle_to_vertex[tuple(triangle)], triangle_to_vertex[tuple(topple_face)]
            predecessor.add_edge(successor)

    probabilities = propagate_probabilities(triangle_to_vertex.values())    

    return probabilities
Esempio n. 6
0
def main (argv):
    nodule_model = Model(FLAGS.prob, FLAGS.mode, FLAGS.fts, FLAGS.channels, FLAGS.prob_dropout, FLAGS.fts_dropout)
    with open(os.path.join('models', FLAGS.score), 'rb') as f:
        score_model = pickle.load(f)

    case = FsCase(FLAGS.input)

    case.normalizeHU()
    case = case.rescale3D(SPACING)
    lung, _ = mesh.segment_lung(case.images)
    save_mesh(lung, os.path.join(FLAGS.output, 'lung'))
    mask = mesh.convex_hull(lung)
    #body, _ = mesh.segment_body(case.images)
    #save_mesh(body, os.path.join(FLAGS.output, 'body'))
    case.standardize_color()

    case.round_stride(FLAGS.stride)

    mask = case.copy_replace_images(mask)
    mask.round_stride(FLAGS.stride)
    mask = mask.images

    views = [case.transpose(AXIAL),
             case.transpose(SAGITTAL),
             case.transpose(CORONAL)]

    if FLAGS.dilate > 0:
        ksize = FLAGS.dilate * 2 + 1
        mask = grey_dilation(mask, size=(ksize, ksize, ksize), mode='constant')
        pass
    if True:
        with tf.Session() as sess:
            tf.global_variables_initializer().run()
            nodule_model.load(sess)
            dim, nodules = nodule_model.apply(sess, views, mask)
            pass
        pass
    else:
        dim = 11
        nodules = []

    fts = []
    pos = []
    #print(nodules)
    fts.append(pyramid(dim, nodules))   # global
    pos.append(None)                    # global
    for nodule in nodules:
        fts.append(pyramid(dim, [nodule]))
        pos.append(nodule[3])
        pass
    Nt = np.array(fts, dtype=np.float32)
    Ny = score_model.predict_proba(Nt)[:,1]
    global_score = float(Ny[0])
    #print('GLOBAL SCORE:', global_score)
    pw = sorted(zip(pos, list(Ny)), key=lambda x:x[1], reverse=True)

    gal = Gallery(FLAGS.output, cols=5, header=['nodule','score','axial','sagittal','coronal'])
    anno = Annotations()
    C = 1
    for box, score in pw:
        if box is None:
            continue
        if score < 0.1:
            break
        anno.add(box, str(score))
        gal.text('%d' % C)
        gal.text('%.4f' % score)
        for v in VIEWS:
            cc, (y0, x0, y1, x1) = box_center(box, v)
            view = views[v]
            image = get3c(view.images, cc)
            cv2.rectangle(image, (x0,y0), (x1,y1), (0,255,255))
            if v == AXIAL:
                image = cv2.flip(image, 1)
            elif v == SAGITTAL:
                image = cv2.transpose(image)
                image = cv2.flip(image, 0)
            elif v == CORONAL:
                image = cv2.flip(image, -1)
            cv2.imwrite(gal.next(), image)
            pass
        C += 1
        pass
    gal.flush('plumo.html', extra={'score':global_score})
    Papaya(os.path.join(FLAGS.output, 'papaya'), case, annotations=anno)
    pass
Esempio n. 7
0
def compute_stable_poses(mesh):
    """
    Computes convex hull of the input mesh and returns stable final faces along with 
    corresponding probabilities.

    mesh -- a 3D Mesh object
    """
    convex_hull, cm = mesh.convex_hull(), mesh.vertex_mean_

    # mapping each edge in the convex hull to the two faces it borders
    triangles, vertices, edge_to_faces, triangle_to_vertex = convex_hull.triangles(), convex_hull.vertices(), {}, {}

    for triangle in triangles:
        triangle_vertices = [vertices[i] for i in triangle]
        e1, e2, e3 = Segment(triangle_vertices[0], triangle_vertices[1]), Segment(triangle_vertices[0], triangle_vertices[2]), Segment(triangle_vertices[1], triangle_vertices[2])
        for edge in [e1, e2, e3]:
            # order vertices for consistent hashing
            p_1, p_2 = tuple(edge.endpoint_1), tuple(edge.endpoint_2)
            k = (p_1, p_2)
            if p_1[0] < p_2[0]:
                k = (p_2, p_1)
            elif p_1[0] == p_2[0] and p_1[1] < p_2[1]:
                k = (p_2, p_1)
            elif p_1[0] == p_2[0] and p_1[1] == p_2[1] and p_1[2] < p_2[2]:
                k = (p_2, p_1)
                
 
            if k in edge_to_faces:
                edge_to_faces[k] += [triangle]
            else:
                edge_to_faces[k] = [triangle]
        p_i = compute_projected_area(triangle_vertices, cm) / (4 * math.pi)
        v = Vertex(p_i, triangle)
        triangle_to_vertex[tuple(triangle)] = v

    # determining if landing on a given face implies toppling, and initializes a directed acyclic graph
    # a directed edge between two graph nodes implies that landing on one face will lead to toppling onto its successor
    # an outdegree of 0 for any graph node implies it is a sink (the object will come to rest if it topples to this face)
    for triangle in triangles:
        triangle_vertices = [vertices[i] for i in triangle]

        # computation of projection of cm onto plane of face
        v_0 = np.subtract(triangle_vertices[2], triangle_vertices[0])
        v_1 = np.subtract(triangle_vertices[1], triangle_vertices[0])

        v_0 = v_0 / np.linalg.norm(v_0)
        v_1 = v_1 / np.linalg.norm(v_1)
        normal_vector = np.cross(v_0, v_1)
        
        origin_point = np.array(triangle_vertices[0])
        normal_vector = normal_vector / np.linalg.norm(normal_vector)

        proj_vector = np.subtract(cm, origin_point)
        dist = np.dot(normal_vector, proj_vector)
        proj_cm = np.subtract(cm, dist*normal_vector)

        other_dist = np.linalg.norm(cm - np.array(triangle_vertices[1]))

        # barycentric coordinates/minimum distance analysis (adapted from implementation provided at http://www.blackpawn.com/texts/pointinpoly/)
        v_2 = np.subtract(proj_cm, triangle_vertices[0])

        dot_00 = np.dot(v_0, v_0)
        dot_01 = np.dot(v_0, v_1)
        dot_02 = np.dot(v_0, v_2)
        dot_11 = np.dot(v_1, v_1)
        dot_12 = np.dot(v_1, v_2)

        inv_denom = 1.0 / (dot_00 * dot_11 - dot_01 * dot_01)
        u = (dot_11 * dot_02 - dot_01 * dot_12) * inv_denom
        v = (dot_00 * dot_12 - dot_01 * dot_02) * inv_denom

        proj_cm_in_triangle = (u >= 0) and (v >= 0) and (u + v < 1)

        # update list of top vertices, add edges between vertices as needed
        if not proj_cm_in_triangle:
            s1, s2, s3 = Segment(triangle_vertices[0], triangle_vertices[1]), Segment(triangle_vertices[0], triangle_vertices[2]), Segment(triangle_vertices[1], triangle_vertices[2])
            closest_edges, common_endpoint = closest_segment(proj_cm, [s1, s2, s3])
            if len(closest_edges) > 1:
                index = triangle_vertices.index(common_endpoint)
                if index == len(triangle_vertices) - 1:
                    index = 0
                else:
                    index = index + 1
                closest_edge = Segment(common_endpoint, triangle_vertices[index])

            else:
                closest_edge = closest_edges[0]

            # order vertices for consistent hashing
            p_1, p_2 = tuple(closest_edge.endpoint_1), tuple(closest_edge.endpoint_2)
            k = (p_1, p_2)
            if p_1[0] < p_2[0]:
                k = (p_2, p_1)
            elif p_1[0] == p_2[0] and p_1[1] < p_2[1]:
                k = (p_2, p_1)
            elif p_1[0] == p_2[0] and p_1[1] == p_2[1] and p_1[2] < p_2[2]:
                k = (p_2, p_1)

            for face in edge_to_faces[k]:
                if list(face) != list(triangle):
                    topple_face = face
            predecessor, successor = triangle_to_vertex[tuple(triangle)], triangle_to_vertex[tuple(topple_face)]
            predecessor.add_edge(successor)

    probabilities = propagate_probabilities(triangle_to_vertex.values())

    return probabilities