From cef06cdd643a341fc1148dbe148f697c8a0eff21 Mon Sep 17 00:00:00 2001 From: Felix-Mac Date: Thu, 25 Jul 2024 13:48:24 +0200 Subject: [PATCH 1/3] Create python script which covers how to load images and read their metadata, as well as saves them again --- .../open_diverse_file_formats_bioio.py | 228 ++++++++++++++++++ 1 file changed, 228 insertions(+) create mode 100644 _includes/image_file_formats/open_diverse_file_formats_bioio.py diff --git a/_includes/image_file_formats/open_diverse_file_formats_bioio.py b/_includes/image_file_formats/open_diverse_file_formats_bioio.py new file mode 100644 index 00000000..92728e2b --- /dev/null +++ b/_includes/image_file_formats/open_diverse_file_formats_bioio.py @@ -0,0 +1,228 @@ +# %% +# Load different image files and access various levels of metadata +# minimal conda env for this module +# conda create -n ImageFileFormats python=3.10 +# activate ImageFileFormat +# pip install bioio bioio-tifffile bioio-lif bioio-czi bioio-ome-tiff bioio-ome-zarr notebook + +# %% +# Load .tif file with minimal metadata +# - Observe that BioImage chooses the correct reader plugin +# - Observe that the return object is not the image matrix +from bioio import BioImage +image_url = 'https://github.com/NEUBIAS/training-resources/raw/master/image_data/xy_8bit__nuclei_PLK1_control.tif' +bioimage = BioImage(image_url) +print(bioimage) +print(type(bioimage)) + +# %% +# Print some onject attributes +# - Observe that the object is 5 dimensional with most dimensions being empty +# - Observe that the dimension order is always time, channel, z, y, x, (TCZYX) +print(bioimage.dims) +print(bioimage.shape) +print(f'Dimension order is: {bioimage.dims.order}') +print(type(bioimage.dims.order)) +print(f'Size of X dimension is: {bioimage.dims.X}') + +# %% +# Extract image data +# - Observe that the returned numpy.array is still 5 dimensional +image_data = bioimage.data +print(type(image_data)) +print(image_data) +print(image_data.shape) + +# %% +# Extract specific part of image data +# - Observe that numpy.array is reduced to populated dimensions only +yx_image_data = bioimage.get_image_data('YX') +print(type(yx_image_data)) +print(yx_image_data) +print(yx_image_data.shape) + +# %% +# Access pixel size +import numpy as np +print(bioimage.physical_pixel_sizes) +print(f'An pixel has a length of {np.round(bioimage.physical_pixel_sizes.X,2)} microns in X dimension.') + +# %% +# Access general metadata +print(type(bioimage.metadata)) +print(bioimage.metadata) + +# %% +# Load .tif file with extensive metadata +image_url = "https://github.com/NEUBIAS/training-resources/raw/master/image_data/xy_16bit__collagen.md.tif" +bioimage = BioImage(image_url) +print(bioimage) +print(type(bioimage)) + +# - Observe that the image is larger than the previous +print(bioimage.dims) + +# %% +# Access image and reduce to only populated dimensions +yx_image_data = bioimage.data.squeeze() +print(type(yx_image_data)) +print(yx_image_data) +print(yx_image_data.shape) + +# %% +# Access pixel size +print(bioimage.physical_pixel_sizes) +print(f'An pixel has a length of {np.round(bioimage.physical_pixel_sizes.Y,2)} microns in Y dimension.') + +# Access general metadata +# - Observe that metadata are more extensive than in the previous image +print(type(bioimage.metadata)) +print(bioimage.metadata) + +# %% +# Load .lif file +# - Observe that BioImage chooses the correct reader plugin +# - Observe that the return object has 4 different channels +# - Observe that the general metadata are an abstract element +image_url = "https://github.com/NEUBIAS/training-resources/raw/master/image_data/xy_xyc__two_images.lif" +bioimage = BioImage(image_url) +print(bioimage) +print(type(bioimage)) +print(bioimage.dims) +print(bioimage.metadata) +print(type(bioimage.metadata)) + +# %% +# Access channel information +print(bioimage.channel_names) + +# %% +# Access image data for all channels +img_4channel = bioimage.data.squeeze() + +# Alternative +img_4channel = bioimage.get_image_data('CYX') + +# - Observe that numpy.array shape is 3 dimensional representing channel,y,x +print(img_4channel.shape) + +# Access only one channel +img_1channel = bioimage.get_image_data('YX',C=0) + +# Alternative +img_1channel = img_4channel[0] + +# - Observe that numpy.array shape is 2 dimensional representing y,x +print(img_1channel.shape) + +# %% +# Access different images in one image file (scenes) +# - Observe that one image file can contain several scenes +# - Observe that they can be different in various aspects +print(bioimage.scenes) +print(f'Current scene: {bioimage.current_scene}') + +# - Observe that the image in the current scene as 4 channel and Y/X dimensions have the size of 1024 +print(bioimage.dims) +print(bioimage.physical_pixel_sizes) + +# Switch to second scene +# - Observe that the image in the other scene as only one channel and Y/X dimensions are half as large as the first scene +# - Observe that the pixel sizes are doubled +bioimage.set_scene(1) +print(bioimage.dims) +print(bioimage.physical_pixel_sizes) + +# %% +# Load .czi file +# file needs first to be downloaded from https://github.com/NEUBIAS/training-resources/raw/master/image_data/xyz__multiple_images.czi +# save file in the same directory as this notebook +# - Observe that BioImage chooses the correct reader plugin +# - Observe that the return object has a z dimension +bioimage = BioImage('/Users/fschneider/skimage-napari-tutorial/ExampleImages/xyz__multiple_images.czi') +print(bioimage) +print(type(bioimage)) + +# %% +# lession in between +# Access image dimensions +print(bioimage.dims) + +# Access general metadata +# - Observe that metadata are abstract +print(bioimage.metadata) +print(type(bioimage.metadata)) + +# Access pixel size +print(bioimage.physical_pixel_sizes) + +# Access image data for all channels +img_3d = bioimage.data.squeeze() + +# Alternative +img_3d = bioimage.get_image_data('ZYX') + +# - Observe that numpy.array shape is 3 dimensional representing z,y,x +print(img_3d.shape) + +# Access only one channel +img_2d = bioimage.get_image_data('YX',Z=0) + +# Alternative +img_2d = img_3d[0] + +# - Observe that numpy.array shape is 2 dimensional representing y,x +print(img_2d.shape) + +# %% +# Save image as .ome.tif +# Option 1: directly from the BioImage object +# - Observe that some metadata are automatically transferred +image_url = "https://github.com/NEUBIAS/training-resources/raw/master/image_data/xy_8bit__nuclei_PLK1_control.tif" +bioimage = BioImage(image_url) +print(bioimage.physical_pixel_sizes) +print(bioimage.metadata) + +# Save and reload +bioimage.save('option1.ome.tif') +print(BioImage('option1.ome.tif').physical_pixel_sizes) +print(bioimage.metadata) + +# %% +# Option 2: Start from numpy.array +from bioio.writers import OmeTiffWriter +img_data = bioimage.data.squeeze() +OmeTiffWriter.save(img_data, + 'option2.ome.tif', + dim_order='YX', + physical_pixel_sizes=bioimage.physical_pixel_sizes) + +# - Observe that pixel size is stored in file +print(BioImage('option2.ome.tif').physical_pixel_sizes) + +# %% +# Option 3: Save as ome.zarr +# - Observe that saved image is no longer single file, but whole folder +from bioio.writers import OmeZarrWriter + +OmeZarrWriter('option3.ome.zarr').write_image(img_data, + image_name='Option3', + channel_names=None, + channel_colors=None, + dimension_order='YX', + physical_pixel_sizes=bioimage.physical_pixel_sizes) + +# - Observe that relaoding shows the same array again with the same pixel sizes +reloaded_img = BioImage('option3.ome.zarr') +print(reloaded_img.dims) +print(reloaded_img.physical_pixel_sizes) + +# %% +# Option 4: Save only the numpy.array +# - Keep in mind that is not the best way, as all metadata are lost and the file can only be opened with python again +np.save('option4.npy',img_data) + +# Reload and check if they are the same +reloaded_img = np.load('option4.npy') +print(f'Are the dimensions the same: {np.all(img_data.shape == reloaded_img.shape)}') +print(f'Are the images the same: {np.all(img_data == reloaded_img)}') From e07cca3ae1843fee8765502c51b5463d04378188 Mon Sep 17 00:00:00 2001 From: felixS27 Date: Thu, 25 Jul 2024 14:01:34 +0200 Subject: [PATCH 2/3] Add python activity to module image file formats --- _modules/image_file_formats.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_modules/image_file_formats.md b/_modules/image_file_formats.md index 7b4b5389..4e20182f 100644 --- a/_modules/image_file_formats.md +++ b/_modules/image_file_formats.md @@ -29,7 +29,7 @@ figure: /figures/image_file_formats.png figure_legend: Image pixel data and metadata multiactivities: - - ["image_file_formats/open_diverse_file_formats.md", [["ImageJ GUI", "image_file_formats/open_diverse_file_formats_imagejgui.md", "markdown"]]] + - ["image_file_formats/open_diverse_file_formats.md", [["ImageJ GUI", "image_file_formats/open_diverse_file_formats_imagejgui.md"],["python BioIO", "image_file_formats/open_diverse_file_formats_bioio.py"]]] - ["image_file_formats/resaving_images.md", [["ImageJ GUI", "image_file_formats/resaving_images_imagejgui.md", "markdown"]]] assessment: > From 7d3e5e659b1d5be5b58effbf745234573ef31905 Mon Sep 17 00:00:00 2001 From: felixS27 Date: Thu, 25 Jul 2024 14:14:37 +0200 Subject: [PATCH 3/3] Add little excersie block --- .../image_file_formats/open_diverse_file_formats_bioio.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/_includes/image_file_formats/open_diverse_file_formats_bioio.py b/_includes/image_file_formats/open_diverse_file_formats_bioio.py index 92728e2b..6dd96c14 100644 --- a/_includes/image_file_formats/open_diverse_file_formats_bioio.py +++ b/_includes/image_file_formats/open_diverse_file_formats_bioio.py @@ -144,7 +144,7 @@ print(type(bioimage)) # %% -# lession in between +# little excersise in between # Access image dimensions print(bioimage.dims) @@ -174,6 +174,10 @@ # - Observe that numpy.array shape is 2 dimensional representing y,x print(img_2d.shape) +# %% +# little excercise: +# paticipants should try to open one of their files with python + # %% # Save image as .ome.tif # Option 1: directly from the BioImage object