Skip to content

Commit 01b6418

Browse files
committed
Update 06-blurring.md to address datacarpentry#221, visualization of image blurring
1 parent 06c4504 commit 01b6418

7 files changed

+136
-1
lines changed

episodes/06-blurring.md

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

332467
::::::::::::::::::::::::::::::::::::::: challenge
333468

110 KB
Loading
108 KB
Loading
25.3 KB
Loading

episodes/fig/petri-dish.png

117 KB
Loading
27.1 KB
Loading
112 KB
Loading

0 commit comments

Comments
 (0)