We make use of Numpy arrays and Pillow Images to represent data. Both are extremely rich tools, and to learn more about them please see the appropriate documentation for information about saving data to image files and more.
+
+
Installation
+
ImageryClient can be installed with pip:
+
pip install imageryclient
+
While not required, if you are using a CAVE-hosted dataset, installing CAVEclient will make your life much easier.
+
+
+
+
+
+
+Troubleshooting
+
+
+
+
If you have installation issues due to Cloudvolume, which can have a complex set of requirements, we recommend looking at its github issues page for help.
+
+
+
+
+
Basic example
+
A small example that uses all of the major components of ImageryClient: Downloading aligned images and segmentation, specifying specific segmentations to visualize, and generating an image overlay. This uses the pubically available Kasthuri et al. 2014 dataset.
Connectomics data often involves a combination of microscopy imagery and segmentation, labels of distinct objects applied to this imagery. While exploring the data in tools like Neuroglancer is great, a common task is often to make figures overlaying 2d images and segmentation sliced from the larger data. ImageryClient is designed to make it easy to generate aligned cutouts from imagery and segmentation, and make it efficient to produce attractive, publication-ready overlay images.
+
Because of the size of these volumes, cloud-based serverless n-d array file storage systems are often used to host this data. CloudVolume has become an excellent general purpose tool for accessing such data. However, imagery and segmentation for the same data are hosted at distinct cloud locations and can differ in basic properties like base resolution. Moreover, imagery and segmentation have data that means intrensically different things. Values in imagery indicate pixel intensity in order to produce a picture, while values in segmentation indicate the object id at a given location. ImageryClient acts as a front end for making aligned cutouts from multiple cloudvolume sources, splitting segmentations into masks for each object, and more.
Make a colored composite overlay for a 3d mask from an iterable of masks.
+
+
Parameters
+
+
+
+
+
+
+
+
+
+
Name
+
Type
+
Description
+
Default
+
+
+
+
+
segs
+
+
Iterable of masked images of the same size. If a dict, colors must be a dict as well.
+
required
+
+
+
colors
+
list-like, dict, or None
+
Iterable of RGB colors of the same size as masks. If a dict, masks must also be a dict and colors must have all keys in masks. If None, uses discrete_colors to generate colors.
+
None
+
+
+
alpha
+
float
+
Alpha value for the overlay
+
0.2
+
+
+
imagery
+
PIL.PIL.Image.PIL.Image.Image or None
+
If an Image, applies the overlay to the image, by default None
+
None
+
+
+
outline
+
bool
+
If True, produces an outline instead of a flat overay, by default False
+
False
+
+
+
merge_outline
+
bool
+
If True, the merge outline applies to the segmentation as a whole and thus internal contacts are not outlined.
+
True
+
+
+
overlap
+
bool
+
If False, segmentations later in the list will not overlap segmentations earlier on the list.
+
True
+
+
+
width
+
int
+
If outline=True, sets the width of the outline, by default 10
+
10
+
+
+
side
+
out or ‘in’
+
If outline=True, selects if the outline is inside or outside the original segmentation mask, by default ‘out’
+
'out'
+
+
+
dim
+
int
+
Determines axis over which slices are iterated if the data is 3 dimensional. Default is 2 (z-axis).
+
2
+
+
+
+
+
+
Returns
+
+
+
+
+
+
+
+
Type
+
Description
+
+
+
+
+
list or PIL.PIL.Image.PIL.Image.Image
+
Image or list of composite overlay images, optionally overlaid over provided imagery. List or single image is determined based on segmentation arrays being 2 or 3 dimensional.
Tool to help download imagery and segmentation data.
+
Can either take explicit cloudvolume paths for imagery and segmentation or use the Info Service to look up the right paths.
+
+
Parameters
+
+
+
+
+
+
+
+
+
+
Name
+
Type
+
Description
+
Default
+
+
+
+
+
client
+
caveclient.caveclient.CAVEclient or None
+
A pre-initialized CAVEclient to use for configuration. If used, the image source and segmentation source come from the info service values.
+
None
+
+
+
resolution
+
array - like or image or segmentation
+
Sets the voxel resolution that bounds will be entered in, by default ‘image’, which is the mip 0 resolution of the imagery.
+
None
+
+
+
segmentation
+
bool
+
If False, no segmentation cloudvolume is initialized. By default True
+
True
+
+
+
imagery
+
bool
+
If False, no imagery cloudvolume is initialized. By default True
+
True
+
+
+
image_source
+
str
+
CloudVolume path to an imagery source, by default None
+
None
+
+
+
segmentation_source
+
str
+
CloudVolume path to a segmentation source, by default None
+
None
+
+
+
image_mip
+
int
+
Default mip level to use for imagery lookups, by default 0. Note that the same mip level for imagery and segmentation can correspond to different voxel resolutions.
+
None
+
+
+
segmentation_mip
+
int
+
Default mip level to use for segmentation lookups, by default 0.
+
None
+
+
+
auth_token
+
str or None
+
Auth token to use for cloudvolume. If None, uses the default values from the CAVEclient. Default is None.
+
None
+
+
+
timestamp
+
(datetime.datetime.datetime or None)
+
Fixed timestamp to use for segmentation lookups. If None, defaults to the present time when each function is run. Default is None.
Download aligned and scaled imagery and segmentation data at a given resolution.
+
+
Parameters
+
+
+
+
+
+
+
+
+
+
Name
+
Type
+
Description
+
Default
+
+
+
+
+
bounds
+
2x3 list of ints
+
A list of the lower and upper bound point for the cutout. The units are voxels in the resolution set by the base_resolution parameter.
+
required
+
+
+
image_mip
+
int
+
Mip level of the imagery if something other than the default is wanted, by default None
+
None
+
+
+
segmentation_mip
+
int
+
Mip level of the segmentation if something other than the default is wanted, by default None
+
None
+
+
+
root_ids
+
list, None, or ‘all’
+
If a list, the segmentation cutout only includes voxels for a specified set of root ids. If None, default to the supervoxel ids. If ‘all’, finds all root ids corresponding to the supervoxels in the cutout and get all of them. By default ‘all’.
+
'all'
+
+
+
resize
+
bool
+
If True, upscale the lower resolution cutout to the same resolution of the higher one (either imagery or segmentation).
+
True
+
+
+
split_segmentations
+
bool
+
If True, the segmentation is returned as a dict of masks (using split_segmentation_cutout), and if False returned as an array with root_ids (using segmentation_cutout), by default False
+
False
+
+
+
include_null_root
+
bool
+
If True, includes root id of 0, which is usually reserved for a null segmentation value. Default is False.
+
False
+
+
+
bbox_size
+
array or None
+
If not None, bbox_size is a 3 element array of ints giving the dimensions of the cutout. In this case, bounds is treated as the center.
+
None
+
+
+
resolution
+
list - like
+
Voxel resolution used when specifying bounds bounds and bbox_size (but not image_size). If none, defaults to client default.
+
None
+
+
+
timestamp
+
datetime or None
+
Timestamp to use for dynamic segmentation data
+
None
+
+
+
scale_to_bounds
+
bool or None
+
If True, rescales image to the same size as the bounds. Default is None, which rescales if mip is not set but otherwise does not.
+
None
+
+
+
convert_to_int64
+
bool
+
If True, converts segmentation data to int64 from uint64 if it is safe to do so. Default is True. If not safe, raises a warning and does not convert from uint64.
+
True
+
+
+
+
+
+
Returns
+
+
+
+
+
+
+
+
Type
+
Description
+
+
+
+
+
cloudvolume.cloudvolume.VolumeCutout
+
Imagery volume cutout
+
+
+
numpy.numpy.ndarray or dict
+
Segmentation volume cutout as either an ndarray or dict of masks depending on the split_segmentations flag.
Get an image cutout for a certain location or set of bounds and a mip level.
+
+
Parameters
+
+
+
+
+
+
+
+
+
+
Name
+
Type
+
Description
+
Default
+
+
+
+
+
bounds
+
array
+
Either a 2x3 array of a lower bound and upper bound point to bound the cutout in units of voxels in a resolution set by the base_resolution parameter. Alternatively, if bbox_size or image_size is set, bounds should be a 3-element array specifying the center of the field of view.
+
required
+
+
+
bbox_size
+
array or None
+
If not None, bbox_size is a 3 element array of ints giving the dimensions. In this case, bounds is treated as the center.
+
None
+
+
+
image_size
+
array or None
+
If not None, indicates the size of the image desired in pixels. Cannot be set with bbox_size, since it has potentially conficting information.
+
None
+
+
+
mip
+
int
+
Mip level of imagery to get if something other than the default is wanted, by default None.
+
None
+
+
+
resolution
+
list - like
+
Voxel resolution used when specifying bounds bounds and bbox_size (but not image_size). If none, defaults to client default.
+
None
+
+
+
scale_to_bounds
+
bool, optional.
+
If True, rescales image to the same size as the bounds. Default is None, which rescales if mip is not set but otherwise does not.
+
None
+
+
+
+
+
+
Returns
+
+
+
+
+
+
+
+
Type
+
Description
+
+
+
+
+
cloudvolume.VolumeCutout
+
An n-d image of the image requested with image intensity values as the elements.
Save aligned and scaled imagery and segmentation mask cutouts as pngs. Kwargs are passed to imageio.imwrite.
+
+
Parameters
+
+
+
+
+
+
+
+
+
+
Name
+
Type
+
Description
+
Default
+
+
+
+
+
filename_prefix
+
str
+
Prefix for the segmentation filenames. The full filename will be either {filename_prefix}root_id{root_id}.png or {filename_prefix}root_id{root_id}_{i}.png, depending on if multiple slices of each root id are saved.
+
required
+
+
+
bounds
+
2x3 list of ints
+
A list of the lower and upper bound point for the cutout. The units are voxels in the resolution set by the base_resolution parameter. Only used if a precomputed data is not passed. By default, None.
+
None
+
+
+
image_mip
+
int
+
Only used if a precomputed data is not passed. Mip level of imagery to get if something other than the default is wanted, by default None.
+
None
+
+
+
segmentation_mip
+
int
+
Only used if precomputed data is not passed. Mip level of segmentation to get if something other than the default is wanted, by default None
+
None
+
+
+
root_ids
+
list, None, or ‘all’
+
If a list, the segmentation cutout only includes voxels for a specified set of root ids. If None, default to the supervoxel ids. If ‘all’, finds all root ids corresponding to the supervoxels in the cutout and get all of them. By default ‘all’.
+
'all'
+
+
+
include_null_root
+
bool
+
If True, includes root id of 0, which is usually reserved for a null segmentation value. By default, False.
+
False
+
+
+
segmentation_colormap
+
dict
+
A dict of root ids to an uint8 RGB color triplet (0-255) or RGBa quadrooplet to optionally color the mask png. Any root id not specified will be rendered in white. Color triplets default to full opacity. Default is an empty dictionary.
+
{}
+
+
+
resize
+
bool
+
If True, upscale the lower resolution cutout to the same resolution of the higher one (either imagery or segmentation).
+
True
+
+
+
precomputed_data
+
tuple
+
Already computed tuple with imagery and segmentation mask data, in that order. If not provided, bounds must be given to download cutout data. By default, None.
+
None
+
+
+
slice_axis
+
int
+
If the image data is truly 3 dimensional, determines which axis to use to save serial images, by default 2 (i.e. z-axis)
+
2
+
+
+
bbox_size
+
array or None
+
If not None, bbox_size is a 3 element array of ints giving the dimensions of the cutout. In this case, bounds is treated as the center.
+
None
+
+
+
resolution
+
list - like
+
Voxel resolution of the bounds provided. If not provided, uses the client defaults.
+
None
+
+
+
timestamp
+
datetime
+
Timestamp to use for the segmentation. If not provided, defaults to the client defaults.
+
None
+
+
+
scale_to_bounds
+
bool or None
+
If True, rescales image to the same size as the bounds. Default is None, which rescales if mip is not set but otherwise does not.
Prefix for the imagery filename. The full filename will be {filename_prefix}_imagery.png
+
required
+
+
+
bounds
+
2x3 list of ints
+
A list of the lower and upper bound point for the cutout. The units are voxels in the resolution set by the base_resolution parameter. Only used if a precomputed image is not passed. By default, None.
+
None
+
+
+
mip
+
int
+
Only used if a precomputed image is not passed. Mip level of imagery to get if something other than the default is wanted, by default None
+
None
+
+
+
precomputed_image
+
cloudvolume.cloudvolume.VolumeCutout
+
Already downloaded VolumeCutout data to save explicitly. If called this way, the bounds and mip arguments will not apply. If a precomputed image is not provided, bounds must be specified to download the cutout data. By default None
+
None
+
+
+
slice_axis
+
int
+
If the image data is truly 3 dimensional, determines which axis to use to save serial images, by default 2 (i.e. z-axis)
+
2
+
+
+
bbox_size
+
array or None
+
If not None, bbox_size is a 3 element array of ints giving the dimensions of the cutout. In this case, bounds is treated as the center.
+
None
+
+
+
image_size
+
array or None
+
If not None, indicates the size of the image desired in pixels. Cannot be set with bbox_size, since it has potentially conficting information.
+
None
+
+
+
resolution
+
list - like
+
Voxel resolution used when specifying bounds bounds and bbox_size (but not image_size). If none, defaults to client default.
+
None
+
+
+
scale_to_bounds
+
bool or None
+
If True, rescales image to the same size as the bounds. Default is None, which rescales if mip is not set but otherwise does not.
Save queried or precomputed segmentation masks to png files. Additional kwargs are passed to imageio.imwrite.
+
+
Parameters
+
+
+
+
+
+
+
+
+
+
Name
+
Type
+
Description
+
Default
+
+
+
+
+
filename_prefix
+
str
+
Prefix for the segmentation filenames. The full filename will be either {filename_prefix}root_id{root_id}.png or {filename_prefix}root_id{root_id}_{i}.png, depending on if multiple slices of each root id are saved.
+
required
+
+
+
bounds
+
2x3 list of ints
+
A list of the lower and upper bound point for the cutout. The units are voxels in the resolution specified. Only used if a precomputed segmentation is not passed. By default, None.
+
None
+
+
+
mip
+
int
+
Only used if a precomputed segmentation is not passed. Mip level of segmentation to get if something other than the default is wanted, by default None
+
None
+
+
+
root_ids
+
list, None, or ‘all’
+
If a list, the segmentation cutout only includes voxels for a specified set of root ids. If None, default to the supervoxel ids. If ‘all’, finds all root ids corresponding to the supervoxels in the cutout and get all of them. By default ‘all’.
+
'all'
+
+
+
precomputed_masks
+
dict
+
Already downloaded dict of mask data to save explicitly. If called this way, the bounds and mip arguments will not apply. If precomputed_masks are not provided, bounds must be given to download cutout data. By default None
+
None
+
+
+
segmentation_colormap
+
dict
+
A dict of root ids to an uint8 RGB color triplet (0-255) or RGBa quadrooplet to optionally color the mask png. Any root id not specified will be rendered in white. Color triplets default to full opacity. Default is an empty dictionary.
+
{}
+
+
+
slice_axis
+
int
+
If the image data is truly 3 dimensional, determines which axis to use to save serial images, by default 2 (i.e. z-axis)
+
2
+
+
+
include_null_root
+
bool
+
If True, includes root id of 0, which is usually reserved for a null segmentation value. Default is False.
+
False
+
+
+
bbox_size
+
array or None
+
If not None, bbox_size is a 3 element array of ints giving the dimensions of the cutout. In this case, bounds is treated as the center.
+
None
+
+
+
image_size
+
array or None
+
If not None, indicates the size of the image desired in pixels. Cannot be set with bbox_size, since it has potentially conficting information.
+
None
+
+
+
resolution
+
list - like
+
Voxel resolution used when specifying bounds bounds and bbox_size (but not image_size). If none, defaults to client default.
+
None
+
+
+
timestamp
+
datetime or None
+
Timestamp to use for dynamic segmentation data
+
None
+
+
+
scale_to_bounds
+
bool or None
+
If True, rescales image to the same size as the bounds. Default is None, which rescales if mip is not set but otherwise does not.
Get a cutout of the segmentation imagery for some or all root ids between set bounds. Note that if all root ids are requested in a large region, it could take a long time to query all supervoxels.
+
+
Parameters
+
+
+
+
+
+
+
+
+
+
Name
+
Type
+
Description
+
Default
+
+
+
+
+
bounds
+
2x3 list of ints
+
A list of the lower and upper bound point for the cutout. The units are voxels in the resolution set by the base_resolution parameter.
+
required
+
+
+
root_ids
+
list, None, or ‘all’
+
If a list, only compute the voxels for a specified set of root ids. If None, default to the supervoxel ids. If ‘all’, find all root ids corresponding to the supervoxels in the cutout and get all of them. None, by default ‘all’
+
'all'
+
+
+
bbox_size
+
array or None
+
If not None, bbox_size is a 3 element array of ints giving the dimensions. In this case, bounds is treated as the center.
+
None
+
+
+
image_size
+
array or None
+
If not None, indicates the size of the image desired in pixels. Cannot be set with bbox_size, since it has potentially conficting information.
+
None
+
+
+
mip
+
int
+
Mip level of the segmentation if something other than the defualt is wanted, by default None
+
None
+
+
+
resolution
+
list - like
+
Voxel resolution used when specifying bounds bounds and bbox_size (but not image_size). If none, defaults to client default.
+
None
+
+
+
timestamp
+
datetime or None
+
Timestamp to use for dynamic segmentation data
+
None
+
+
+
scale_to_bounds
+
bool or None
+
If True, rescales image to the same size as the bounds. Default is None, which rescales if mip is not set but otherwise does not.
+
None
+
+
+
convert_to_int64
+
bool
+
If True, converts segmentation data to int64 from uint64 if it is safe to do so. Default is True. If not safe, raises a warning and does not convert from uint64.
+
True
+
+
+
+
+
+
Returns
+
+
+
+
+
+
+
+
Type
+
Description
+
+
+
+
+
numpy.numpy.ndarray
+
Array whose elements correspond to the root id (or, if root_ids=None, the supervoxel id) at each voxel.
Generate segmentation cutouts with a single binary mask for each root id, organized as a dict with keys as root ids and masks as values.
+
+
Parameters
+
+
+
+
+
+
+
+
+
+
Name
+
Type
+
Description
+
Default
+
+
+
+
+
bounds
+
2x3 list of ints
+
A list of the lower and upper bound point for the cutout. The units are voxels in the resolution set by the base_resolution parameter.
+
required
+
+
+
root_ids
+
list, None, or ‘all’
+
If a list, only compute the voxels for a specified set of root ids. If None, default to the supervoxel ids. If ‘all’, find all root ids corresponding to the supervoxels in the cutout and get all of them. None, by default ‘all’
+
'all'
+
+
+
include_null_root
+
bool
+
If True, includes root id of 0, which is usually reserved for a null segmentation value. Default is False.
+
False
+
+
+
bbox_size
+
array or None
+
If not None, bbox_size is a 3 element array of ints giving the dimensions. In this case, bounds is treated as the center.
+
None
+
+
+
image_size
+
array or None
+
If not None, indicates the size of the image desired in pixels. Cannot be set with bbox_size, since it has potentially conficting information.
+
None
+
+
+
mip
+
int
+
Mip level of the segmentation if something other than the default is wanted, by default None
+
None
+
+
+
resolution
+
list - like
+
Voxel resolution used when specifying bounds bounds and bbox_size (but not image_size). If none, defaults to client default.
+
None
+
+
+
timestamp
+
datetime or None
+
Timestamp to use for dynamic segmentation data
+
None
+
+
+
scale_to_bounds
+
bool or None
+
If True, rescales image to the same size as the bounds. Default is None, which rescales if mip is not set but otherwise does not.
+
None
+
+
+
+
+
+
Returns
+
+
+
+
+
+
+
+
Type
+
Description
+
+
+
+
+
dict
+
Dict whose keys are root ids and whose values are the binary mask for that root id, with a 1 where the object contains the voxel.
This site provides basic documentation for the functions in ImageryClient. Please see the tutorials for more information about how to use them.
+
Documentation is split into three parts:
+
+
ImageryClient for using the ImageryClient class to download images and segmentation.
+
Compositing for generating segmentation overlays for visualization.
+
Utilities has additional utilities that may be useful for data manipulation. Note that, unlike the other two categories, these functions are not imported by default.
+
+
+
+
+
+
+
ImageryClient
+
Main functions for downloading imagery and segmentation data.
Here, we will use the ImageryClient to get some data from the Kasthuri et al. 2014 dataset hosted by Google. In its simplest form, we just intialize an ImageryClient object with an image cloudpath and a segmentation cloudpath. Values are taken from the layers in the linked neuroglancer state.
+
import imageryclient as ic
+
+img_src ='precomputed://gs://neuroglancer-public-data/kasthuri2011/image_color_corrected'
+seg_src ='precomputed://gs://neuroglancer-public-data/kasthuri2011/ground_truth'
+
+img_client = ic.ImageryClient(image_source=img_src, segmentation_source=seg_src)
+
+
Imagery cutouts
+
Cutouts are defined by their bounds, which can be specified by providing bounds. The most direct form is a pair of points representing the upper and lower corners of the bounding box. By default, coordinates are in the default resolution of the imagery as you would see in neuroglancer.
Since often we are using analysis points to center an image on, we can alternatively define a center point and the width/height/depth of the bounding box (in voxels). The same image could be achived from this specification.
A very important element in ImageryClient is the resolution, which specifies the units that you are using when providing bounds. You can check the resolution that the client is expecting with img_client.resolution. The resolution will default to the highest resolution available for the imagery, but you can specify another resolution manually. For example, to say that you are going to provide bounds in [8,8,30] voxel units, you would add the resolution argument:
You can also explicitly set the resolution to "image" or "segmentation" to use the highest available resolution available for either. Resolution can also be specified in each of the functions for image or segmentation cutouts, but will default to the client values.
+
Note that the volumetric data itself is not necessarily at the resolution specified, but rather this parameter determines how to interpret the coordinates. The resolution is set by the image and segmentation mip levels, which can be added either when creating the ImageryClient instance or when doing any cutout download. By default, ImageryClient will use the highest resolution mip level that is not labeled as a "placeholder" in CloudVolume.
+
+
Specifying image size instead of field of view
+
When upper and lower bounds are specified or a bbox_size is used, the resolution will change with mip level but the field of view that is downloaded will remain the same. Alternatively, one might want to download an image with a specific size in pixels and a specific mip level without having to calculate what bounding box would get you that.. This can be done in image_cutout by specifying the center point in the place of bounds and also specify image_size as a 2- or 3-element array. In this case, the center point will be adjusted according to the resolutions specified, while the field of view will change with image size.
+
In practice, this only is needed for non-default mip levels. If you specify mip level, this approach will always yield an image with the same size while a bounds-based approach will get smaller with increasing mips as the effective resolution gets coarser.
You can also use the scale_to_bounds=True argument to upscale an image to the size specified in the bounding box, equivalent to having one pixel for each voxel as measured by the resolution parameter.
+
+
+
+
Segmentations
+
An aligned segmentation cutout is retrieved similarly. Note that segmentations show segment ids, and are not directly visualizable. However, in this case we can convert to a uint8 greyscale and see the gist, although there are many better approaches to coloring segmentations that will be shown later. Note that for dynamic segmentations, you can use the timestamp parameter to (optionally) set the time at which segmentation will e looked up.
+
seg = img_client.segmentation_cutout(bounds)
+
+import numpy as np
+Image.fromarray( (seg.T / np.max(seg) *255).astype('uint8') )
+
+
+
+
Specific root ids can also be specified. All pixels outside those root ids have a value of 0.
It’s often convenient to split out the segmentation for each root id as a distinct mask. These “split segmentations” come back as a dictionary with root id as key and binary mask as value.
Aligned image and segmentations can be downloaded in one call, as well. If the lowest mip data in each differs in resolution, the lower resolution data will be optionally upsampled to the higher resolution in order to produce aligned overlays. Root ids and split segmentations can be optionally specified. This is the best option if your primary goal is overlay images.
Note that image_size is not an option for joint image and segmentation calls, because it’s not clear which bounds to use. If this is needed, you can use the img_client.segmentation_bbox_size_from_dimensions or img_client.image_bbox_size_from_dimensions to get the appropriate bbox_size argument for a segmentation-based image dimension (or image-based, respectively).
+
+
+
Using with CAVEclient
+
While the ImageryClient was designed to work specifically with the CAVEclient and its associated suite of services, it should work with any cloudvolume project.
+
However, if you are working within an CAVEclient-compatible project, a CAVEclient can be used to help configure the ImageryClient, filling in the imagery source, the segmentation source, authentication information, and the default resolution used in Neuroglancer.
from caveclient import CAVEclient
+client = CAVEclient('minnie65_public_v343') . # Note that you have to set up a token for this to work, see below.
+
+img_client = ic.ImageryClient(client=client)
+
+ctr = [240640, 207872, 21360]
+
+image, segs = img_client.image_and_segmentation_cutout(ctr,
+ split_segmentations=True,
+ bbox_size=(1024, 1024),
+ scale_to_bounds=True,
+)
+
+ic.composite_overlay(segs, imagery=image, palette='husl')
+
+
+
+
Note that the following code requires setting up a CAVE token to access the server. See here for details.
Once you have imagery and segmentation data, one important use case is to make visualizations overlaying segmentations on top of images.
+
Now let produce an overlay of segmentation and imagery to highlight a particular synapse. Overlays are returned as a PIL Image, which has convenient saving options but can also be converted to RGBa (a is for “alpha”, i.e. transparency) via a simple np.array call. Note that if imagery isn’t specified, the segmentations are colored but not put over another image. Segmentations must be either a list or a dict, such as comes out of split segmentation cutouts.
+
ic.composite_overlay(segs, imagery=image)
+
+
+
+
+
Aesthetic options
+
Colors are chosen by default from the perceptually uniform discrete HUSL Palette as implemented in Seaborn, and any color scheme available through Seaborn’s color_palette function is similarly easy to specify. Alpha is similarly easy to set.
While the overlay guides the eye, it can also obscure the imagery. Because of that, one can also use highly configurable outlines instead of solid overlays. The default option puts the outlines along the outside of the segmentations, but omits lines where two segmentations touch.
Outlines can also be put inside of the segmentation and width can be specified. Additionally, setting merge_outline to False will not omit outlines in places where segmentations touch. Lots of different effects are possible!
All of the functions are designed to also work for 3d image stacks. Image and segmentation cutouts will return 3d arrays instead of 2d ones. However, note that composite images will come back as a list of PIL images. An optional dim argument will perform the slicing on axes other than the z-axis, although anisotropy in voxel resolution will not be accounted for.
In order to quickly assemble sequential images into a series, we can stack them. A direction argument will let you specify vertical instead of the default, and spacing can be adjusted as well.
+
ic.stack_images(overlays)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/_variables.yml b/docs/_variables.yml
new file mode 100644
index 0000000..cfd5f95
--- /dev/null
+++ b/docs/_variables.yml
@@ -0,0 +1,4 @@
+urls:
+ kasthuri: https://neuroglancer-demo.appspot.com/#!%7B%22dimensions%22:%7B%22x%22:%5B6.000000000000001e-9%2C%22m%22%5D%2C%22y%22:%5B6.000000000000001e-9%2C%22m%22%5D%2C%22z%22:%5B3.0000000000000004e-8%2C%22m%22%5D%7D%2C%22position%22:%5B5523.99072265625%2C8538.9384765625%2C1198.0423583984375%5D%2C%22projectionOrientation%22:%5B-0.0040475670248270035%2C-0.9566215872764587%2C-0.22688281536102295%2C-0.18271005153656006%5D%2C%22layers%22:%5B%7B%22type%22:%22image%22%2C%22source%22:%22precomputed://gs://neuroglancer-public-data/kasthuri2011/image%22%2C%22tab%22:%22source%22%2C%22name%22:%22original-image%22%2C%22visible%22:false%7D%2C%7B%22type%22:%22image%22%2C%22source%22:%22precomputed://gs://neuroglancer-public-data/kasthuri2011/image_color_corrected%22%2C%22tab%22:%22source%22%2C%22name%22:%22corrected-image%22%7D%2C%7B%22type%22:%22segmentation%22%2C%22source%22:%22precomputed://gs://neuroglancer-public-data/kasthuri2011/ground_truth%22%2C%22tab%22:%22source%22%2C%22selectedAlpha%22:0.63%2C%22notSelectedAlpha%22:0.14%2C%22segments%22:%5B%223208%22%2C%224901%22%2C%2213%22%2C%224965%22%2C%224651%22%2C%222282%22%2C%223189%22%2C%223758%22%2C%2215%22%2C%224027%22%2C%223228%22%2C%22444%22%2C%223207%22%2C%223224%22%2C%223710%22%5D%2C%22name%22:%22ground_truth%22%7D%5D%2C%22layout%22:%224panel%22%7D
+
+version: 1.0.3
\ No newline at end of file
diff --git a/docs/example_images/code_to_picture.png b/docs/example_images/code_to_picture.png
new file mode 100644
index 0000000..21dfab7
Binary files /dev/null and b/docs/example_images/code_to_picture.png differ
diff --git a/docs/example_images/exact_mip_3.png b/docs/example_images/exact_mip_3.png
new file mode 100644
index 0000000..6d93554
Binary files /dev/null and b/docs/example_images/exact_mip_3.png differ
diff --git a/docs/example_images/img_base.png b/docs/example_images/img_base.png
new file mode 100644
index 0000000..4a790d8
Binary files /dev/null and b/docs/example_images/img_base.png differ
diff --git a/docs/example_images/microns_example.png b/docs/example_images/microns_example.png
new file mode 100644
index 0000000..4412431
Binary files /dev/null and b/docs/example_images/microns_example.png differ
diff --git a/docs/example_images/scaled_mip_3.png b/docs/example_images/scaled_mip_3.png
new file mode 100644
index 0000000..bda39ad
Binary files /dev/null and b/docs/example_images/scaled_mip_3.png differ
diff --git a/docs/example_images/seg_base.png b/docs/example_images/seg_base.png
new file mode 100644
index 0000000..a8e6714
Binary files /dev/null and b/docs/example_images/seg_base.png differ
diff --git a/docs/example_images/seg_outline_0.png b/docs/example_images/seg_outline_0.png
new file mode 100644
index 0000000..2583c2d
Binary files /dev/null and b/docs/example_images/seg_outline_0.png differ
diff --git a/docs/example_images/seg_outline_1.png b/docs/example_images/seg_outline_1.png
new file mode 100644
index 0000000..8d4c63c
Binary files /dev/null and b/docs/example_images/seg_outline_1.png differ
diff --git a/docs/example_images/seg_overlay_0.png b/docs/example_images/seg_overlay_0.png
new file mode 100644
index 0000000..02fb197
Binary files /dev/null and b/docs/example_images/seg_overlay_0.png differ
diff --git a/docs/example_images/seg_overlay_1.png b/docs/example_images/seg_overlay_1.png
new file mode 100644
index 0000000..ad09b21
Binary files /dev/null and b/docs/example_images/seg_overlay_1.png differ
diff --git a/docs/example_images/seg_overlay_2.png b/docs/example_images/seg_overlay_2.png
new file mode 100644
index 0000000..9ddfbb7
Binary files /dev/null and b/docs/example_images/seg_overlay_2.png differ
diff --git a/docs/example_images/seg_series_0.png b/docs/example_images/seg_series_0.png
new file mode 100644
index 0000000..5e20735
Binary files /dev/null and b/docs/example_images/seg_series_0.png differ
diff --git a/docs/example_images/seg_series_full.png b/docs/example_images/seg_series_full.png
new file mode 100644
index 0000000..b64797e
Binary files /dev/null and b/docs/example_images/seg_series_full.png differ
diff --git a/docs/example_images/seg_single.png b/docs/example_images/seg_single.png
new file mode 100644
index 0000000..6ff1a7b
Binary files /dev/null and b/docs/example_images/seg_single.png differ
diff --git a/docs/example_images/seg_specific.png b/docs/example_images/seg_specific.png
new file mode 100644
index 0000000..8740434
Binary files /dev/null and b/docs/example_images/seg_specific.png differ
diff --git a/docs/getting_started.qmd b/docs/getting_started.qmd
new file mode 100644
index 0000000..36d4531
--- /dev/null
+++ b/docs/getting_started.qmd
@@ -0,0 +1,50 @@
+---
+title: Getting Started
+---
+
+We make use of [Numpy arrays](https://numpy.org/doc/stable/) and [Pillow Images](https://pillow.readthedocs.io/) to represent data.
+Both are extremely rich tools, and to learn more about them please see the appropriate documentation for information about saving data to image files and more.
+
+## Installation
+
+ImageryClient can be installed with pip:
+
+`pip install imageryclient`
+
+While not required, if you are using a CAVE-hosted dataset, installing [CAVEclient](https://caveclient.readthedocs.io/) will make your life much easier.
+
+::: {.callout-warning}
+## Troubleshooting
+
+If you have installation issues due to Cloudvolume, which can have a complex set of requirements, we recommend looking at its github [issues page](https://github.com/seung-lab/cloud-volume/issues) for help.
+:::
+
+## Basic example
+
+A small example that uses all of the major components of ImageryClient: Downloading aligned images and segmentation, specifying specific segmentations to visualize, and generating an image overlay.
+This uses the pubically available [Kasthuri et al. 2014 dataset]({{< var urls.kasthuri >}}).
+
+```python
+import imageryclient as ic
+
+img_src = 'precomputed://gs://neuroglancer-public-data/kasthuri2011/image_color_corrected'
+seg_src = 'precomputed://gs://neuroglancer-public-data/kasthuri2011/ground_truth'
+
+img_client = ic.ImageryClient(image_source=img_src, segmentation_source=seg_src)
+
+bounds = [
+ [5119, 8477, 1201],
+ [5519, 8877, 1202]
+]
+root_ids = [2282, 4845]
+
+image, segs = img_client.image_and_segmentation_cutout(bounds,
+ split_segmentations=True,
+ root_ids=root_ids)
+
+
+ic.composite_overlay(segs, imagery=image)
+```
+
+![overlay 0](../example_images/seg_overlay_0.png)
+
diff --git a/docs/index.qmd b/docs/index.qmd
new file mode 100644
index 0000000..d583e59
--- /dev/null
+++ b/docs/index.qmd
@@ -0,0 +1,20 @@
+---
+title: "ImageryClient"
+
+about:
+ template: broadside
+ image: example_images/code_to_picture.png
+
+---
+
+Connectomics data often involves a combination of microscopy imagery and segmentation, labels of distinct objects applied to this imagery.
+While exploring the data in tools like [Neuroglancer](https://github.com/google/neuroglancer) is great, a common task is often to make figures overlaying 2d images and segmentation sliced from the larger data.
+ImageryClient is designed to make it easy to generate aligned cutouts from imagery and segmentation, and make it efficient to produce attractive, publication-ready overlay images.
+
+Because of the size of these volumes, cloud-based serverless n-d array file storage systems are often used to host this data.
+[CloudVolume](https://github.com/seung-lab/cloud-volume/) has become an excellent general purpose tool for accessing such data.
+However, imagery and segmentation for the same data are hosted at distinct cloud locations and can differ in basic properties like base resolution.
+Moreover, imagery and segmentation have data that means intrensically different things.
+Values in imagery indicate pixel intensity in order to produce a picture, while values in segmentation indicate the object id at a given location.
+ImageryClient acts as a front end for making aligned cutouts from multiple cloudvolume sources, splitting segmentations into masks for each object, and more.
+
diff --git a/docs/objects.json b/docs/objects.json
new file mode 100644
index 0000000..20afe4a
--- /dev/null
+++ b/docs/objects.json
@@ -0,0 +1 @@
+{"project": "imageryclient", "version": "0.0.9999", "count": 22, "items": [{"name": "imageryclient.imagery.bounds_from_center", "domain": "py", "role": "function", "priority": "1", "uri": "reference/imagery.bounds_from_center.html#imageryclient.imagery.bounds_from_center", "dispname": "-"}, {"name": "imageryclient.imagery.ImageryClient.image_and_segmentation_cutout", "domain": "py", "role": "function", "priority": "1", "uri": "reference/imagery.ImageryClient.html#imageryclient.imagery.ImageryClient.image_and_segmentation_cutout", "dispname": "-"}, {"name": "imageryclient.imagery.ImageryClient.image_bbox_size_from_dimensions", "domain": "py", "role": "function", "priority": "1", "uri": "reference/imagery.ImageryClient.html#imageryclient.imagery.ImageryClient.image_bbox_size_from_dimensions", "dispname": "-"}, {"name": "imageryclient.imagery.ImageryClient.image_cutout", "domain": "py", "role": "function", "priority": "1", "uri": "reference/imagery.ImageryClient.html#imageryclient.imagery.ImageryClient.image_cutout", "dispname": "-"}, {"name": "imageryclient.imagery.ImageryClient.image_cv", "domain": "py", "role": "attribute", "priority": "1", "uri": "reference/imagery.ImageryClient.html#imageryclient.imagery.ImageryClient.image_cv", "dispname": "-"}, {"name": "imageryclient.imagery.ImageryClient.image_source", "domain": "py", "role": "attribute", "priority": "1", "uri": "reference/imagery.ImageryClient.html#imageryclient.imagery.ImageryClient.image_source", "dispname": "-"}, {"name": "imageryclient.imagery.ImageryClient.resolution", "domain": "py", "role": "attribute", "priority": "1", "uri": "reference/imagery.ImageryClient.html#imageryclient.imagery.ImageryClient.resolution", "dispname": "-"}, {"name": "imageryclient.imagery.ImageryClient.save_image_and_segmentation_masks", "domain": "py", "role": "function", "priority": "1", "uri": "reference/imagery.ImageryClient.html#imageryclient.imagery.ImageryClient.save_image_and_segmentation_masks", "dispname": "-"}, {"name": "imageryclient.imagery.ImageryClient.save_imagery", "domain": "py", "role": "function", "priority": "1", "uri": "reference/imagery.ImageryClient.html#imageryclient.imagery.ImageryClient.save_imagery", "dispname": "-"}, {"name": "imageryclient.imagery.ImageryClient.save_segmentation_masks", "domain": "py", "role": "function", "priority": "1", "uri": "reference/imagery.ImageryClient.html#imageryclient.imagery.ImageryClient.save_segmentation_masks", "dispname": "-"}, {"name": "imageryclient.imagery.ImageryClient.segmentation_bbox_size_from_dimensions", "domain": "py", "role": "function", "priority": "1", "uri": "reference/imagery.ImageryClient.html#imageryclient.imagery.ImageryClient.segmentation_bbox_size_from_dimensions", "dispname": "-"}, {"name": "imageryclient.imagery.ImageryClient.segmentation_cutout", "domain": "py", "role": "function", "priority": "1", "uri": "reference/imagery.ImageryClient.html#imageryclient.imagery.ImageryClient.segmentation_cutout", "dispname": "-"}, {"name": "imageryclient.imagery.ImageryClient.segmentation_cv", "domain": "py", "role": "attribute", "priority": "1", "uri": "reference/imagery.ImageryClient.html#imageryclient.imagery.ImageryClient.segmentation_cv", "dispname": "-"}, {"name": "imageryclient.imagery.ImageryClient.segmentation_source", "domain": "py", "role": "attribute", "priority": "1", "uri": "reference/imagery.ImageryClient.html#imageryclient.imagery.ImageryClient.segmentation_source", "dispname": "-"}, {"name": "imageryclient.imagery.ImageryClient.split_segmentation_cutout", "domain": "py", "role": "function", "priority": "1", "uri": "reference/imagery.ImageryClient.html#imageryclient.imagery.ImageryClient.split_segmentation_cutout", "dispname": "-"}, {"name": "imageryclient.imagery.ImageryClient", "domain": "py", "role": "class", "priority": "1", "uri": "reference/imagery.ImageryClient.html#imageryclient.imagery.ImageryClient", "dispname": "-"}, {"name": "imageryclient.composite.stack_images", "domain": "py", "role": "function", "priority": "1", "uri": "reference/composite.stack_images.html#imageryclient.composite.stack_images", "dispname": "-"}, {"name": "imageryclient.composite.composite_overlay", "domain": "py", "role": "function", "priority": "1", "uri": "reference/composite.composite_overlay.html#imageryclient.composite.composite_overlay", "dispname": "-"}, {"name": "imageryclient.utils.rescale_to_bounds", "domain": "py", "role": "function", "priority": "1", "uri": "reference/utils.rescale_to_bounds.html#imageryclient.utils.rescale_to_bounds", "dispname": "-"}, {"name": "imageryclient.utils.binary_seg_outline", "domain": "py", "role": "function", "priority": "1", "uri": "reference/utils.binary_seg_outline.html#imageryclient.utils.binary_seg_outline", "dispname": "-"}, {"name": "imageryclient.utils.mask_image", "domain": "py", "role": "function", "priority": "1", "uri": "reference/utils.mask_image.html#imageryclient.utils.mask_image", "dispname": "-"}, {"name": "imageryclient.utils.segmentation_masks", "domain": "py", "role": "function", "priority": "1", "uri": "reference/utils.segmentation_masks.html#imageryclient.utils.segmentation_masks", "dispname": "-"}]}
\ No newline at end of file
diff --git a/docs/reference/_api_index.qmd b/docs/reference/_api_index.qmd
new file mode 100644
index 0000000..050c142
--- /dev/null
+++ b/docs/reference/_api_index.qmd
@@ -0,0 +1,30 @@
+# {.doc .doc-index}
+
+## ImageryClient
+
+Main functions for downloading imagery and segmentation data.
+
+| | |
+| --- | --- |
+| [imagery.bounds_from_center](imagery.bounds_from_center.qmd#imageryclient.imagery.bounds_from_center) | Generate bounds from a center point and dimensions for each direction |
+| [imagery.ImageryClient](imagery.ImageryClient.qmd#imageryclient.imagery.ImageryClient) | Tool to help download imagery and segmentation data. |
+
+## Compositing
+
+Functions for generating overlay visualizations of images and segmentation.
+
+| | |
+| --- | --- |
+| [composite.stack_images](composite.stack_images.qmd#imageryclient.composite.stack_images) | Stack an iterable of images either veritcally or horizontally |
+| [composite.composite_overlay](composite.composite_overlay.qmd#imageryclient.composite.composite_overlay) | Make a colored composite overlay for a 3d mask from an iterable of masks. |
+
+## Utilities
+
+Additional utility functions for working with imagery and segmentation data.
+
+| | |
+| --- | --- |
+| [utils.rescale_to_bounds](utils.rescale_to_bounds.qmd#imageryclient.utils.rescale_to_bounds) | |
+| [utils.binary_seg_outline](utils.binary_seg_outline.qmd#imageryclient.utils.binary_seg_outline) | Convert a 2d image segmentation to a binary outline inside or outside the segmentation |
+| [utils.mask_image](utils.mask_image.qmd#imageryclient.utils.mask_image) | Apply mask as a a transparency layer to seg |
+| [utils.segmentation_masks](utils.segmentation_masks.qmd#imageryclient.utils.segmentation_masks) | Convert a segmentation array into a dict of binary masks for each root id. |
\ No newline at end of file
diff --git a/docs/reference/composite.composite_overlay.qmd b/docs/reference/composite.composite_overlay.qmd
new file mode 100644
index 0000000..2ab8306
--- /dev/null
+++ b/docs/reference/composite.composite_overlay.qmd
@@ -0,0 +1,26 @@
+# composite.composite_overlay { #imageryclient.composite.composite_overlay }
+
+`composite.composite_overlay(segs, colors=None, alpha=0.2, imagery=None, outline=False, merge_outline=True, overlap=True, width=10, side='out', dim=2, palette=DEFAULT_PALETTE, h=DEFAULT_H, l=DEFAULT_L, s=DEFAULT_S)`
+
+Make a colored composite overlay for a 3d mask from an iterable of masks.
+
+## Parameters
+
+| Name | Type | Description | Default |
+|-----------------|---------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|------------|
+| `segs` | | Iterable of masked images of the same size. If a dict, colors must be a dict as well. | _required_ |
+| `colors` | list-like, dict, or None | Iterable of RGB colors of the same size as masks. If a dict, masks must also be a dict and colors must have all keys in masks. If None, uses `discrete_colors` to generate colors. | `None` |
+| `alpha` | float | Alpha value for the overlay | `0.2` |
+| `imagery` | PIL.PIL.Image.PIL.Image.Image or None | If an Image, applies the overlay to the image, by default None | `None` |
+| `outline` | bool | If True, produces an outline instead of a flat overay, by default False | `False` |
+| `merge_outline` | bool | If True, the merge outline applies to the segmentation as a whole and thus internal contacts are not outlined. | `True` |
+| `overlap` | bool | If False, segmentations later in the list will not overlap segmentations earlier on the list. | `True` |
+| `width` | int | If outline=True, sets the width of the outline, by default 10 | `10` |
+| `side` | out or 'in' | If outline=True, selects if the outline is inside or outside the original segmentation mask, by default 'out' | `'out'` |
+| `dim` | int | Determines axis over which slices are iterated if the data is 3 dimensional. Default is 2 (z-axis). | `2` |
+
+## Returns
+
+| Type | Description |
+|---------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+| list or PIL.PIL.Image.PIL.Image.Image | Image or list of composite overlay images, optionally overlaid over provided imagery. List or single image is determined based on segmentation arrays being 2 or 3 dimensional. |
\ No newline at end of file
diff --git a/docs/reference/composite.discrete_colors.qmd b/docs/reference/composite.discrete_colors.qmd
new file mode 100644
index 0000000..e6ae398
--- /dev/null
+++ b/docs/reference/composite.discrete_colors.qmd
@@ -0,0 +1,23 @@
+# composite.discrete_colors { #imageryclient.composite.discrete_colors }
+
+`composite.discrete_colors(segs, palette=DEFAULT_PALETTE, h=DEFAULT_H, l=DEFAULT_L, s=DEFAULT_S)`
+
+Generate discrete colors for segmentations from a palette
+generator. Defaults to perceptually uniform differences with
+high saturation.
+
+## Parameters
+
+| Name | Type | Description | Default |
+|-----------|-----------------------|-----------------------------------------------------------------------------------------------------------------|-------------------|
+| `segs` | list or dict | Dict or list of segmentations to provide colors for. | _required_ |
+| `palette` | 'husl', 'hls', or str | Which palette system to use, by default 'husl'. Will accept anything allowed by seaborn color_palette function. | `DEFAULT_PALETTE` |
+| `h` | float | Hue value if husl or hls palettes are used, by default 0.01 | `DEFAULT_H` |
+| `l` | float | Lightness if husl or hls palettes are used, by default 0.6 | `DEFAULT_L` |
+| `s` | int | Saturation if husl or hls palettes are used, by default 1 | `DEFAULT_S` |
+
+## Returns
+
+| Type | Description |
+|--------------|-----------------------------------------------|
+| List or dict | List or dict with one color per segmentation. |
\ No newline at end of file
diff --git a/docs/reference/composite.stack_images.qmd b/docs/reference/composite.stack_images.qmd
new file mode 100644
index 0000000..20851bc
--- /dev/null
+++ b/docs/reference/composite.stack_images.qmd
@@ -0,0 +1,19 @@
+# composite.stack_images { #imageryclient.composite.stack_images }
+
+`composite.stack_images(images, direction='horizontal', spacing=10)`
+
+Stack an iterable of images either veritcally or horizontally
+
+## Parameters
+
+| Name | Type | Description | Default |
+|-------------|------------------------|----------------------------------------------------------|----------------|
+| `images` | list - like | Iterable of Image.Image objects | _required_ |
+| `spacing` | int | Spacing between images in pixels, by default 10 | `10` |
+| `direction` | horizontal or vertical | Direction of the grid of images, by default 'horizontal' | `'horizontal'` |
+
+## Returns
+
+| Type | Description |
+|---------------------------|-------------------------|
+| PIL.Image.PIL.Image.Image | Combined grid of images |
\ No newline at end of file
diff --git a/docs/reference/imagery.ImageryClient.qmd b/docs/reference/imagery.ImageryClient.qmd
new file mode 100644
index 0000000..dbe75bf
--- /dev/null
+++ b/docs/reference/imagery.ImageryClient.qmd
@@ -0,0 +1,263 @@
+# imagery.ImageryClient { #imageryclient.imagery.ImageryClient }
+
+`imagery.ImageryClient(self, client=None, resolution=None, segmentation=True, imagery=True, image_source=None, segmentation_source=None, image_mip=None, segmentation_mip=None, auth_token=None, timestamp=None)`
+
+Tool to help download imagery and segmentation data.
+
+Can either take explicit cloudvolume paths for imagery and segmentation or use the Info Service to look up the right paths.
+
+## Parameters
+
+| Name | Type | Description | Default |
+|-----------------------|------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------|-----------|
+| `client` | caveclient.caveclient.CAVEclient or None | A pre-initialized CAVEclient to use for configuration. If used, the image source and segmentation source come from the info service values. | `None` |
+| `resolution` | array - like or image or segmentation | Sets the voxel resolution that bounds will be entered in, by default 'image', which is the mip 0 resolution of the imagery. | `None` |
+| `segmentation` | bool | If False, no segmentation cloudvolume is initialized. By default True | `True` |
+| `imagery` | bool | If False, no imagery cloudvolume is initialized. By default True | `True` |
+| `image_source` | str | CloudVolume path to an imagery source, by default None | `None` |
+| `segmentation_source` | str | CloudVolume path to a segmentation source, by default None | `None` |
+| `image_mip` | int | Default mip level to use for imagery lookups, by default 0. Note that the same mip level for imagery and segmentation can correspond to different voxel resolutions. | `None` |
+| `segmentation_mip` | int | Default mip level to use for segmentation lookups, by default 0. | `None` |
+| `auth_token` | str or None | Auth token to use for cloudvolume. If None, uses the default values from the CAVEclient. Default is None. | `None` |
+| `timestamp` | (datetime.datetime.datetime or None) | Fixed timestamp to use for segmentation lookups. If None, defaults to the present time when each function is run. Default is None. | `None` |
+
+## Attributes
+
+| Name | Description |
+| --- | --- |
+| [image_cv](#imageryclient.imagery.ImageryClient.image_cv) | Imagery CloudVolume |
+| [image_source](#imageryclient.imagery.ImageryClient.image_source) | Image cloudpath |
+| [resolution](#imageryclient.imagery.ImageryClient.resolution) | The voxel resolution assumed when locations are used for the client. |
+| [segmentation_cv](#imageryclient.imagery.ImageryClient.segmentation_cv) | Segmentation CloudVolume object |
+| [segmentation_source](#imageryclient.imagery.ImageryClient.segmentation_source) | Segmentation cloudpath |
+
+## Methods
+
+| Name | Description |
+| --- | --- |
+| [image_and_segmentation_cutout](#imageryclient.imagery.ImageryClient.image_and_segmentation_cutout) | Download aligned and scaled imagery and segmentation data at a given resolution. |
+| [image_bbox_size_from_dimensions](#imageryclient.imagery.ImageryClient.image_bbox_size_from_dimensions) | Get the bbox_size equivalent for an imagery cutout with specified pixel dimensions |
+| [image_cutout](#imageryclient.imagery.ImageryClient.image_cutout) | Get an image cutout for a certain location or set of bounds and a mip level. |
+| [save_image_and_segmentation_masks](#imageryclient.imagery.ImageryClient.save_image_and_segmentation_masks) | Save aligned and scaled imagery and segmentation mask cutouts as pngs. Kwargs are passed to imageio.imwrite. |
+| [save_imagery](#imageryclient.imagery.ImageryClient.save_imagery) | Save queried or precomputed imagery to png files. |
+| [save_segmentation_masks](#imageryclient.imagery.ImageryClient.save_segmentation_masks) | Save queried or precomputed segmentation masks to png files. Additional kwargs are passed to imageio.imwrite. |
+| [segmentation_bbox_size_from_dimensions](#imageryclient.imagery.ImageryClient.segmentation_bbox_size_from_dimensions) | Get the bbox_size equivalent for an segmentation cutout with specified pixel dimensions |
+| [segmentation_cutout](#imageryclient.imagery.ImageryClient.segmentation_cutout) | Get a cutout of the segmentation imagery for some or all root ids between set bounds. |
+| [split_segmentation_cutout](#imageryclient.imagery.ImageryClient.split_segmentation_cutout) | Generate segmentation cutouts with a single binary mask for each root id, organized as a dict with keys as root ids and masks as values. |
+
+## image_and_segmentation_cutout { #imageryclient.imagery.ImageryClient.image_and_segmentation_cutout }
+
+`imagery.ImageryClient.image_and_segmentation_cutout(bounds, image_mip=None, segmentation_mip=None, root_ids='all', resize=True, split_segmentations=False, include_null_root=False, bbox_size=None, resolution=None, timestamp=None, scale_to_bounds=None, convert_to_int64=True)`
+
+Download aligned and scaled imagery and segmentation data at a given resolution.
+
+### Parameters
+
+| Name | Type | Description | Default |
+|-----------------------|----------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|------------|
+| `bounds` | 2x3 list of ints | A list of the lower and upper bound point for the cutout. The units are voxels in the resolution set by the base_resolution parameter. | _required_ |
+| `image_mip` | int | Mip level of the imagery if something other than the default is wanted, by default None | `None` |
+| `segmentation_mip` | int | Mip level of the segmentation if something other than the default is wanted, by default None | `None` |
+| `root_ids` | list, None, or 'all' | If a list, the segmentation cutout only includes voxels for a specified set of root ids. If None, default to the supervoxel ids. If 'all', finds all root ids corresponding to the supervoxels in the cutout and get all of them. By default 'all'. | `'all'` |
+| `resize` | bool | If True, upscale the lower resolution cutout to the same resolution of the higher one (either imagery or segmentation). | `True` |
+| `split_segmentations` | bool | If True, the segmentation is returned as a dict of masks (using split_segmentation_cutout), and if False returned as an array with root_ids (using segmentation_cutout), by default False | `False` |
+| `include_null_root` | bool | If True, includes root id of 0, which is usually reserved for a null segmentation value. Default is False. | `False` |
+| `bbox_size` | array or None | If not None, bbox_size is a 3 element array of ints giving the dimensions of the cutout. In this case, bounds is treated as the center. | `None` |
+| `resolution` | list - like | Voxel resolution used when specifying bounds bounds and bbox_size (but not image_size). If none, defaults to client default. | `None` |
+| `timestamp` | datetime or None | Timestamp to use for dynamic segmentation data | `None` |
+| `scale_to_bounds` | bool or None | If True, rescales image to the same size as the bounds. Default is None, which rescales if mip is not set but otherwise does not. | `None` |
+| `convert_to_int64` | bool | If True, converts segmentation data to int64 from uint64 if it is safe to do so. Default is True. If not safe, raises a warning and does not convert from uint64. | `True` |
+
+### Returns
+
+| Type | Description |
+|--------------------------------------|-------------------------------------------------------------------------------------------------------------|
+| cloudvolume.cloudvolume.VolumeCutout | Imagery volume cutout |
+| numpy.numpy.ndarray or dict | Segmentation volume cutout as either an ndarray or dict of masks depending on the split_segmentations flag. |
+
+## image_bbox_size_from_dimensions { #imageryclient.imagery.ImageryClient.image_bbox_size_from_dimensions }
+
+`imagery.ImageryClient.image_bbox_size_from_dimensions(image_size, mip=None, resolution=None)`
+
+Get the bbox_size equivalent for an imagery cutout with specified pixel dimensions
+
+### Parameters
+
+| Name | Type | Description | Default |
+|--------------|--------|---------------------------------------------------------------------------------------------|------------|
+| `image_size` | | Image size in pixels (2-element) or voxels (3-element) | _required_ |
+| `mip` | | Mip for which the image would be computed. Defaults to None, which uses the client default. | `None` |
+| `resolution` | | Resolution to use for the bbox_size. Defaults to None, or the client defauls. | `None` |
+
+### Returns
+
+| Type | Description |
+|--------|----------------------------------------------------------------------|
+| | Argument for bbox_size that would give the desired pixel dimensions. |
+
+## image_cutout { #imageryclient.imagery.ImageryClient.image_cutout }
+
+`imagery.ImageryClient.image_cutout(bounds, bbox_size=None, image_size=None, mip=None, resolution=None, scale_to_bounds=None)`
+
+Get an image cutout for a certain location or set of bounds and a mip level.
+
+### Parameters
+
+| Name | Type | Description | Default |
+|-------------------|-----------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|------------|
+| `bounds` | array | Either a 2x3 array of a lower bound and upper bound point to bound the cutout in units of voxels in a resolution set by the base_resolution parameter. Alternatively, if bbox_size or image_size is set, bounds should be a 3-element array specifying the center of the field of view. | _required_ |
+| `bbox_size` | array or None | If not None, bbox_size is a 3 element array of ints giving the dimensions. In this case, bounds is treated as the center. | `None` |
+| `image_size` | array or None | If not None, indicates the size of the image desired in pixels. Cannot be set with bbox_size, since it has potentially conficting information. | `None` |
+| `mip` | int | Mip level of imagery to get if something other than the default is wanted, by default None. | `None` |
+| `resolution` | list - like | Voxel resolution used when specifying bounds bounds and bbox_size (but not image_size). If none, defaults to client default. | `None` |
+| `scale_to_bounds` | bool, optional. | If True, rescales image to the same size as the bounds. Default is None, which rescales if mip is not set but otherwise does not. | `None` |
+
+### Returns
+
+| Type | Description |
+|--------------------------|----------------------------------------------------------------------------------|
+| cloudvolume.VolumeCutout | An n-d image of the image requested with image intensity values as the elements. |
+
+## save_image_and_segmentation_masks { #imageryclient.imagery.ImageryClient.save_image_and_segmentation_masks }
+
+`imagery.ImageryClient.save_image_and_segmentation_masks(filename_prefix, bounds=None, image_mip=None, segmentation_mip=None, root_ids='all', include_null_root=False, segmentation_colormap={}, resize=True, precomputed_data=None, slice_axis=2, bbox_size=None, resolution=None, timestamp=None, scale_to_bounds=None, **kwargs)`
+
+Save aligned and scaled imagery and segmentation mask cutouts as pngs. Kwargs are passed to imageio.imwrite.
+
+### Parameters
+
+| Name | Type | Description | Default |
+|-------------------------|----------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|------------|
+| `filename_prefix` | str | Prefix for the segmentation filenames. The full filename will be either {filename_prefix}_root_id_{root_id}.png or {filename_prefix}_root_id_{root_id}_{i}.png, depending on if multiple slices of each root id are saved. | _required_ |
+| `bounds` | 2x3 list of ints | A list of the lower and upper bound point for the cutout. The units are voxels in the resolution set by the base_resolution parameter. Only used if a precomputed data is not passed. By default, None. | `None` |
+| `image_mip` | int | Only used if a precomputed data is not passed. Mip level of imagery to get if something other than the default is wanted, by default None. | `None` |
+| `segmentation_mip` | int | Only used if precomputed data is not passed. Mip level of segmentation to get if something other than the default is wanted, by default None | `None` |
+| `root_ids` | list, None, or 'all' | If a list, the segmentation cutout only includes voxels for a specified set of root ids. If None, default to the supervoxel ids. If 'all', finds all root ids corresponding to the supervoxels in the cutout and get all of them. By default 'all'. | `'all'` |
+| `include_null_root` | bool | If True, includes root id of 0, which is usually reserved for a null segmentation value. By default, False. | `False` |
+| `segmentation_colormap` | dict | A dict of root ids to an uint8 RGB color triplet (0-255) or RGBa quadrooplet to optionally color the mask png. Any root id not specified will be rendered in white. Color triplets default to full opacity. Default is an empty dictionary. | `{}` |
+| `resize` | bool | If True, upscale the lower resolution cutout to the same resolution of the higher one (either imagery or segmentation). | `True` |
+| `precomputed_data` | tuple | Already computed tuple with imagery and segmentation mask data, in that order. If not provided, bounds must be given to download cutout data. By default, None. | `None` |
+| `slice_axis` | int | If the image data is truly 3 dimensional, determines which axis to use to save serial images, by default 2 (i.e. z-axis) | `2` |
+| `bbox_size` | array or None | If not None, bbox_size is a 3 element array of ints giving the dimensions of the cutout. In this case, bounds is treated as the center. | `None` |
+| `resolution` | list - like | Voxel resolution of the bounds provided. If not provided, uses the client defaults. | `None` |
+| `timestamp` | datetime | Timestamp to use for the segmentation. If not provided, defaults to the client defaults. | `None` |
+| `scale_to_bounds` | bool or None | If True, rescales image to the same size as the bounds. Default is None, which rescales if mip is not set but otherwise does not. | `None` |
+
+## save_imagery { #imageryclient.imagery.ImageryClient.save_imagery }
+
+`imagery.ImageryClient.save_imagery(filename_prefix, bounds=None, mip=None, precomputed_image=None, slice_axis=2, bbox_size=None, image_size=None, resolution=None, scale_to_bounds=None, verbose=False, **kwargs)`
+
+Save queried or precomputed imagery to png files.
+
+### Parameters
+
+| Name | Type | Description | Default |
+|---------------------|--------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|------------|
+| `filename_prefix` | str | Prefix for the imagery filename. The full filename will be {filename_prefix}_imagery.png | _required_ |
+| `bounds` | 2x3 list of ints | A list of the lower and upper bound point for the cutout. The units are voxels in the resolution set by the base_resolution parameter. Only used if a precomputed image is not passed. By default, None. | `None` |
+| `mip` | int | Only used if a precomputed image is not passed. Mip level of imagery to get if something other than the default is wanted, by default None | `None` |
+| `precomputed_image` | cloudvolume.cloudvolume.VolumeCutout | Already downloaded VolumeCutout data to save explicitly. If called this way, the bounds and mip arguments will not apply. If a precomputed image is not provided, bounds must be specified to download the cutout data. By default None | `None` |
+| `slice_axis` | int | If the image data is truly 3 dimensional, determines which axis to use to save serial images, by default 2 (i.e. z-axis) | `2` |
+| `bbox_size` | array or None | If not None, bbox_size is a 3 element array of ints giving the dimensions of the cutout. In this case, bounds is treated as the center. | `None` |
+| `image_size` | array or None | If not None, indicates the size of the image desired in pixels. Cannot be set with bbox_size, since it has potentially conficting information. | `None` |
+| `resolution` | list - like | Voxel resolution used when specifying bounds bounds and bbox_size (but not image_size). If none, defaults to client default. | `None` |
+| `scale_to_bounds` | bool or None | If True, rescales image to the same size as the bounds. Default is None, which rescales if mip is not set but otherwise does not. | `None` |
+| `verbose` | bool | If True, prints the progress, by default False | `False` |
+
+## save_segmentation_masks { #imageryclient.imagery.ImageryClient.save_segmentation_masks }
+
+`imagery.ImageryClient.save_segmentation_masks(filename_prefix, bounds=None, mip=None, root_ids='all', precomputed_masks=None, segmentation_colormap={}, slice_axis=2, include_null_root=False, bbox_size=None, image_size=None, resolution=None, timestamp=None, scale_to_bounds=None, verbose=False, **kwargs)`
+
+Save queried or precomputed segmentation masks to png files. Additional kwargs are passed to imageio.imwrite.
+
+### Parameters
+
+| Name | Type | Description | Default |
+|-------------------------|----------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|------------|
+| `filename_prefix` | str | Prefix for the segmentation filenames. The full filename will be either {filename_prefix}_root_id_{root_id}.png or {filename_prefix}_root_id_{root_id}_{i}.png, depending on if multiple slices of each root id are saved. | _required_ |
+| `bounds` | 2x3 list of ints | A list of the lower and upper bound point for the cutout. The units are voxels in the resolution specified. Only used if a precomputed segmentation is not passed. By default, None. | `None` |
+| `mip` | int | Only used if a precomputed segmentation is not passed. Mip level of segmentation to get if something other than the default is wanted, by default None | `None` |
+| `root_ids` | list, None, or 'all' | If a list, the segmentation cutout only includes voxels for a specified set of root ids. If None, default to the supervoxel ids. If 'all', finds all root ids corresponding to the supervoxels in the cutout and get all of them. By default 'all'. | `'all'` |
+| `precomputed_masks` | dict | Already downloaded dict of mask data to save explicitly. If called this way, the bounds and mip arguments will not apply. If precomputed_masks are not provided, bounds must be given to download cutout data. By default None | `None` |
+| `segmentation_colormap` | dict | A dict of root ids to an uint8 RGB color triplet (0-255) or RGBa quadrooplet to optionally color the mask png. Any root id not specified will be rendered in white. Color triplets default to full opacity. Default is an empty dictionary. | `{}` |
+| `slice_axis` | int | If the image data is truly 3 dimensional, determines which axis to use to save serial images, by default 2 (i.e. z-axis) | `2` |
+| `include_null_root` | bool | If True, includes root id of 0, which is usually reserved for a null segmentation value. Default is False. | `False` |
+| `bbox_size` | array or None | If not None, bbox_size is a 3 element array of ints giving the dimensions of the cutout. In this case, bounds is treated as the center. | `None` |
+| `image_size` | array or None | If not None, indicates the size of the image desired in pixels. Cannot be set with bbox_size, since it has potentially conficting information. | `None` |
+| `resolution` | list - like | Voxel resolution used when specifying bounds bounds and bbox_size (but not image_size). If none, defaults to client default. | `None` |
+| `timestamp` | datetime or None | Timestamp to use for dynamic segmentation data | `None` |
+| `scale_to_bounds` | bool or None | If True, rescales image to the same size as the bounds. Default is None, which rescales if mip is not set but otherwise does not. | `None` |
+
+## segmentation_bbox_size_from_dimensions { #imageryclient.imagery.ImageryClient.segmentation_bbox_size_from_dimensions }
+
+`imagery.ImageryClient.segmentation_bbox_size_from_dimensions(image_size, mip=None, resolution=None)`
+
+Get the bbox_size equivalent for an segmentation cutout with specified pixel dimensions
+
+### Parameters
+
+| Name | Type | Description | Default |
+|--------------|--------|---------------------------------------------------------------------------------------------|------------|
+| `image_size` | | Image size in pixels (2-element) or voxels (3-element) | _required_ |
+| `mip` | | Mip for which the image would be computed. Defaults to None, which uses the client default. | `None` |
+| `resolution` | | Resolution to use for the bbox_size. Defaults to None, or the client defauls. | `None` |
+
+### Returns
+
+| Type | Description |
+|--------|----------------------------------------------------------------------|
+| | Argument for bbox_size that would give the desired pixel dimensions. |
+
+## segmentation_cutout { #imageryclient.imagery.ImageryClient.segmentation_cutout }
+
+`imagery.ImageryClient.segmentation_cutout(bounds, root_ids='all', bbox_size=None, image_size=None, mip=None, resolution=None, timestamp=None, scale_to_bounds=None, convert_to_int64=True)`
+
+Get a cutout of the segmentation imagery for some or all root ids between set bounds.
+Note that if all root ids are requested in a large region, it could take a long time to query
+all supervoxels.
+
+### Parameters
+
+| Name | Type | Description | Default |
+|--------------------|----------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|------------|
+| `bounds` | 2x3 list of ints | A list of the lower and upper bound point for the cutout. The units are voxels in the resolution set by the base_resolution parameter. | _required_ |
+| `root_ids` | list, None, or 'all' | If a list, only compute the voxels for a specified set of root ids. If None, default to the supervoxel ids. If 'all', find all root ids corresponding to the supervoxels in the cutout and get all of them. None, by default 'all' | `'all'` |
+| `bbox_size` | array or None | If not None, bbox_size is a 3 element array of ints giving the dimensions. In this case, bounds is treated as the center. | `None` |
+| `image_size` | array or None | If not None, indicates the size of the image desired in pixels. Cannot be set with bbox_size, since it has potentially conficting information. | `None` |
+| `mip` | int | Mip level of the segmentation if something other than the defualt is wanted, by default None | `None` |
+| `resolution` | list - like | Voxel resolution used when specifying bounds bounds and bbox_size (but not image_size). If none, defaults to client default. | `None` |
+| `timestamp` | datetime or None | Timestamp to use for dynamic segmentation data | `None` |
+| `scale_to_bounds` | bool or None | If True, rescales image to the same size as the bounds. Default is None, which rescales if mip is not set but otherwise does not. | `None` |
+| `convert_to_int64` | bool | If True, converts segmentation data to int64 from uint64 if it is safe to do so. Default is True. If not safe, raises a warning and does not convert from uint64. | `True` |
+
+### Returns
+
+| Type | Description |
+|---------------------|---------------------------------------------------------------------------------------------------------|
+| numpy.numpy.ndarray | Array whose elements correspond to the root id (or, if root_ids=None, the supervoxel id) at each voxel. |
+
+## split_segmentation_cutout { #imageryclient.imagery.ImageryClient.split_segmentation_cutout }
+
+`imagery.ImageryClient.split_segmentation_cutout(bounds, root_ids='all', include_null_root=False, bbox_size=None, image_size=None, mip=None, resolution=None, timestamp=None, scale_to_bounds=None)`
+
+Generate segmentation cutouts with a single binary mask for each root id, organized as a dict with keys as root ids and masks as values.
+
+### Parameters
+
+| Name | Type | Description | Default |
+|---------------------|----------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|------------|
+| `bounds` | 2x3 list of ints | A list of the lower and upper bound point for the cutout. The units are voxels in the resolution set by the base_resolution parameter. | _required_ |
+| `root_ids` | list, None, or 'all' | If a list, only compute the voxels for a specified set of root ids. If None, default to the supervoxel ids. If 'all', find all root ids corresponding to the supervoxels in the cutout and get all of them. None, by default 'all' | `'all'` |
+| `include_null_root` | bool | If True, includes root id of 0, which is usually reserved for a null segmentation value. Default is False. | `False` |
+| `bbox_size` | array or None | If not None, bbox_size is a 3 element array of ints giving the dimensions. In this case, bounds is treated as the center. | `None` |
+| `image_size` | array or None | If not None, indicates the size of the image desired in pixels. Cannot be set with bbox_size, since it has potentially conficting information. | `None` |
+| `mip` | int | Mip level of the segmentation if something other than the default is wanted, by default None | `None` |
+| `resolution` | list - like | Voxel resolution used when specifying bounds bounds and bbox_size (but not image_size). If none, defaults to client default. | `None` |
+| `timestamp` | datetime or None | Timestamp to use for dynamic segmentation data | `None` |
+| `scale_to_bounds` | bool or None | If True, rescales image to the same size as the bounds. Default is None, which rescales if mip is not set but otherwise does not. | `None` |
+
+### Returns
+
+| Type | Description |
+|--------|-----------------------------------------------------------------------------------------------------------------------------------|
+| dict | Dict whose keys are root ids and whose values are the binary mask for that root id, with a 1 where the object contains the voxel. |
\ No newline at end of file
diff --git a/docs/reference/imagery.bounds_from_center.qmd b/docs/reference/imagery.bounds_from_center.qmd
new file mode 100644
index 0000000..c92e6e7
--- /dev/null
+++ b/docs/reference/imagery.bounds_from_center.qmd
@@ -0,0 +1,20 @@
+# imagery.bounds_from_center { #imageryclient.imagery.bounds_from_center }
+
+`imagery.bounds_from_center(ctr, width=1, height=1, depth=1)`
+
+Generate bounds from a center point and dimensions for each direction
+
+## Parameters
+
+| Name | Type | Description | Default |
+|----------|--------------|--------------------------------------------------------------------|------------|
+| `ctr` | array - like | x,y,z coordinates of the center of the bounds in voxel dimensions. | _required_ |
+| `width` | | Width of the box in the x direction in. Default is 1. | `1` |
+| `height` | | Height of the box in the y direction. Default is 1. | `1` |
+| `depth` | | Depth of the box in the z direction. Default is 1. | `1` |
+
+## Returns
+
+| Type | Description |
+|--------|------------------------------------------------------|
+| array | 2x3 array of lower and upper bounds (in that order). |
\ No newline at end of file
diff --git a/docs/reference/imagery.save_image_slices.qmd b/docs/reference/imagery.save_image_slices.qmd
new file mode 100644
index 0000000..4078b26
--- /dev/null
+++ b/docs/reference/imagery.save_image_slices.qmd
@@ -0,0 +1,5 @@
+# imagery.save_image_slices { #imageryclient.imagery.save_image_slices }
+
+`imagery.save_image_slices(filename_prefix, filename_suffix, img, slice_axis, image_type, verbose=False, color=None, **kwargs)`
+
+Helper function for generic image saving
\ No newline at end of file
diff --git a/docs/reference/index.qmd b/docs/reference/index.qmd
new file mode 100644
index 0000000..9b86d92
--- /dev/null
+++ b/docs/reference/index.qmd
@@ -0,0 +1,18 @@
+---
+name: Function Reference Intro
+---
+
+# Function Reference
+This site provides basic documentation for the functions in `ImageryClient`.
+Please see the [tutorials](../tutorials/index.qmd) for more information about how to use them.
+
+Documentation is split into three parts:
+
+* `ImageryClient` for using the ImageryClient class to download images and segmentation.
+* `Compositing` for generating segmentation overlays for visualization.
+* `Utilities` has additional utilities that may be useful for data manipulation.
+ Note that, unlike the other two categories, these functions are not imported by default.
+
+---
+
+{{< include /reference/_api_index.qmd >}}
\ No newline at end of file
diff --git a/docs/reference/utils.binary_seg_outline.qmd b/docs/reference/utils.binary_seg_outline.qmd
new file mode 100644
index 0000000..092354c
--- /dev/null
+++ b/docs/reference/utils.binary_seg_outline.qmd
@@ -0,0 +1,21 @@
+# utils.binary_seg_outline { #imageryclient.utils.binary_seg_outline }
+
+`utils.binary_seg_outline(seg, width, side='out', color=None, alpha=1)`
+
+Convert a 2d image segmentation to a binary outline inside or outside the segmentation
+
+## Parameters
+
+| Name | Type | Description | Default |
+|---------|--------------------|-------------------------------------------------------------|------------|
+| `seg` | PIL image or array | one-channel PIL Image or 2d array representing image values | _required_ |
+| `width` | int | Width of outline in pixels | _required_ |
+| `side` | out or 'in' | Whether outline is inside or outside the segmentation mask | `'out'` |
+| `color` | list or None | RGB color for masked values (0-255) or None for white. | `None` |
+| `alpha` | float | 0-1 value for transparency. | `1` |
+
+## Returns
+
+| Type | Description |
+|-------------------------------|--------------------|
+| PIL.PIL.Image.PIL.Image.Image | Image with outline |
\ No newline at end of file
diff --git a/docs/reference/utils.mask_image.qmd b/docs/reference/utils.mask_image.qmd
new file mode 100644
index 0000000..03e8d49
--- /dev/null
+++ b/docs/reference/utils.mask_image.qmd
@@ -0,0 +1,18 @@
+# utils.mask_image { #imageryclient.utils.mask_image }
+
+`utils.mask_image(seg, mask)`
+
+Apply mask as a a transparency layer to seg
+
+## Parameters
+
+| Name | Type | Description | Default |
+|--------|---------------------------|-----------------------------------------------------------------------------------------------------------------------|------------|
+| `seg` | PIL.Image.PIL.Image.Image | RGBa image. | _required_ |
+| `mask` | numpy.numpy.ndarray | Mask with the same number of pixels as the RGBa image. Note that the mask is transposed relative to the image pixels. | _required_ |
+
+## Returns
+
+| Type | Description |
+|---------------------------|----------------------------------------------------------------------|
+| PIL.Image.PIL.Image.Image | Original segmentation with the mask values set be fully transparent. |
\ No newline at end of file
diff --git a/docs/reference/utils.rescale_to_bounds.qmd b/docs/reference/utils.rescale_to_bounds.qmd
new file mode 100644
index 0000000..ea40c9e
--- /dev/null
+++ b/docs/reference/utils.rescale_to_bounds.qmd
@@ -0,0 +1,4 @@
+# utils.rescale_to_bounds { #imageryclient.utils.rescale_to_bounds }
+
+`utils.rescale_to_bounds(img, bbox)`
+
diff --git a/docs/reference/utils.segmentation_masks.qmd b/docs/reference/utils.segmentation_masks.qmd
new file mode 100644
index 0000000..a1801a7
--- /dev/null
+++ b/docs/reference/utils.segmentation_masks.qmd
@@ -0,0 +1,18 @@
+# utils.segmentation_masks { #imageryclient.utils.segmentation_masks }
+
+`utils.segmentation_masks(seg_img, include_null_root=False)`
+
+Convert a segmentation array into a dict of binary masks for each root id.
+
+## Parameters
+
+| Name | Type | Description | Default |
+|---------------------|---------------------|---------------------------------------------------------------------------|------------|
+| `seg_img` | numpy.numpy.ndarray | Array with voxel values corresponding to the object id at that voxel | _required_ |
+| `include_null_root` | bool | Create a mask for 0 id, which usually denotes no object, by default False | `False` |
+
+## Returns
+
+| Type | Description |
+|--------|-------------------------------------------------------------------------------------------------------|
+| dict | Dict of binary masks. Keys are root ids, values are boolean n-d arrays with a 1 where that object is. |
\ No newline at end of file
diff --git a/docs/tutorials/images.qmd b/docs/tutorials/images.qmd
new file mode 100644
index 0000000..ef8a78e
--- /dev/null
+++ b/docs/tutorials/images.qmd
@@ -0,0 +1,181 @@
+---
+title: Using ImageryClient
+toc: true
+---
+
+Here, we will use the ImageryClient to get some data from the [Kasthuri et al. 2014 dataset]({{< var urls.kasthuri >}}) hosted by Google.
+In its simplest form, we just intialize an ImageryClient object with an image cloudpath and a segmentation cloudpath.
+Values are taken from the layers in the linked neuroglancer state.
+
+```python
+import imageryclient as ic
+
+img_src = 'precomputed://gs://neuroglancer-public-data/kasthuri2011/image_color_corrected'
+seg_src = 'precomputed://gs://neuroglancer-public-data/kasthuri2011/ground_truth'
+
+img_client = ic.ImageryClient(image_source=img_src, segmentation_source=seg_src)
+```
+
+### Imagery cutouts
+
+Cutouts are defined by their bounds, which can be specified by providing bounds.
+The most direct form is a pair of points representing the upper and lower corners of the bounding box.
+By default, coordinates are in the default resolution of the imagery as you would see in neuroglancer.
+
+```python
+bounds = [
+ [5119, 8477, 1201],
+ [5519, 8877, 1202]
+]
+
+image = img_client.image_cutout(bounds)
+
+# Use PIL to visualize
+from PIL import Image
+Image.fromarray(image.T)
+```
+
+![imagery base](../example_images/img_base.png)
+
+Since often we are using analysis points to center an image on, we can alternatively define a center point and the width/height/depth of the bounding box (in voxels).
+The same image could be achived from this specification.
+```python
+ctr = [5319, 8677, 1201]
+img_width = 400
+image = img_client.image_cutout(ctr, bbox_size=(img_width, img_width))
+```
+
+You can also generate bounds from a center and size.
+```python
+bounds = ic.bounds_from_center(ctr, width=img_width, height=img_width, depth=1)
+```
+
+### Resolution
+
+A very important element in ImageryClient is the resolution, which specifies the units that you are using when providing bounds.
+You can check the resolution that the client is expecting with `img_client.resolution`.
+The resolution will default to the highest resolution available for the imagery, but you can specify another resolution manually.
+For example, to say that you are going to provide bounds in `[8,8,30]` voxel units, you would add the `resolution` argument:
+
+```python
+img_client = ic.ImageryClient(..., resolution=[8,8,30])
+```
+You can also explicitly set the resolution to `"image"` or `"segmentation"` to use the highest available resolution available for either.
+Resolution can also be specified in each of the functions for image or segmentation cutouts, but will default to the client values.
+
+Note that the volumetric data itself is not necessarily at the resolution specified, but rather this parameter determines how to interpret the _coordinates_.
+The resolution is set by the image and segmentation mip levels, which can be added either when creating the ImageryClient instance or when doing any cutout download.
+By default, ImageryClient will use the highest resolution mip level that is not labeled as a `"placeholder"` in CloudVolume.
+
+#### Specifying image size instead of field of view
+
+When upper and lower bounds are specified or a `bbox_size` is used, the resolution will change with mip level but the field of view that is downloaded will remain the same.
+Alternatively, one might want to download an image with a specific size in pixels and a specific mip level without having to calculate what bounding box would get you that..
+This can be done in `image_cutout` by specifying the center point in the place of bounds and also specify `image_size` as a 2- or 3-element array.
+In this case, the center point will be adjusted according to the resolutions specified, while the field of view will change with image size.
+
+In practice, this only is needed for non-default mip levels.
+If you specify mip level, this approach will always yield an image with the same size while a bounds-based approach will get smaller with increasing mips as the effective resolution gets coarser.
+
+For example, using bounds:
+```python
+image = img_client.image_cutout(bounds, mip=3)
+Image.fromarray(image.T)
+```
+
+![imagery scaled](../example_images/scaled_mip_3.png)
+
+And using specified pixel dimensions:
+```python
+img_size=(400, 400)
+image = img_client.image_cutout(ctr, mip=3, image_size=img_size)
+Image.fromarray(image.T)
+```
+
+![imagery exact](../example_images/exact_mip_3.png)
+
+You can also use the `scale_to_bounds=True` argument to upscale an image to the size specified in the bounding box, equivalent to having one pixel for each voxel as measured by the resolution parameter.
+
+### Segmentations
+
+An aligned segmentation cutout is retrieved similarly.
+Note that segmentations show segment ids, and are not directly visualizable.
+However, in this case we can convert to a uint8 greyscale and see the gist, although there are many better approaches to coloring segmentations that will be shown later.
+Note that for dynamic segmentations, you can use the timestamp parameter to (optionally) set the time at which segmentation will e looked up.
+
+```python
+seg = img_client.segmentation_cutout(bounds)
+
+import numpy as np
+Image.fromarray( (seg.T / np.max(seg) * 255).astype('uint8') )
+```
+
+![segmentation base](../example_images/seg_base.png)
+
+Specific root ids can also be specified. All pixels outside those root ids have a value of 0.
+
+```python
+root_ids = [2282, 4845]
+seg = img_client.segmentation_cutout(bounds, root_ids=root_ids)
+Image.fromarray( (seg.T / np.max(seg) * 255).astype('uint8') )
+```
+
+![segmentation specific](../example_images/seg_specific.png)
+
+
+### Split segmentations
+
+It's often convenient to split out the segmentation for each root id as a distinct mask. These "split segmentations" come back as a dictionary with root id as key and binary mask as value.
+
+```python
+split_seg = img_client.split_segmentation_cutout(bounds, root_ids=root_ids)
+
+Image.fromarray((split_seg[ root_ids[0] ].T * 255).astype('uint8'))
+```
+
+![segmentation single](../example_images/seg_single.png)
+
+### Aligned cutouts
+
+Aligned image and segmentations can be downloaded in one call, as well.
+If the lowest mip data in each differs in resolution, the lower resolution data will be optionally upsampled to the higher resolution in order to produce aligned overlays.
+Root ids and split segmentations can be optionally specified. This is the best option if your primary goal is overlay images.
+
+```python
+image, segs = img_client.image_and_segmentation_cutout(bounds,
+ split_segmentations=True,
+ root_ids=root_ids)
+```
+
+Note that `image_size` is not an option for joint image and segmentation calls, because it's not clear which bounds to use.
+If this is needed, you can use the `img_client.segmentation_bbox_size_from_dimensions` or `img_client.image_bbox_size_from_dimensions` to get the appropriate `bbox_size` argument for a segmentation-based image dimension (or image-based, respectively).
+
+
+## Using with CAVEclient
+
+While the ImageryClient was designed to work specifically with the [CAVEclient](https://github.com/seung-lab/CAVEclient)
+and its associated suite of services, it should work with any cloudvolume project.
+
+However, if you are working within an CAVEclient-compatible project, a CAVEclient can be used to help configure the ImageryClient, filling in the imagery source, the segmentation source, authentication information, and the default resolution used in Neuroglancer.
+
+For example, we can download the data around [this view of the MICRoNs mouse visual cortex data from Neuroglancer](https://ngl.microns-explorer.org/#!%7B%22dimensions%22:%7B%22x%22:%5B4e-9%2C%22m%22%5D%2C%22y%22:%5B4e-9%2C%22m%22%5D%2C%22z%22:%5B4e-8%2C%22m%22%5D%7D%2C%22position%22:%5B240640.5%2C207872.5%2C21360.5%5D%2C%22crossSectionScale%22:0.9700751861624107%2C%22projectionOrientation%22:%5B0.021348824724555016%2C-0.17453671991825104%2C-0.007549765054136515%2C-0.9843902587890625%5D%2C%22projectionScale%22:489587.6696286937%2C%22layers%22:%5B%7B%22type%22:%22image%22%2C%22source%22:%7B%22url%22:%22precomputed://https://bossdb-open-data.s3.amazonaws.com/iarpa_microns/minnie/minnie65/em%22%2C%22subsources%22:%7B%22default%22:true%7D%2C%22enableDefaultSubsources%22:false%7D%2C%22tab%22:%22source%22%2C%22shaderControls%22:%7B%22normalized%22:%7B%22range%22:%5B86%2C172%5D%7D%7D%2C%22name%22:%22img65%22%7D%2C%7B%22type%22:%22image%22%2C%22source%22:%7B%22url%22:%22precomputed://https://bossdb-open-data.s3.amazonaws.com/iarpa_microns/minnie/minnie35/em%22%2C%22subsources%22:%7B%22default%22:true%7D%2C%22enableDefaultSubsources%22:false%7D%2C%22tab%22:%22source%22%2C%22shaderControls%22:%7B%22normalized%22:%7B%22range%22:%5B112%2C172%5D%7D%7D%2C%22name%22:%22img35%22%7D%2C%7B%22type%22:%22segmentation%22%2C%22source%22:%22precomputed://gs://iarpa_microns/minnie/minnie65/seg%22%2C%22tab%22:%22segments%22%2C%22annotationColor%22:%22#8f8f8a%22%2C%22selectedAlpha%22:0.41%2C%22notSelectedAlpha%22:0.06%2C%22colorSeed%22:1689220695%2C%22name%22:%22seg65%22%7D%2C%7B%22type%22:%22segmentation%22%2C%22source%22:%22precomputed://gs://iarpa_microns/minnie/minnie35/seg%22%2C%22tab%22:%22segments%22%2C%22annotationColor%22:%22#8a8a8a%22%2C%22segments%22:%5B%22864691137827278437%22%2C%22864691138020403235%22%2C%22864691138081021535%22%2C%22864691138134948293%22%2C%22864691138142870469%22%2C%22864691138153699060%22%2C%22864691138178964470%22%2C%22864691138345166401%22%5D%2C%22name%22:%22seg35%22%7D%5D%2C%22showSlices%22:false%2C%22selectedLayer%22:%7B%22visible%22:true%2C%22layer%22:%22seg65%22%7D%2C%22layout%22:%7B%22type%22:%22xy%22%2C%22orthographicProjection%22:true%7D%7D).
+
+```python
+from caveclient import CAVEclient
+client = CAVEclient('minnie65_public_v343') . # Note that you have to set up a token for this to work, see below.
+
+img_client = ic.ImageryClient(client=client)
+
+ctr = [240640, 207872, 21360]
+
+image, segs = img_client.image_and_segmentation_cutout(ctr,
+ split_segmentations=True,
+ bbox_size=(1024, 1024),
+ scale_to_bounds=True,
+)
+
+ic.composite_overlay(segs, imagery=image, palette='husl')
+```
+![Microns Example](../example_images/microns_example.png)
+
+Note that the following code requires setting up a CAVE token to access the server. [See here for details](https://github.com/AllenInstitute/MicronsBinder/blob/master/notebooks/mm3_intro/CAVEsetup.ipynb).
diff --git a/docs/tutorials/index.qmd b/docs/tutorials/index.qmd
new file mode 100644
index 0000000..6a3e132
--- /dev/null
+++ b/docs/tutorials/index.qmd
@@ -0,0 +1,5 @@
+---
+title: Tutorials
+---
+
+ImageryClient helps with both downloading aligned images and segmentations and turning these into overlays.
diff --git a/docs/tutorials/overlays.qmd b/docs/tutorials/overlays.qmd
new file mode 100644
index 0000000..767a306
--- /dev/null
+++ b/docs/tutorials/overlays.qmd
@@ -0,0 +1,99 @@
+---
+title: Making Overlays
+toc: true
+---
+
+Once you have imagery and segmentation data, one important use case is to make visualizations overlaying segmentations on top of images.
+
+Now let produce an overlay of segmentation and imagery to highlight a particular synapse.
+Overlays are returned as a [PIL Image](https://pillow.readthedocs.io/en/stable/), which has convenient saving options but can also be converted to RGBa (a is for "alpha", i.e. transparency) via a simple `np.array` call.
+Note that if imagery isn't specified, the segmentations are colored but not put over another image.
+Segmentations must be either a list or a dict, such as comes out of split segmentation cutouts.
+
+```python
+ic.composite_overlay(segs, imagery=image)
+```
+![overlay 0](../example_images/seg_overlay_0.png)
+
+### Aesthetic options
+
+Colors are chosen by default from the perceptually uniform discrete [HUSL Palette](https://seaborn.pydata.org/generated/seaborn.husl_palette.html) as implemented in Seaborn, and any color scheme available through Seaborn's [color_palette](https://seaborn.pydata.org/generated/seaborn.color_palette.html?highlight=color_palette) function is similarly easy to specify.
+Alpha is similarly easy to set.
+
+```python
+ic.composite_overlay(segs, imagery=image, palette='tab10', alpha=0.4)
+```
+
+![overlay 1](../example_images/seg_overlay_1.png)
+
+Colors can also be specified in the same form as the segmentations, e.g. a dictionary of root id to RGB tuple.
+
+```python
+colors = {2282: (0,1,1), # cyan
+ 4845: (1,0,0)} # red
+ic.composite_overlay(segs, imagery=image, colors=colors)
+```
+
+![overlay 2](../example_images/seg_overlay_2.png)
+
+### Outline options
+
+While the overlay guides the eye, it can also obscure the imagery.
+Because of that, one can also use highly configurable outlines instead of solid overlays.
+The default option puts the outlines along the outside of the segmentations, but omits lines where two segmentations touch.
+
+```python
+ic.composite_overlay(segs, imagery=image, outline=True, alpha=0.5, width=15, colors=colors)
+```
+
+![outline 0](../example_images/seg_outline_0.png)
+
+Outlines can also be put inside of the segmentation and width can be specified.
+Additionally, setting `merge_outline` to False will not omit outlines in places where segmentations touch.
+Lots of different effects are possible!
+
+```python
+ic.composite_overlay(segs,
+ imagery=image,
+ outline=True,
+ alpha=1,
+ width=3,
+ merge_outline=False,
+ side='in',
+ colors=colors)
+```
+
+![outline 1](../example_images/seg_outline_1.png)
+
+## 3d Image Stacks
+
+All of the functions are designed to also work for 3d image stacks.
+Image and segmentation cutouts will return 3d arrays instead of 2d ones.
+However, note that composite images will come back as a list of PIL images.
+An optional `dim` argument will perform the slicing on axes other than the z-axis, although anisotropy in voxel resolution will not be accounted for.
+
+```python
+ctr = [5019, 8677, 1211]
+width = 100
+z_slices = 3
+
+bounds_3d = ic.bounds_from_center(ctr, delx=width, dely=width, delz=z_slices)
+
+image, segs = img_client.image_and_segmentation_cutout(bounds_3d, split_segmentations=True)
+
+overlays = ic.composite_overlay(segs, imagery=image, alpha=0.3, width=3,
+ merge_outline=False, side='in')
+
+overlays[0]
+```
+
+![Series 0](../example_images/seg_series_0.png)
+
+In order to quickly assemble sequential images into a series, we can stack them.
+A `direction` argument will let you specify `vertical` instead of the default, and spacing can be adjusted as well.
+
+```python
+ic.stack_images(overlays)
+```
+
+![Series 1](../example_images/seg_series_full.png)
diff --git a/example_images/code_to_picture.png b/example_images/code_to_picture.png
new file mode 100644
index 0000000..21dfab7
Binary files /dev/null and b/example_images/code_to_picture.png differ
diff --git a/imageryclient/composite.py b/imageryclient/composite.py
index 70ea330..3e1dc5d 100644
--- a/imageryclient/composite.py
+++ b/imageryclient/composite.py
@@ -230,7 +230,7 @@ def composite_overlay(segs,
Parameters
----------
- masks : list-like or dict
+ segs: list-like or dict
Iterable of masked images of the same size. If a dict, colors must be a dict as well.
colors : list-like, dict, or None
Iterable of RGB colors of the same size as masks. If a dict, masks must also be a dict and colors
diff --git a/imageryclient/imagery.py b/imageryclient/imagery.py
index f64febd..42b8851 100644
--- a/imageryclient/imagery.py
+++ b/imageryclient/imagery.py
@@ -34,7 +34,6 @@ def bounds_from_center(ctr, width=1, height=1, depth=1):
return np.array([xl, xh])
-
def save_image_slices(
filename_prefix,
filename_suffix,
@@ -73,32 +72,24 @@ class ImageryClient(object):
Parameters
----------
+ client : caveclient.CAVEclient or None, optional
+ A pre-initialized CAVEclient to use for configuration.
+ If used, the image source and segmentation source come from the info service values.
+ resolution : array-like or 'image' or 'segmentation', optional
+ Sets the voxel resolution that bounds will be entered in, by default 'image', which is the mip 0 resolution of the imagery.
+ segmentation : bool, optional
+ If False, no segmentation cloudvolume is initialized. By default True
+ imagery : bool, optional
+ If False, no imagery cloudvolume is initialized. By default True
image_source : str, optional
CloudVolume path to an imagery source, by default None
segmentation_source : str, optional
CloudVolume path to a segmentation source, by default None
- datastack_name : str, optional
- Datastack name to lookup information for in the InfoService, by default None
- server_address : str, optional
- Address of an InfoService host, by default None. If none, uses defaults in
- the CAVEclient.
- base_resolution : array-like or 'image' or 'segmentation', optional
- Sets the voxel resolution that bounds will be entered in, by default 'image'.
- Literal resolutions will be followed, while "image" or "segmentation" use the
- mip 0 values of the associated cloudvolumes.
- table_name : str, optional
- Name of the chunkedgraph table (if used), by default None
image_mip : int, optional
Default mip level to use for imagery lookups, by default 0. Note that the same mip
level for imagery and segmentation can correspond to different voxel resolutions.
segmentation_mip : int, optional
Default mip level to use for segmentation lookups, by default 0.
- segmentation : bool, optional
- If False, no segmentation cloudvolume is initialized. By default True
- imagery : bool, optional
- If False, no imagery cloudvolume is initialized. By default True
- framework_client : caveclient.CAVEclient, optional
- A pre-initialized Framework client to be used instead of initializing a new one.
auth_token : str or None, optional
Auth token to use for cloudvolume. If None, uses the default values from the CAVEclient. Default is None.
timestamp : datetime.datetime or None,
@@ -119,7 +110,6 @@ def __init__(
auth_token=None,
timestamp=None,
):
-
self._image_source = image_source
self._segmentation_source = segmentation_source
@@ -161,14 +151,16 @@ def _configure_mip_levels(self, image_mip, segmentation_mip):
else:
self._base_imagery_mip = image_mip
if segmentation_mip is None:
- self._base_segmentation_mip = utils._get_lowest_nonplaceholder(self.segmentation_cv)
+ self._base_segmentation_mip = utils._get_lowest_nonplaceholder(
+ self.segmentation_cv
+ )
else:
self._base_segmentation_mip = segmentation_mip
def _configure_resolution(self, resolution):
if resolution is None:
resolution = "image"
-
+
if isinstance(resolution, str):
if resolution in ["image", "segmentation"]:
if resolution == "image":
@@ -176,13 +168,17 @@ def _configure_resolution(self, resolution):
raise ValueError(
"Cannot set resolution from imagery if not being used"
)
- self._resolution = np.array(self.image_cv.mip_resolution(self._base_imagery_mip))
+ self._resolution = np.array(
+ self.image_cv.mip_resolution(self._base_imagery_mip)
+ )
elif resolution == "segmentation":
if self._use_segmentation is None:
raise ValueError(
"Cannot set resolution from segmentation if not being used"
)
- self._resolution = np.array(self.segmentation_cv.mip_resolution(self._base_segmentation_mip))
+ self._resolution = np.array(
+ self.segmentation_cv.mip_resolution(self._base_segmentation_mip)
+ )
else:
raise ValueError(
'Base resolution must be set by the client, array-like, "image" or "segmentation"'
@@ -190,7 +186,6 @@ def _configure_resolution(self, resolution):
else:
self._resolution = np.array(resolution)
-
@property
def token(self):
return self._auth_token
@@ -285,17 +280,17 @@ def image_bbox_size_from_dimensions(self, image_size, mip=None, resolution=None)
Parameters
----------
- image_size: list-like
- Image size in pixels (2-element) or voxels (3-element)
- mip: int or None, optional
- Mip for which the image would be computed. Defaults to None, which uses the client default.
- resolution: list-like or None, optional.
- Resolution to use for the bbox_size. Defaults to None, or the client defauls.
+ image_size: list-like
+ Image size in pixels (2-element) or voxels (3-element)
+ mip: int or None, optional
+ Mip for which the image would be computed. Defaults to None, which uses the client default.
+ resolution: list-like or None, optional.
+ Resolution to use for the bbox_size. Defaults to None, or the client defauls.
Returns
-------
- tuple:
- Argument for bbox_size that would give the desired pixel dimensions.
+ tuple:
+ Argument for bbox_size that would give the desired pixel dimensions.
"""
if mip is None:
mip = self._base_imagery_mip
@@ -312,17 +307,17 @@ def segmentation_bbox_size_from_dimensions(
Parameters
----------
- image_size: list-like
- Image size in pixels (2-element) or voxels (3-element)
- mip: int or None, optional
- Mip for which the image would be computed. Defaults to None, which uses the client default.
- resolution: list-like or None, optional.
- Resolution to use for the bbox_size. Defaults to None, or the client defauls.
+ image_size: list-like
+ Image size in pixels (2-element) or voxels (3-element)
+ mip: int or None, optional
+ Mip for which the image would be computed. Defaults to None, which uses the client default.
+ resolution: list-like or None, optional.
+ Resolution to use for the bbox_size. Defaults to None, or the client defauls.
Returns
-------
- tuple:
- Argument for bbox_size that would give the desired pixel dimensions.
+ tuple:
+ Argument for bbox_size that would give the desired pixel dimensions.
"""
if mip is None:
@@ -451,7 +446,7 @@ def segmentation_cutout(
convert_to_int64 : bool, optional
If True, converts segmentation data to int64 from uint64 if it is safe to do so. Default is True.
If not safe, raises a warning and does not convert from uint64.
-
+
Returns
-------
numpy.ndarray
@@ -509,7 +504,9 @@ def segmentation_cutout(
if utils.safe_to_convert_uint64(seg):
seg = seg.astype(np.int64)
else:
- raise Warning('Could not convert to int64 because values are too large. Returning as uint64.')
+ raise Warning(
+ "Could not convert to int64 because values are too large. Returning as uint64."
+ )
if scale_to_bounds:
return utils.rescale_to_bounds(
@@ -589,7 +586,6 @@ def image_and_segmentation_cutout(
scale_to_bounds=None,
convert_to_int64=True,
):
-
"""Download aligned and scaled imagery and segmentation data at a given resolution.
Parameters