After completing this lesson, learners should be able to:
Understand that a digital image is typically stored as an N-dimensional array.
Learn that the image array elements are called pixels (2D) or voxels (3D).
Examine the values and locations of pixels/voxels in an image.
Motivation
Digital images are a very important subset of the more general mathematical definition of an image. The vast majority of available algorithms and visualisation tools operate on digital images and all (as far as we know) scientific microscopes output digital images. Thus, for microscopy based science, it is crucial to understand the basic properties of digitial images and how to effectively inspect their content.
Concept map
graph TD
Im("Digital image") --- A("N-D array")
A --- E("Elements/Pixels/Voxels")
A --- DT("Data type")
A --- D("Shape/Size/Dimensions")
E --- V("Value")
E --- I("Indices")
Figure
Digital image pixel array and gray-scale rendering. This array (image) has two dimensions with 21 x 21 elements (pixels). The pixel values (black numbers) can be addressed by their respective pixel indices (green numbers).
Explore different ways to inspect pixel values and indices
Mouse hover
Orient yourself by checking where the lowest pixel indices are
Line profile. Draw a line and [Analyze > Plot Profile] or [Ctrl + K].
Histogram [Analyze > Histogram] or [Ctrl + H]
skimage napari
# %% [markdown]
# ## Inspect a 2D image
# To follow along for the plot profile you require a napari plugin. \
# Install napari-plot-profile in your course activated conda environment.\
# `conda activate skimage-napari-tutorial` \
# `pip install napari-plot-profile`
# %%
# Load the image
# You can also load a local image by providing the path to the file
fromOpenIJTIFFimportopen_ij_tiffimage_url="https://github.com/NEUBIAS/training-resources/raw/master/image_data/xy_8bit__nuclei_noisy_different_intensity.tif"image,axes,scales,units=open_ij_tiff(image_url)# %%
# Create a new napari viewer.
fromnapari.viewerimportViewernapari_viewer=Viewer()# %% [markdown]
# ### Code completion and help in Jupyter notebook
# * **Code completion** type `napari_viewer.` and press `TAB`
# * **Help** type `napari_viewer.add_image` and press `SHIFT-TAB` this will open a help associated to the add_image method/command
# %%
# %%
# Add an image to the napari_viewer.
napari_viewer.add_image(image)# %% [markdown]
# ### Alternative loading of data
# **Napari GUI** drag and drop image from browser\
# rename the layer for convenience\
# `napari_viewer.layers[0].name = 'image'`
# Get the data as numpy array\
# `image = napari_viewer.layers['image'].data`
# %%
# Print image shape
print(image.shape)# %%
# Print the image pixel values.
print(image)# %%
# Top left corner is [y, x] = [r, c] = [0, 0]
print(image[0,0])# %%
# [y, x] = [r, c] = [1, 0]
print(image[1,0])# %%
# [y, x] = [r, c] = [0, 2]
print(image[0,2])# %% [markdown]
# **Napari GUI** Explore the napari-plot-profile plugin (optional)
# %%
importnumpyasnp# Compute min and max.
print(image.min(),image.max())# %%
importmatplotlib.pyplotasplt# Use matplotlib to quickly plot a histogram.
plt.hist(image.flatten(),bins=np.arange(image.min(),image.max()+1));# %%
# Most frequent pixel value (the mode)
fromscipy.statsimportmodemode(image,axis=None,keepdims=True)
MATLAB
% This MATLAB script illustrates how to explore different ways
% to inspect pixel values and indices
% It is recommended to read comments and to run sections separately
% one after the other with the corresponding command in the Editor Toolstrip
%% Choose and load the image %%
% Read input image
in_image = webread('https://github.com/NEUBIAS/training-resources/raw/master/image_data/xy_8bit__nuclei_noisy_different_intensity.tif');
% Display input image
figure
imagesc(in_image)
axis equal
%% 1 - Explore pixels with mouse (Data Tips) %%
% In the Figure window, click the Data Tips symbol
% (text baloon icon on the top right corner of the image)
% or select from [Tools>Data Cursor] in the Figure Toolstrip
% Now if you click on the image a Data Tip window will appear
% showing the coordinates [X,Y], the pixel intensity [Index]
% and the assigned colour in the current display [R,G,B]
% To exit the Data Tips mode, click again on the Data Tips icon
% To stop displaying Data Tips, right click on the image and select
% [Delete All Data Tips]
% N.B. The point with the lowest coordinates [X,Y = 0,0] is normally found
% on the top left corner
%% 2 - Explore by linescans %%
% Draw a line across the image to evaluate its intensity profile
% 1. Click on the starting point of the line on the image
% 2. Click on the end point of the line on the image
% 3. Press [Enter]
[x_coord, y_coord, line_profile] = improfile;
% Plot sampled line on the image
hold on
plot(x_coord, y_coord, 'w.')
% Create new figure showing the line profile
figure
plot(line_profile, 'k', 'LineWidth', 2)
xlabel('Distance (pixels)')
ylabel('Gray value')
set(findall(gcf, '-property', 'FontSize'), 'FontSize', 14)
%% 3 - Explore by plotting the image histogram %%
% Produce the image histogram
figure
histogram(in_image)
xlabel('Gray value')
ylabel('Counts')
set(findall(gcf, '-property', 'FontSize'), 'FontSize', 14)
% Calculate some metrics from the histogram
% Number of pixels included in the count:
px_count = size(in_image,1)*size(in_image,2);
% Mean gray value
px_mean = nanmean(in_image(:));
% Standard deviation for gray values
px_std = nanstd(double(in_image(:)));
% Minimum gray value
px_min = nanmin(in_image(:));
% Maximum gray value
px_max = nanmax(in_image(:));
% Mode for gray values
[px_mode, px_mode_frequency] = mode(in_image(:));
% Print metrics to screen
fprintf('Count = %i\n', px_count);
fprintf('Mean = %.3f\n', px_mean);
fprintf('StdDev = %.3f\n', px_std);
fprintf('Min = %i\n', px_min);
fprintf('Max = %i\n', px_max);
fprintf('Mode = %i (%i)\n', px_mode, px_mode_frequency);
What is the value of the voxel at the indices (x=93,y=124,z=13)?
Which is the highest value in the image?
Solution
47
255
Explanations
Digital image dimensions
There are several ways to describe the size of a digital image. For example, the following sentences describe the same image.
The image has 2 dimensions, the length of dimension 0 is 200 and the length of dimension 1 is 100.
The image has 2 dimensions, the length of dimension 1 is 200 and the length of dimension 2 is 100.
The image has a size/shape of (200, 100).
The image has 200 x 100 pixels.
Note that “images” in bioimaging can also have more than two dimensions and one typically specifies how to map those dimensions to the physical space (x,y,z, and t). For example, if you acquire a 2-D movie with 100 time points and each movie frame consisting of 256 x 256 pixels it is quite common to represent this as a 3-D array with a shape of ( 256, 256, 100 ) accompanied with metadata such as ( (“x”, 100 nm), (“y”, 100 nm), (“t”, 1 s) ); check out the module on spatial calibration for more details on this.