zudi-lin / pytorch_connectomics

PyTorch Connectomics: segmentation toolbox for EM connectomics
http://connectomics.readthedocs.io/
MIT License
169 stars 77 forks source link

how to create a precomputed point annotation #130

Closed liuyx599 closed 1 year ago

liuyx599 commented 1 year ago

You have done a great tutorial on neuroglancerhttps://connectomics.readthedocs.io/en/latest/external/neuroglancer.html, which is particularly friendly for beginners who do not understand the front-end and back-end. Do you have a more detailed tutorial? In the eighth step of your tutorial, Visualize Point Annotations, you render each point on the page in real-time by reading a txt file. If I want to create a precomputed point annotation, how can I achieve it

donglaiw commented 1 year ago

Glad that you found the tutorial useful! We'll add the skeleton tutorial soon. Here is the function to use: createSkeleton

import os, struct
def createSkeleton(coordinates, volume_size, resolution, output_folder='skeletons/'):
    """
    Parameters
    -------
    coordinates: Nx3 numpy array or a list of tuples (x,y,z)  
    volume_size: dimension of the layer (xyz order)
    resolution: list or tuple or numpy array
        unit is meter. e.g., [8e-9,8e-9,3e-8] for 8x8x30nm volume   
    """
    # write info file
    writeSkeletonInfo(volume_size, resolution, output_folder)

    # write the binary file of points
    pts_folder = os.path.join(output_folder, 'spatial0')
    if not os.path.exists(pts_folder):
        os.mkdir(pts_folder)

    with open(os.path.join(pts_folder, '0_0_0'), 'wb') as outfile:
        total_count=len(coordinates) # coordinates is a list of tuples (x,y,z) 
        buf = struct.pack('<Q',total_count)
        for (x,y,z) in coordinates:
            pt_buf = struct.pack('<3f',x,y,z)
            buf += pt_buf
         # write the ids at the end of the buffer as increasing integers 
        id_buf = struct.pack('<%sQ' % len(coordinates), *range(len(coordinates)))
        buf += id_buf
        outfile.write(buf)

def writeSkeletonInfo(volume_size, resolution, output_folder='skeletons/'):
    out = """{
       "@type" : "neuroglancer_annotations_v1",
       "annotation_type" : "POINT",
       "by_id" : {
          "key" : "by_id"
       },
       "dimensions" : {
          "x" : [ %.e, "m" ],
          "y" : [ %.e, "m" ],
          "z" : [ %.e, "m" ]
       },
       "lower_bound" : [ 0, 0, 0 ],
       "properties" : [],
       "relationships" : [],
       "spatial" : [
          {
             "chunk_size" : [ %d, %d, %d ],
             "grid_shape" : [ 1, 1, 1 ],
             "key" : "spatial0",
             "limit" : 1
          }
       ],
       "upper_bound" : [ %d, %d, %d]
    }"""%(resolution[0],resolution[1],resolution[2],volume_size[0],volume_size[1],volume_size[2],volume_size[0],volume_size[1],volume_size[2])
    if not os.path.exists(output_folder):
        os.mkdir(output_folder)
    a = open(os.path.join(output_folder, 'info'), 'w')
    a.write(out)
    a.close()