The aim of this exercise is to get you familiarised with the structure tensor. You are going to learn how to:
- Use the functionality of the structure tensor.
- Obtain the orientation angle and degree of anisotropy from the structure tensor.
- Visualise the output of the structure tensor.
- Tune the input parameters of the structure tensor.
In some parts of code you will be asked to give user input, write in between the comments ###USER INPUT and ###END OF USER INPUT.
%% Cell type:markdown id: tags:
## Packages
Let's import the packages we will use in this exercise. The most important ones for you to know are:
-[numpy](www.numpy.org) is the basic package for scientific computing with Python.
-[skimage](https://scikit-image.org/) is one of the top image processing libraries in Python. Today, we will use its intput/output module io to read in the images, and the transform module to...
-[matplotlib](http://matplotlib.org) is the most commonly used package for plotting in Python.
-[st2d](https://lab.compute.dtu.dk/QIM/structure-tensor) contains the structure tensor implementation for 2D images by V.A. Dahl (vand@dtu.dk).
-*utilsST* is a Python file containing helper functions for this exercise
%% Cell type:markdown id: tags:
First, run the cell right below to get the structure tensor repository.
If this doesn't work, ignore the cell and instead do the following.
1. Download the [structure tensor repository](https://lab.compute.dtu.dk/QIM/structure-tensor) as a .zip.
2. Extract and rename to 'structure_tensor'
3. Place folder in the directory of this exercise.
Structure tensor information is carried in a (3, 2500) array.
Orientation information is carried in a (2, 2500) array.
%% Cell type:markdown id: tags:
With the structure tensor, we get an orientation value for every pixel, but actually, we are only interested in the orientations of the fibres.
Because the fibres in this image are bright and the background is dark, the orientations can be overlaid on the image by multiplying the image pixels by the orientation values (see below).
We will also use the function `st2d.plot_orientations()` to the visualise the orientations as vectors.
%% Cell type:code id: tags:
``` python
## VISUALISE THE ORIENTATIONS OVERLAID ON THE IMAGE
When visualizing only the dominant orientation, it may seem as the orientation changes abruptly in some areas (e.g. where the fibres merge). These areas where the orientation is smoothly changing from one dominant orientation to another dominant orientation, are actually isotropic, meaning that they do not actually have a preferencial orientation.
%% Cell type:markdown id: tags:
## Part 2. Shape of the Structures
While some image regions may have a preferencial orientation, others don't. In this part, we are going to measure the isotropy of the structures to find out whether they have a preferencial direction. Are they more linear-like (isotropy of a line = 0) or circular-like (isotropy of a circle = 1)? We will use this information to give more importance to the angles in regions with preferential orientations.
The first output of the structure tensor (`val`) indicates how fast the intensities change around a pixel in the two principal directions. Along the first principal direction of a line, the intensities will not change, and `val[0]` will be very small. Along the second principal direction, the intensities will change fast so `val[1]` will be large. For a circle, both values will be equal.
The ratio between the components of `val` will give us the **degree of structural isotropy**. To obtain a more realistic idea of the orientations of our material, we will weigh the dominant orientation by the anisotropy.
Can you find the formula for the anisotropy, given `val[0]` and `val[1]`?
ax[1][2].set_title('Orientation and anisotropy on image')
plt.show()
```
%% Output
%% Cell type:markdown id: tags:
## Part 3. Understand the parameters sigma and rho
The aim of this part of the exercise is to get you familiarised with the parameters sigma and rho.
In the structure tensor, there is a first step to remove noise and a second step to compute the orientations, where the dominant direction is found as the direction in which the intensities change the least. In the first step, noise removal, the image is smoothed with a kernel of size sigma. In the second step, the intensities are integrated around the pixel in a region of size defined by rho.
Now that you know that sigma is related to the scale of the image noise and rho to the scale of the structures of interest, play with the widgets to change the values of the parameters and see the effects on the results. Move the widgets and wait for the image to update.
Set rho low (< 1) and play with the noise level (sigma in 0-1). See how the noise is reduced.
Increase rho and watch the orientations become more smooth as the size of the integration window covers the width of the structures. As rho is increased (try rho > 6), the smaller structures start to disapear in the anisotropy image and the orientations colours start to blend across structures.
%% Cell type:markdown id: tags:
## Part 4. Application: Find whether your sample has a preferencial orientation
The structure tensor is very useful for finding out whether your material has a preferencial orientation. This has numerous applications, from manufacturing of composite materials to understanding blood flow in your body.
We are going to see two examples, one about cardboard fibres and the other about retina vasculature. You will see how the orientation information can be accumulated into a histogram of angles and used to determine the preferencial orientations of your sample, if any!
%% Cell type:markdown id: tags:
### Orientation analysis of carboard fibres.
Here, the orientation information is collected from the whole image. However, as shown above, the orientation information is reliable only in areas of high anisotropy. For this reason, and depending on problem at hand, it may be desirable to weight the orientation using the anisotropy (remove parts with low anisotropy) and/or the intensity (remove the background and keep only information of fibres).
Note: To choose the scale at which you wish to capture the orientations, you may want to first analyse a smaller region of interest so as to visualise the data close-up and determine a sigma, and especially a rho parameter, that provides the orientations you are interested in. See the difference between choosing a rho of 17 and a rho of 2.
%% Cell type:markdown id: tags:
### Orientation information from the OCT image of a retina
%% Cell type:markdown id: tags:
Play with the widget and find the optimal rho value for capturing the orientation of the thicker vessels.
Play with the widget and find the optimal rho value for capturing the orientation of the thicker vessels.
%% Cell type:markdown id: tags:
When working with large amounts of data, the computational time becomes crucial. In [Github](https://github.com/Skielex/structure-tensor/tree/master/structure_tensor) you can find an optimised version of the structure tensor developed at the Technical University of Denmark (DTU)by Niels Jeppesen (niejep@dtu.dk). This implementation provides the option of using the package cupy, instead of numpy, to run the computations on a Graphical Processing Unit (GPU).
When working with large amounts of data, the computational time becomes crucial. In [Github](https://github.com/Skielex/structure-tensor/tree/master/structure_tensor) you can find an optimised version of the structure tensor developed at the Technical University of Denmark (DTU)by Niels Jeppesen (niejep@dtu.dk). This implementation provides the option of using the package cupy, instead of numpy, to run the computations on a Graphical Processing Unit (GPU).
*Please note that the visualisation functions used today would have to be adapted to work with Niels' code, as the output of his functions is in a different format.*
%% Cell type:markdown id: tags:
This workshop exercise was made by Monica J. Emerson (monj@dtu.dk) based on the example scripts by Vedrana A. Dahl (vand@dtu.dk)