Skip to content

Downloading annotation layer with Python library, but downloaded annotation is not the same size as the actual image layer? #909

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
azatian opened this issue Jun 4, 2023 · 4 comments
Labels

Comments

@azatian
Copy link

azatian commented Jun 4, 2023

Hello,

I've been using the following code to programmatically download our annotations from our WebKnossos instance. However, I've run into an issue, where the size of the downloaded annotation cutout is not the same size as the underlying image cutout. I'm not sure why the size is different as everything that appears on the UI corresponds to the original image layer size.

Size of our cutout uploaded to WK: 816 × 816 × 6

However, using this code, the size downloaded is 832 x 640 x 6.

ds = wk.dataset.Dataset('tmp', voxel_size=(4,4,40))
with wk.webknossos_context(
    token="our-token",
    url="our-server-address"):
        
    annotation = wk.Annotation.download(
        "646e55b30100003e29aff00b",
        #annotation_type="Explorational",
    )
    
annotation.export_volume_layer_to_dataset(ds)
mag_view = ds.get_segmentation_layers()[0].get_mag(MAG)
data = mag_view.read()[0,:,:,:6]
data.shape

Shape is 832 x 640 x 6 ??

Python
webknossos 0.10.24

Webknossos U.I version 22.09.0
wkissue

@azatian azatian added the bug label Jun 4, 2023
@azatian
Copy link
Author

azatian commented Jun 4, 2023

I've tested the download on all of our annotations and the size that is being downloaded is not the original size...it is some multiple of 32
Here are some examples
Volume shape was (912,912,6), downloaded annotation was (928,928,32)
Volume shape was (1050, 1050, 6), downloaded annotation was (928, 1056, 32)
Volume shape was (588, 588, 6), dowloaded annotation was (544, 608, 32)
Volume shape was (378, 378, 6), downloaded annotation was (224, 320, 32)
Volume shape was (774, 774, 6), downloaded annotation was (800, 736, 32)

@azatian
Copy link
Author

azatian commented Jun 4, 2023

For a visual, this is the mentioned dataset in the post. The two layers are cellseg and img. Cellseg is the red shading. The img layer is the img itself. They both have sizes 816,816,6 with a data type of uint8.
The volume layer is the annotation, the paintings in blue. When hovering over the info button, the size is also 816,816,6 but for some reason the data type is uint32. Not sure if the dtype difference is the reason why the downloaded annotation is of a different shape.
wklayers

wklayers2

@fm3
Copy link
Member

fm3 commented Jun 5, 2023

Hi and thanks for your report!

You are rightly confused… Some context: volume annotations in webknossos are internally stored in 32³-voxel chunks. This means that some of these chunks “protrude” from the dataset bounding box if the bounding box is not itself divisible by 32 in a dimension. Furthermore, these chunks are saved sparsely, so only where a brush stroke has occurred, a chunk is stored.

Now the confusing part is what happens in export_volume_layer_to_dataset – it downloads all of these stored chunks and writes their contents to the dataset. This will expand the tempoarary dataset’s bounding box to encompass all these chunks where something was stored. This is why you always get 32 in z and why x and y vary, depending on how much was brushed.

I would assume that the array data is actually complete and correct. It is only the bounding box metadata that differs from what you expected.

I believe you could just call ds.get_segmentation_layers()[0].bounding_box = wk.BoundingBox((0,0,0),(816,816,6)) to fix that property. After that, reading the data the way you did should return the expected shape.

You could also use Dataset.open_remote to programmatically get the original dataset’s bounding box info, in order to then set it for your temp dataset.

We understand that this is confusing and there should probably be a convenience function for this. We will have a look and discuss this internally. Trouble is that some of our datasets are multiple teravoxels in size, but only smaller areas are annotated, so we are reluctant to always set the bbox to the full input dataset’s.

I hope this helps!

@azatian
Copy link
Author

azatian commented Jun 5, 2023

Thank you very much for your prompt response. This makes a lot of sense and now my annotations are aligned!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants