In- and output

A Qiber3D.Network can either be created from from an image stack, or an already reconstructed source like a .mv3d or .swc file. To load the network simply pass its path to Qiber3D.Network.load(). Based on the file suffix the corresponding part of Qiber3D.IO.load is used.

Note

The examples presented here use the corresponding image stacks from figshare doi:10.6084/m9.figshare.13655606. The Qiber3D.helper.Example class can be used to download the data easily.

  • microvascular_network.nd2 - FigID: 26211077 (1.06 GB)

  • microvascular_network.tif - FigID: 30771817 (1.06 GB)

  • microvascular_network-C2.tif - FigID: 30771877 (362 MB)

  • microvascular_network-C2-reduced.tif - FigID: 31106104 (40MB)

Note

To directly download the files on the commandline curl can be used. Just replace $(FigID) with the number from the list above.

curl -X GET "https://api.figshare.com/v2/file/download/$(FigID)"

ND2 example

>>> import logging
>>> from Qiber3D import Network, config
>>> from Qiber3D.helper import Example, change_log_level
>>> config.log_level = change_log_level(logging.DEBUG)  # This will show 3D renderings of the intermediate steps
>>> config.extract.nd2_channel_name = 'FITC'
>>> net_ex = Example.nd2()
>>> net = Network.load(net_ex)
Qiber3D_extract [INFO] Load image data from microvascular_network.nd2
Qiber3D_extract [INFO] Image voxel size: [1.230,1.230,2.500]
Qiber3D_extract [INFO] Median Filter (despeckle)
Qiber3D_extract [INFO] Z-Drop correction
Qiber3D_extract [INFO] Resample image to cubic voxels
Qiber3D_extract [INFO] Apply gaussian filter
Qiber3D_extract [INFO] Generate binary representation
Qiber3D_extract [INFO] Binary representation used a threshold of 4.9% (otsu)
Qiber3D_extract [INFO] Morph binary representation
Qiber3D_extract [INFO] reconstruct image
Qiber3D_reconstruct [INFO] Skeletonize image by thinning
Qiber3D_reconstruct [INFO] Euclidean distance transformation
Link up skeleton: 100%|██████████| 13/13 [00:15<00:00,  1.17s/it]
Qiber3D_reconstruct [INFO] Build Qiber3D.Network from the raw graph
Qiber3D_reconstruct [INFO] Cleaning Network
Qiber3D_reconstruct [INFO] Smooth Segments
>>> print(net)
Input file: microvascular_network.nd2
  Number of fibers: 405 (clustered 109)
  Number of segments: 966
  Number of branch points: 327
  Total length: 43192.45
  Total volume: 5146410.65
  Average radius: 5.770
  Cylinder radius: 6.158
  Bounding box volume: 683663872

