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