|
| 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 | +{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 | +{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 | +{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