Skip to content
My-Tien Nguyen edited this page Feb 23, 2022 · 30 revisions

Although Knossos can still load and export *.nml files, the recommended way is to use the new annotation files.

The annotation files *.k.zip are zip archives that can currently contain 4 things:

  • A file annotation.xml which is formerly known as *.nml containing general information about the whole annotation and optionally a skeleton (for an easy start the contents are currently the same as you’d get when exporting as *.nml, but the vision is to split the skeleton from skeleton independent information in the future)
  • several *.seg.sz files containing segmentation overlay cubes which are loaded at higher priority than files from disk and saved when cubes got edited
    the filenames consist of: the experiment name, '_', the magnification, 'x' 'y' and 'z' with their respective cubes coordinates
    e.g. 2012-03-07_AreaX14_mag1 _ mag1 x41 y40 z22 .seg.sz
    You can generate these by dumping the in-memory representation of a snappy-compressed cube into a file using a snappy library binding or a tool like snzip using the raw format.
  • A file mergelist.txt containing information about objects which span multiple overlay ids with the format specified below
  • Several *.ply files containing vertices, colors and indices to define a triangle mesh. The filename usually consists only of the tree id to which the mesh belongs. Otherwise the mesh will be associated to a newly created tree. Details about the format are specified below.

Merge list

The merge list is used to group supervoxels (groups of voxels with the same unique ID) into objects and assign information to them. It’s just a text file where each object occupies 4 lines.

Object = Object_ID, ToDo_flag, Immutability_flag, Supervoxel_IDs, '\n', Position, [' ', Color], '\n', Class, '\n', Comment, '\n';

Object_ID = uint64, ' ';
ToDo_flag = Immutability_flag = (0|1), ' ';
Supervoxel_IDs = uint64, {' ', uint64};
Position = int32, ' ', int32, ' ', int32;
Color = uint8, ' ', uint8, ' ', uint8;
Class = Comment = −'\n';

Object_ID is a unique identifier for the group of Supervoxel_IDs.
ToDo_flag represents objects marked to be evaluated by the annotator.
The Immutability_flag is used to represent if an object should persist in the list after it was merged by proofreaders (i. e. for later unmerging, usually all initial objects given to proofreaders are marked as immutable).
Position are space-separated x, y and z voxel coordinates assigned to an object.
Color is an optional space separated tuple of the red, green and blue components of a custom color.
Class and Comment each occupy a line on their own – without any escape characters.

Example:

3150 1 1 5352 3297 3971 4104 2654 4153 4046 2257 3624 3150 4100
5333 5267 2880
mito
whatever one may want to add here
3151 1 0 2257 2654 2663 3018 3023 3029 3150 3294 3297 3298 3363
1024 2048 4096 16 25 222
neuron
proofread merge

Triangle Mesh (.ply)

A triangle mesh is a collection of vertices, colors and indices. The filename usually consists only of the tree id to which the mesh belongs. Otherwise it will be associated to a newly created tree. We use the ply file format for loading and saving meshes. We chose this format because it is very simple and extensible at the same time, it can be stored as text as well as binary, it supports per vertex colors and python and C++ libraries are available to create and read ply files. At the moment KNOSSOS can load ply files with following header:

ply
format [ascii|binary_little_endian|binary_big_endian] 1.0
element vertex #vertices
property float x
property float y
property float z
property uint8 red
property uint8 green
property uint8 blue
property uint8 alpha
element face #faces
property list uint8 uint vertex_indices
end_header

In the ply format an element is declared as a name, the number of instances and its properties. Above we have e.g. #vertices vertex elements with properties x, y, z, red, green, blue, alpha. So after the header #vertices lines should follow, each one with space-separated values for those properties. After them come #faces lines of face elements respectively.

Note that a face is a property list. So each line starts with the length of the list (for a triangle mesh 3) followed by the list itself: space-separated vertex indices.

The vertex color properties are optional. If no colors are specified, the mesh will have the same color as its skeleton tree.

In the example below we declare a minimal mesh with 3 vertices and 1 face. The vertices are red and at positions (0, 0, 0), (100, 0, 0) and (50, 50, 0). The last line describes the face by saying that it consists of 3 vertices with indices 0, 1 and 2.

ply
format ascii 1.0
element vertex 3
property float x
property float y
property float z
property uint8 red
property uint8 green
property uint8 blue
property uint8 alpha
element face 1
property list uint8 uint vertex_indices
end_header
0 0 0 255 0 0 255
100 0 0 255 0 0 255
50 50 0 255 0 0 255
3 0 1 2

This Python code fragment allows you to write valid KNOSSOS ply files from a flat list of indices (3 consecutive integers defining a triangle) and a flat list of vertices (of format [x1,y1,z1,x2,y2,z2,....]).

def make_ply_string(indices, vertices, rgba_color):
    """
    Creates a ply str that can be included into a .k.zip for rendering in KNOSSOS.
    :param indices: iterable of indices (int)
    :param vertices: iterable of vertices (int)
    :param rgba_color: 4-tuple (uint8)
    :return:
    """

    # create header
    ply_str = 'ply\nformat ascii 1.0\nelement vertex {0}\nproperty float x\nproperty float y\nproperty float z\n'\
              'property uint8 red\nproperty uint8 green\nproperty uint8 blue\nproperty uint8 alpha\n'\
              'element face {1}\nproperty list uint8 uint vertex_indices\nend_header\n'.format(len(vertices) / 3, len(indices) / 3)

    for v in zip(vertices[0::3], vertices[1::3], vertices[2::3]):
        ply_str += '{0} {1} {2} {3} {4} {5} {6}\n'.format(v[0], v[1], v[2],
                                                          rgba_color[0],
                                                          rgba_color[1],
                                                          rgba_color[2],
                                                          rgba_color[3])

    for face in zip(indices[0::3], indices[1::3], indices[2::3]):
        ply_str += '3 {0} {1} {2}\n'.format(face[0], face[1], face[2])

    return ply_str
Clone this wiki locally