A reconstructed network can quickly be saved with Qiber3D.Network.save(). Without arguments, just the reconstructed network is saved. If the image stack at the different stages should be preserved set `save_steps to True. Saving the reconstruction steps can consume a lot of space.

>>> net.save(save_steps=True)
Qiber3D_core [INFO] Network saved to microvascular_network.qiber

The created .qiber can be loaded as any other supported file type.

>>> net = Network.load('microvascular_network.qiber')

TIFF example

The same example can be run using a .tif version of the same data.

Note

While the reduced dataset is the same subject, the reduced resolution and greyscale range will result in altered results.

>>> from Qiber3D import Network, config
>>> from Qiber3D.helper import Example
>>> config.extract.voxel_size = [1.2302, 1.2302, 2.5]
>>> config.extract.low_memory = True
>>> net_ex = Example.tiff()
>>> net = Network.load(net_ex, channel=1)
Qiber3D_extract [INFO] Load image data from microvascular_network.tif
Qiber3D_extract [INFO] Image voxel size: [1.230,1.230,2.500]
Qiber3D_extract [INFO] Median Filter (despeckle)
Qiber3D_extract [INFO] Z-Drop correction
Qiber3D_extract [INFO] Resample image to cubic voxels
Qiber3D_extract [INFO] Apply gaussian filter
Qiber3D_extract [INFO] Generate binary representation
Qiber3D_extract [INFO] Binary representation used a threshold of 4.9% (otsu)
Qiber3D_extract [INFO] Morph binary representation
Qiber3D_extract [INFO] reconstruct image
Qiber3D_reconstruct [INFO] Skeletonize image by thinning
Qiber3D_reconstruct [INFO] Euclidean distance transformation
Qiber3D_reconstruct [INFO] Build Qiber3D.Network from the raw graph
Qiber3D_reconstruct [INFO] Cleaning Network
Qiber3D_reconstruct [INFO] Smooth Segments
>>> print(net)
Input file: microvascular_network.tif
  Number of fibers: 406 (clustered 111)
  Number of segments: 971
  Number of branch points: 329
  Total length: 43241.93
  Total volume: 5150823.10
  Average radius: 5.775
  Cylinder radius: 6.158
  Bounding box volume: 683658224

A reconstructed network can saved as we did before with Qiber3D.Network.save(). The save function can be given a name for the save file.

>>> net.save('reconstructed_net.qiber')
Qiber3D_core [INFO] Network saved to reconstructed_net.qiber

Synthetic example

The settings for the different image filters can be accessed through the Qiber3D.config module. In next example the image to be reconstructed is already cleaned up and just needs to be binarized. As source we will use a rasterized version of the synthetic test network (:meth:’Qiber3D.IO.load.synthetic_network’).

>>> from Qiber3D import config
>>> from Qiber3D import Network, IO
>>> syn_net = IO.load.synthetic_network()
# set up the resolution of the synthetic network
>>> voxel_resolution = 5
>>> config.extract.voxel_size = [1 / voxel_resolution] * 3
# switching off unneeded filters,
# as the synthetic network is already cleaned
>>> config.extract.morph.apply = False
>>> config.extract.median.apply = False
>>> config.extract.smooth.apply = False
>>> config.extract.z_drop.apply = False
# set a specific threshold to preserve radius
>>> config.extract.binary.threshold = 29
# export the synthetic network as .tif file
>>> syn_net.export('synthetic.tif', voxel_resolution=voxel_resolution, overwrite=True)
Qiber3D_render [INFO] Rasterizing network (voxel resolution : 5.00E+00 voxel/unit)
Qiber3D_core [INFO] Network exported to synthetic.tif.
# import .tif file
>>> net = Network.load('synthetic.tif')
Qiber3D_render [INFO] Rasterizing network (voxel resolution : 5.00E+00 voxel/unit)
Qiber3D_core [INFO] Network exported to synthetic.tif
Qiber3D_extract [INFO] Load image data from synthetic.tif
Qiber3D_extract [INFO] Image voxel size: [0.200,0.200,0.200]
Qiber3D_extract [INFO] Resample image to cubic voxels
Qiber3D_extract [INFO] Generate binary representation
Qiber3D_extract [INFO] Binary representation used a threshold of 29.0% (direct)
Qiber3D_extract [INFO] reconstruct image
Qiber3D_reconstruct [INFO] Skeletonize image by thinning
Qiber3D_reconstruct [INFO] Euclidean distance transformation
Qiber3D_reconstruct [INFO] Link up skeleton
Qiber3D_reconstruct [INFO] Build Qiber3D.Network from the raw graph
Qiber3D_reconstruct [INFO] Cleaning Network
Qiber3D_reconstruct [INFO] Smooth Segments
>>> print(net)
Input file: synthetic.tif
  Number of fibers: 4 (clustered 2)
  Number of segments: 11
  Number of branch points: 4
  Total length: 1120.84
  Total volume: 4665.63
  Average radius: 0.960
  Cylinder radius: 1.151
  Bounding box volume: 799821

Based on the synthetic network we can explore further export options of a Qiber3D.Network.

syn_net.export('synthetic.json')
Qiber3D_core [INFO] Network exported to synthetic.json
synthetic.json (truncated)
{
  "meta": {
    "created": "2021-01-26T14:39:31.774967", "app_name": "Qiber3D", "app_version": "0.4.0", "source": null,
    "name": "synthetic"
  }, "network": {
  "fiber": {
    "0": {
      "fid": 0, "volume": 1651.7148841392172, "average_radius": 0.8604967317483905,
      "cylinder_radius": 1.0789216328856772, "length": 451.65352873495203, "sid_list": [0, 1, 2, 3, 4]
    }, "1": {
      "fid": 1, "volume": 1750.7734629144547, "average_radius": 0.9743524445038705,
      "cylinder_radius": 1.322617429184498, "length": 318.5749324139831, "sid_list": [8, 5, 6, 7]
    }, "2": {
      "fid": 2, "volume": 600.3195103585697, "average_radius": 1.128023071088283, "cylinder_radius": 1.145703995907954,
      "length": 145.5753120928598, "sid_list": [9]
    }, "3": {
      "fid": 3, "volume": 685.8592471183374, "average_radius": 0.9674890076192243,
      "cylinder_radius": 0.9836495172449595, "length": 225.6339048471931, "sid_list": [10]
    }
  }, "extractor_data": null, "bbox": [[10.0, 7.8, -2.7], [153.4, 112.1, 51.2]],
  "bbox_size": [143.4, 104.3, 53.900000000000006], "bbox_volume": 806161.8180000001,
  "center": [81.7, 59.949999999999996, 24.250000000000004], "volume": 4688.667104530579,
  "average_radius": 0.9359459559513582, "max_radius": 1.7082413328724901, "cylinder_radius": 1.1434670669897804,
  "length": 1141.437678088988, "segment": {
    "0": {
      "sid": 0, "volume": 17.301298158883707, "average_radius": 0.3663121252534919,
      "cylinder_radius": 0.3701523254210267, "length": 40.19461319013881, "direction": [3.6000000000000014, 36.6, 5.7],
      "point": [
        [20.0, 10.0, -0.0], [19.6, 11.6, -0.2], [19.2, 13.2, -0.3], [18.8, 14.7, -0.4], [18.5, 16.2, -0.5],
        [18.2, 17.6, -0.6], [17.9, 19.0, -0.7], [17.7, 20.4, -0.7], [17.5, 21.7, -0.7], [17.3, 23.0, -0.7],

Full output: synthetic.json

syn_net.export('synthetic.xlsx')
Qiber3D_core [INFO] Network exported to synthetic.xlsx

Full output: synthetic.xlsx

syn_net.export('synthetic.csv')
Qiber3D_core [INFO] Network exported to synthetic.csv
synthetic.csv (truncated)
FID;SID;X;Y;Z;Radius
0;0;20.000;10.000;-0.000;0.500
0;0;19.600;11.600;-0.200;0.473
0;0;19.200;13.200;-0.300;0.448
0;0;18.800;14.700;-0.400;0.425
0;0;18.500;16.200;-0.500;0.404
0;0;18.200;17.600;-0.600;0.385
0;0;17.900;19.000;-0.700;0.367
0;0;17.700;20.400;-0.700;0.351
0;0;17.500;21.700;-0.700;0.337
0;0;17.300;23.000;-0.700;0.324
0;0;17.200;24.200;-0.700;0.313
0;0;17.000;25.400;-0.700;0.304
0;0;16.900;26.600;-0.700;0.296

Full output: synthetic.csv

syn_net.export('synthetic.mv3d')
Qiber3D_core [INFO] Network exported to synthetic.mv3d
synthetic.csv (truncated)
# MicroVisu3D file (created by Qiber3D 0.4.0)
# Number of lines   11
# Number of points  1404
# Number of inter.  5
#
# No	x	y	z	d
#
0	20.000	10.000	-0.000	1.000
0	19.600	11.600	-0.200	0.946
0	19.200	13.200	-0.300	0.897
0	18.800	14.700	-0.400	0.851
0	18.500	16.200	-0.500	0.809
0	18.200	17.600	-0.600	0.770
0	17.900	19.000	-0.700	0.735

Full output: synthetic.mv3d

syn_net.export('synthetic.x3d')
Qiber3D_core [INFO] Network exported to synthetic.x3d
synthetic.x3d (truncated)
<?xml version="1.0" encoding ="UTF-8"?>

<X3D profile="Immersive" version="3.0">
  <head>
    <meta name="filename" content="docs\x3d\synthetic_show.x3d"/>
    <meta name="generator" content="Visualization ToolKit X3D exporter v0.9.1"/>
    <meta name="numberofelements" content="11"/>
  </head>
  <Scene>
    <Background skyColor="1.00000000000000000e+00 1.00000000000000000e+00 1.00000000000000000e+00"/>
    <Viewpoint fieldOfView="5.23598790168762207e-01" position="8.18827030567863687e+01 6.01443915117113974e+01 3.86125999329838692e+02" description="Default View" orientation="0.00000000000000000e+00 0.00000000000000000e+00 1.00000000000000000e+00 -0.00000000000000000e+00" centerOfRotation="8.18827030567863687e+01 6.01443915117113974e+01 2.42252174161411489e+01"/>
    <NavigationInfo type='"EXAMINE" "FLY" "ANY"' speed="4.00000000000000000e+00" headlight="true"/>
    <DirectionalLight ambientIntensity="1.00000000000000000e+00" intensity="0.00000000000000000e+00" color="1.00000000000000000e+00 1.00000000000000000e+00 1.00000000000000000e+00"/>
    <Transform DEF="ROOT" translation="0.00000000000000000e+00 0.00000000000000000e+00 0.00000000000000000e+00">

Full output: synthetic.x3d