Skip to content

Commit e2d1e9a

Browse files
committed
markdown source builds
Auto-generated via `{sandpaper}` Source : 55d9ef0 Branch : main Author : Laura Murphy <Laura.murphy@igmm.ed.ac.uk> Time : 2026-04-30 12:54:08 +0000 Message : Merge pull request #10 from lauracmurphy/bioio-integration
1 parent 45cba6c commit e2d1e9a

40 files changed

Lines changed: 2170 additions & 0 deletions

01-opening-and-checking-an-image.md

Lines changed: 472 additions & 0 deletions
Large diffs are not rendered by default.

02-applying-filters.md

Lines changed: 245 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,245 @@
1+
---
2+
title: 'Applying Filters'
3+
teaching: 40
4+
exercises: 20
5+
---
6+
7+
:::::::::::::::::::::::::::::::::::::: questions
8+
- How can I make it possible to isolate features in my images?
9+
::::::::::::::::::::::::::::::::::::::::::::::::
10+
11+
::::::::::::::::::::::::::::::::::::: objectives
12+
- Apply mean and Gaussian filters to an image
13+
- Select one of these filtered images to use for processing in subsequent chapters
14+
::::::::::::::::::::::::::::::::::::::::::::::::
15+
16+
## Filters
17+
18+
Images often need to have noise removed in order for the results of further
19+
processing to be meaningful. There are many smoothing filters available, each
20+
with their own advantages depending on the situation and the image in question.
21+
Here are two to get started:
22+
23+
- [mean filter](https://scikit-image.org/docs/stable/api/skimage.filters.rank.html#skimage.filters.rank.mean)
24+
- [Gaussian filter](https://scikit-image.org/docs/stable/api/skimage.filters.html#skimage.filters.Gaussian)
25+
26+
A mean filter will, for each pixel:
27+
28+
- Create a **kernel** of pixels around it, in a size/shape of the user's choosing
29+
- Take the mean of all pixels within this kernel
30+
- Assign this new value to the pixel
31+
32+
The kernel in this case can be considered analogous to a 2-dimensional sliding window.
33+
34+
A Gaussian filter is similar to a mean filter, except that pixels near the centre of
35+
the kernel will have a greater effect on the result.
36+
37+
You can create a kernel with skimage:
38+
39+
```python
40+
from skimage.morphology import square
41+
kernel = square(3) # create a 3x3 square kernel
42+
```
43+
44+
There are other shapes of kernel that can be used, and are documented in the
45+
[morphology section](https://scikit-image.org/docs/stable/api/skimage.morphology.html)
46+
of the skimage docs.
47+
48+
Note that as of skimage 0.25.0, the `square` function has been deprecated in
49+
favour of a new function, [footprint_rectangle](https://scikit-image.org/docs/stable/api/skimage.morphology.html#skimage.morphology.footprint_rectangle):
50+
51+
```python
52+
from skimage.morphology import footprint_rectangle
53+
kernel = square((3, 3)) # also a 3x3 square kernel
54+
```
55+
56+
::::::::::::::::::::::::::::::::::::: challenge
57+
## Exercise 6: Applying filters
58+
59+
Look at the documentation pages for the mean and Gaussian filters above. Load a frame from the second channel
60+
of the test image [skimage.data.cells3d](https://scikit-image.org/docs/stable/api/skimage.data.html#skimage.data.cells3d):
61+
62+
```python
63+
from skimage.data import cells3d
64+
65+
image = cells3d()[30, 1, :, :]
66+
```
67+
68+
Build a figure displaying this image in each of the following forms:
69+
70+
- original image
71+
- mean filter using a 3x3 square kernel
72+
- mean filter using a 9x9 square kernel
73+
- Gaussian filter of sigma = 1
74+
- Gaussian filter of sigma = 5
75+
76+
How do the different methods compare?
77+
78+
:::::::::::::::::::::::: solution
79+
```python
80+
from skimage.data import cells3d
81+
from skimage.filters import gaussian
82+
from skimage.filters.rank import mean
83+
from skimage.morphology.footprints import square
84+
85+
image = cells3d()[30, 1, :, :]
86+
plt.figure(figsize=(10, 12))
87+
88+
plt.subplot(3, 2, 1)
89+
plt.imshow(image)
90+
plt.title('Original')
91+
92+
plt.subplot(3, 2, 2)
93+
plt.imshow(mean(image, footprint=square(3)))
94+
plt.title('3x3 mean filter')
95+
96+
plt.subplot(3, 2, 3)
97+
plt.imshow(mean(image, footprint=square(9)))
98+
plt.title('9x9 mean filter')
99+
100+
plt.subplot(3, 2, 4)
101+
plt.imshow(gaussian(image, sigma=1))
102+
plt.title('Gaussian blur, σ=1')
103+
104+
plt.subplot(3, 2, 5)
105+
plt.imshow(gaussian(image, sigma=5))
106+
plt.title('Gaussian blur, σ=5')
107+
```
108+
109+
![](fig/2_1_filters.jpg){alt='Filters'}
110+
111+
Larger kernels and sigma values will result in a greater smoothing
112+
effect and a more blurred image - as you can see, it is possible to
113+
over-blur the image.
114+
:::::::::::::::::::::::::::::::::
115+
:::::::::::::::::::::::::::::::::::::::::::::::
116+
117+
## Removing the background
118+
119+
Eventually we're going to want to isolate the foreground from the background. In some
120+
images, this may be difficult especially if the two are not entirely distinct from each
121+
other, or if the background is not a uniform shade. In cases like this, a rolling ball
122+
algorithm can be applied. The rolling ball estimates the background intensity of an
123+
image by using the pixel values to translate the image into a height map, and then
124+
rolling a ball of a given radius across it. The rolling ball algorithm has been
125+
published and a [figure](https://www.researchgate.net/figure/Schematic-diagram-of-background-subtraction-by-the-rolling-ball-method-the-histogram_fig3_319985119)
126+
from the publication describes how it works.
127+
128+
::::::::::::::::::::::::::::::::::::: challenge
129+
## Exercise 7: Rolling ball background intensity
130+
131+
Look at the [scikit-image documentation](https://scikit-image.org/docs/stable/auto_examples/segmentation/plot_rolling_ball.html)
132+
on the rolling ball filter. Load the example image [skimage.data.coins](https://scikit-image.org/docs/stable/api/skimage.data.html#skimage.data.coins)
133+
and display:
134+
135+
- the original image
136+
- image with a rolling ball of radius 100 applied
137+
- image with a rolling ball of radius 50 applied
138+
- the image with the radius=50 rolling ball subtracted from it
139+
140+
:::::::::::::::::::::::: solution
141+
142+
Compute time can be found using Python's datetime library:
143+
144+
```python
145+
from skimage.data import coins
146+
from skimage.restoration import rolling_ball
147+
148+
image = coins()
149+
plt.figure(figsize=(10, 8))
150+
151+
plt.subplot(2, 2, 1)
152+
plt.imshow(image, cmap='gray')
153+
plt.title('Original')
154+
155+
plt.subplot(2, 2, 2)
156+
rolling_ball_100 = rolling_ball(image, radius=100)
157+
plt.imshow(rolling_ball_100, cmap='gray')
158+
plt.title('Rolling ball, r=100')
159+
160+
plt.subplot(2, 2, 3)
161+
rolling_ball_50 = rolling_ball(image, radius=50)
162+
plt.imshow(rolling_ball_50, cmap='gray')
163+
plt.title('Rolling ball, r=50')
164+
165+
plt.subplot(2, 2, 4)
166+
plt.imshow(image - rolling_ball_50)
167+
plt.title('Original - rolling ball r50')
168+
```
169+
170+
![](fig/2_2_rolling_ball.jpg){alt='Rolling ball'}
171+
172+
:::::::::::::::::::::::::::::::::
173+
:::::::::::::::::::::::::::::::::::::::::::::::
174+
175+
## Dogs and logs
176+
177+
Difference of Gaussian (DoG) and Laplacian of Gaussian (LoG) are algorithms that build on
178+
the Gaussian filter.
179+
180+
In a [Difference of Gaussian](https://scikit-image.org/docs/stable/api/skimage.filters.html#skimage.filters.difference_of_gaussians),
181+
two Gaussian filters are taken of the image, each with a different sigma value.
182+
The larger filter is then subtracted from the first to give an image where
183+
features are effectively highlighted by an area of high contrast.
184+
185+
In a Laplacian of Gaussian, a Gaussian-filtered image is supplied to a
186+
[Laplace](https://scikit-image.org/docs/stable/api/skimage.filters.html#skimage.filters.laplace)
187+
filter. This eliminates the need to manually select two sigma values as with Difference of Gaussian.
188+
189+
::::::::::::::::::::::::::::::::::::: challenge
190+
## Exercise 8: Dogs and logs
191+
192+
Load a frame from the second channel of [skimage.data.cells3d()](https://scikit-image.org/docs/stable/api/skimage.data.html#skimage.data.cells3d)
193+
again:
194+
195+
```python
196+
from skimage.data import cells3d
197+
198+
image = cells3d()[30, 1, :, :]
199+
```
200+
201+
Display a figure of:
202+
203+
- The original image
204+
- Image with a Difference of Gaussians applied with sigma values 2 and 4
205+
- Image with a Laplacian of Gaussians applied. Note that the Laplace filter linked
206+
above does not perform the Gaussian filter for you, so you will need to pass the
207+
image through `gaussian()` first.
208+
209+
:::::::::::::::::::::::: solution
210+
211+
```python
212+
from skimage.data import cells3d
213+
from skimage.filters import gaussian, difference_of_gaussians, laplace
214+
215+
image = cells3d()[30, 1, :, :]
216+
plt.figure(figsize=(10, 12))
217+
218+
plt.subplot(2, 2, 1)
219+
plt.imshow(image)
220+
plt.title('Original')
221+
222+
plt.subplot(2, 2, 2)
223+
plt.imshow(difference_of_gaussians(image, 1, 2), cmap='gray')
224+
plt.title('Difference of Gaussians')
225+
226+
plt.subplot(2, 2, 3)
227+
plt.imshow(laplace(gaussian(image, sigma=2)), cmap='gray')
228+
plt.title('Laplacian of Gaussian')
229+
```
230+
231+
![](fig/2_3_dogs_and_logs.jpg){alt='Dogs and logs'}
232+
233+
:::::::::::::::::::::::::::::::::
234+
235+
## Exercise 9: Choosing a filter
236+
237+
Look at the images you produced in exercises 6 and 8, and select one to use in
238+
subsequent chapters for thresholding and segmentation!
239+
:::::::::::::::::::::::::::::::::::::::::::::::
240+
241+
::::::::::::::::::::::::::::::::::::: keypoints
242+
- There are many ways of smoothing an image
243+
- Different methods will perform better in different situations
244+
::::::::::::::::::::::::::::::::::::::::::::::::
245+

0 commit comments

Comments
 (0)