@@ -327,7 +327,149 @@ fig, ax = plt.subplots()
327
327
plt.imshow(blurred)
328
328
```
329
329
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
+
331
473
332
474
::::::::::::::::::::::::::::::::::::::: challenge
333
475
0 commit comments