Skip to content

Commit 68be0d4

Browse files
committed
markdown source builds
Auto-generated via {sandpaper} Source : 1a34167 Branch : main Author : Toby Hodges <tbyhdgs@gmail.com> Time : 2023-08-16 10:12:36 +0000 Message : Merge pull request #292 from chbrandt/chbrandt-patch-1 Add visualizations to better explain image blurring in episode 6
1 parent dd9cf28 commit 68be0d4

8 files changed

+144
-2
lines changed

06-blurring.md

Lines changed: 143 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -327,7 +327,149 @@ fig, ax = plt.subplots()
327327
plt.imshow(blurred)
328328
```
329329

330-
![](fig/gaussian-blurred.png){alt='Original image'}
330+
![](fig/gaussian-blurred.png){alt='Blurred image'}
331+
332+
333+
## Visualising Blurring
334+
335+
Somebody said once "an image is worth a thousand words".
336+
What is actually happening to the image pixels when we apply blurring may be
337+
difficult to grasp, let's now visualise the effects of blurring from a different
338+
perspective.
339+
340+
Let's use the petri-dish image from previous episodes:
341+
342+
![
343+
Graysacle version of the Petri dish image
344+
](fig/petri-dish.png){alt='Bacteria colony'}
345+
346+
What we want to see here is the pixel intensities from a lateral perspective,
347+
we want to see the profile of intensities .
348+
For instance, let's look for the intensities of the pixels along the horizontal
349+
at `Y=150`:
350+
351+
```python
352+
import matplotlib.pyplot as plt
353+
import imageio.v3 as iio
354+
import skimage.color
355+
356+
# read colonies color image and convert to grayscale:
357+
#
358+
image = iio.imread('data/colonies-01.tif')
359+
image_gray = skimage.color.rgb2gray(image)
360+
361+
# define the pixels we want to view the intensities (profile)
362+
#
363+
xmin, xmax = (0, image_gray.shape[1])
364+
ymin = ymax = 150
365+
366+
# view the image indicating the profile pixels position
367+
#
368+
fig,ax = plt.subplots()
369+
ax.imshow(image_gray, cmap='gray')
370+
ax.plot([xmin,xmax], [ymin,ymax], color='red')
371+
```
372+
373+
![
374+
Grayscale Petri dish image marking selected pixels for profiling
375+
](fig/petri-selected-pixels-marker.png){
376+
alt='Bacteria colony image with selected pixels marker'
377+
}
378+
379+
The intensity of those pixels we can see with a simple line plot:
380+
381+
```python
382+
# Just rename our "Y" variables for a better reading
383+
#
384+
Y = ymin = ymax
385+
386+
# Select the vector of pixels along "Y"
387+
#
388+
image_gray_pixels_slice = image_gray[Y, :]
389+
390+
# Guarantee the intensity values are in the [0:255] range (unsigned integers)
391+
#
392+
image_gray_pixels_slice = img_as_ubyte(image_gray_pixels_slice)
393+
394+
fig = plt.figure()
395+
ax = fig.add_subplot()
396+
397+
ax.plot(image_gray_pixels_slice, color='red')
398+
ax.set_ylim(255, 0)
399+
ax.set_ylabel('L')
400+
ax.set_xlabel('X')
401+
```
402+
403+
![
404+
Intensities profile line plot of pixels along Y=150 in original image
405+
](fig/petri-original-intensities-plot.png){
406+
alt='Pixel intensities profile in original image'
407+
}
408+
409+
And now, how does the same set of pixels look in the corresponding *blurred* image:
410+
411+
```python
412+
# First, let's create a blurred version of (grayscale) image
413+
#
414+
from skimage.filters import gaussian
415+
416+
image_blur = gaussian(image_gray, sigma=3)
417+
418+
# Like before, plot the pixels profile along "Y"
419+
#
420+
image_blur_pixels_slice = image_blur[Y,:]
421+
image_blur_pixels_slice = img_as_ubyte(image_blur_pixels_slice)
422+
423+
fig = plt.figure()
424+
ax = fig.add_subplot()
425+
426+
ax.plot(image_blur_pixels_slice, 'red')
427+
ax.set_ylim(255, 0)
428+
ax.set_ylabel('L')
429+
ax.set_xlabel('X')
430+
```
431+
432+
![
433+
Intensities profile of pixels along Y=150 in *blurred* image
434+
](fig/petri-blurred-intensities-plot.png){
435+
alt='Pixel intensities profile in blurred image'
436+
}
437+
438+
And that is why *blurring* is also called *smoothing*.
439+
This is how low-pass filters affect neighbouring pixels.
440+
441+
Now that we saw the effects of blurring an image from
442+
two different perspectives, front and lateral, let's take
443+
yet another look using a 3D visualisation.
444+
445+
:::::::::::::::::::::::::::::::::::::::::: callout
446+
447+
### 3D Plots with matplotlib
448+
The code to generate these 3D plots is outside the scope of this lesson
449+
but can be viewed by following the links in the captions.
450+
451+
::::::::::::::::::::::::::::::::::::::::::::::::::
452+
453+
454+
![
455+
A 3D plot of pixel intensities across the whole Petri dish image before blurring.
456+
[Explore how this plot was created with matplotlib](https://gist.github.com/chbrandt/63ba38142630a0586ba2a13eabedf94b).
457+
Image credit: [Carlos H Brandt](https://github.com/chbrandt/).
458+
](fig/3D_petri_before_blurring.png){
459+
alt='3D surface plot showing pixel intensities across the whole example Petri dish image before blurring'
460+
}
461+
462+
![
463+
A 3D plot of pixel intensities after Gaussian blurring of the Petri dish image.
464+
Note the 'smoothing' effect on the pixel intensities of the colonies in the image,
465+
and the 'flattening' of the background noise at relatively low pixel intensities throughout the image.
466+
[Explore how this plot was created with matplotlib](https://gist.github.com/chbrandt/63ba38142630a0586ba2a13eabedf94b).
467+
Image credit: [Carlos H Brandt](https://github.com/chbrandt/).
468+
](fig/3D_petri_after_blurring.png){
469+
alt='3D surface plot illustrating the smoothing effect on pixel intensities across the whole example Petri dish image after blurring'
470+
}
471+
472+
331473

332474
::::::::::::::::::::::::::::::::::::::: challenge
333475

fig/3D_petri_after_blurring.png

110 KB
Loading

fig/3D_petri_before_blurring.png

108 KB
Loading
25.3 KB
Loading

fig/petri-dish.png

117 KB
Loading
27.1 KB
Loading

fig/petri-selected-pixels-marker.png

112 KB
Loading

md5sum.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
"episodes/03-skimage-images.md" "2ed4f295d98a05ab0c98550b1dd210f3" "site/built/03-skimage-images.md" "2023-08-16"
99
"episodes/04-drawing.md" "f1c7af067155a6b9c82a932d4cfe65d3" "site/built/04-drawing.md" "2023-07-26"
1010
"episodes/05-creating-histograms.md" "3bf31d32ff27f76d149c26d7c7ab4662" "site/built/05-creating-histograms.md" "2023-07-26"
11-
"episodes/06-blurring.md" "f8389e7a45f224c63d68a219b0c08a09" "site/built/06-blurring.md" "2023-07-26"
11+
"episodes/06-blurring.md" "d6ada53a402a2b2e9c39220d7cb67b6e" "site/built/06-blurring.md" "2023-08-16"
1212
"episodes/07-thresholding.md" "23787e4d84f2c46e532e4a2f1267cd55" "site/built/07-thresholding.md" "2023-07-26"
1313
"episodes/08-connected-components.md" "aed2d508ba209ab4c7ed6e3b12be20cd" "site/built/08-connected-components.md" "2023-07-26"
1414
"episodes/09-challenges.md" "e3342f430b45f5480d797b6d54b79bce" "site/built/09-challenges.md" "2023-07-26"

0 commit comments

Comments
 (0)