Cookbook
Here you learn how to use eyepy to perform common tasks.
Import OCT data
Currently eyepy
supports the HEYEX E2E, VOL and XML formats, as well as reading data from several public OCT datasets. All functions return a single EyeVolume
object representing the data. E2E files may contain several OCT volumes. The import function only returns the first OCT volume in the file. If you want to read several volumes from a file use the HeE2eReader class. While you can use Reader objects to parse the data and access specific information, it is recommended to use when possible, the provided import functions to get EyeVolume
object which are a convenient interface to the data that provides a unified interface to data imported from various sources.
import eyepy as ep
# Import HEYEX E2E export
ev = ep.import_heyex_e2e("path/to/file.e2e")
# Import HEYEX XML export
ev = ep.import_heyex_xml("path/to/folder")
# Import HEYEX VOL export
ev = ep.import_heyex_vol("path/to/file.vol")
# Import Topcon FDA export
ev = ep.import_topcon_fda("path/to/file.fda")
# Import volume from Duke public dataset
ev = ep.import_duke_mat("path/to/file.mat")
# Import volume form RETOUCH challenge
ev = ep.import_retouch("path/to/volume_folder")
Missing scale information
For the E2E file the scale of both localizer axes as well as the B-scan x-axes has not been identified yet and is hardcoded. When importing B-scans from folders there is also no scale information available.
When only B-scans exist in a folder eyepy
might still be able to import them. B-scans are expected to be ordered and distributed with equal distance on a quadratic area.
Public OCT datasets often have their own data formats. eyepy
can import volumes from the AMD Dataset from Duke University and the RETOUCH Challenge.
import eyepy as ep
# Import DUKE volume
ev = ep.import_duke_mat("path/to/volume.mat")
# Import RETOUCH volume
ev = ep.import_retouch("path/to/folder")
When you don't hava a supported OCT volume at hand you can check out our sample dataset to get familiar with eyepy
.
Plot Localizer
Most OCT volumes come with a localizer image. This image can be plotted using the plot
method of the EyeVolume
object:
There are several options to customize the plot:
+ show B-scan positions or region (bscan_positions
and bscan_region
parameters)
+ show enface projections or quantifications of OCT voxel annotaions such as drusen (projections
and quantifications
parameters)
+ show only a specific region of the localizer image (region
parameter)
The plotting function is documented here: EyeVolume.plot
region
parameter
The region parameter produces unexpected results in combination with bscan_positions
and bscan_region
parameters
Plot Bscans
B-scans can be plotted using the plot
method of the EyeBscan
object. You get EyeBscan
objects by indexing the EyeVolume
object or iterating over it. The following code plots the first B-scan of the volume together with the layer annotations for BM and RPE:
The plotting function is documented here: EyeBscan.plot
Modify Annotations
Compute Drusen from Layer Annotations
Here we compute drusen for our sample data which has manual layer annotations for BM and RPE.
import eyepy as ep
# Import example data
ev = ep.data.load("drusen_patient")
# Compute drusen
drusen_map = ep.drusen(ev.layers["RPE"].data, ev.layers["BM"].data, ev.shape, minimum_height=2)
Add / Remove Layer Annotations
Often OCT volumes come with layer annotations. They are added to the EyeVolume
object during the import, but you can also manipulate them yourself using the add_layer_annotation
and remove_layer_annotation
methods. The following code can be used to layer annotations to EyeVolume
objects. The name
parameter is used to identify the layer.
layer_heights = np.zeros(np.array(ev.shape)[[0,2]])
ev.add_layer_annotation(layer_heights, name="new_layer")
To remove a layer annotation use the remove_layer_annotation
method. The following code removes the layer annotation we added above.
Add / Remove Voxel Annotaitons
If you want to add voxel annotations to the EyeVolume object you can use the add_pixel_annotation
method. The following code adds the drusen map we computed above to the EyeVolume object. The name
parameter is used to identify the annotation.
To remove an annotation use the remove_pixel_annotation
method. The following code removes the drusen annotation we added above.
ETDRS and Custom Quantification Grids
Quantifications on circular grids such as the ETDRS grid are common to quantify imaging data of the eye. With eyepy
you can easily compute quantifications on such grids. The following code computes a quantification grid for the drusen annotation we added above.
fig, axes = plt.subplots(1, 2, figsize=(5, 10))
# Configure quantification grid for drusen quantification
ev.volume_maps["drusen"].radii = [1.5, 2.5]
ev.volume_maps["drusen"].n_sectors = [4, 8]
ev.volume_maps["drusen"].offsets = [0, 45]
# Plot drusen projection and quantification
ev.plot(ax=axes[0], projections=["drusen"])
ev.plot(ax=axes[1], quantification="drusen")
axes[0].axis("off")
axes[1].axis("off")
The result looks like this: On the left, the scale is the drusen height in voxel and on the right, the drusen volume in mm³
To access the quantification as a dictionary use ev.volume_maps["drusen"].quantification
Interact with individual B-scans
If you index into an EyeVolume object you get EyeBscan objects. Annotations you added to the respective EyeVolume
object are also available in the EyeBscan
object and can be visualized easily. The following code plots the 40th B-scan of the volume together with the layer annotations for BM and RPE and the computed drusen annotation: