Skip to content

Commit d6fdcd9

Browse files
committed
Improve correlation widget; use skimage as ski
1 parent d4c7233 commit d6fdcd9

File tree

1 file changed

+32
-38
lines changed

1 file changed

+32
-38
lines changed

tutorial/02_image_filtering.md

Lines changed: 32 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,16 @@ kernelspec:
1818
%config InlineBackend.figure_format = 'retina'
1919
```
2020

21+
```{code-cell} ipython3
22+
---
23+
slideshow:
24+
slide_type: skip
25+
---
26+
import matplotlib.pyplot as plt
27+
import numpy as np
28+
import skimage as ski
29+
```
30+
2131
+++ {"slideshow": {"slide_type": "slide"}}
2232

2333
# Part 2: Image filtering
@@ -30,15 +40,6 @@ Filtering is one of the most basic and common image operations in image processi
3040

3141
## Local filtering
3242

33-
```{code-cell} ipython3
34-
---
35-
slideshow:
36-
slide_type: skip
37-
---
38-
import matplotlib.pyplot as plt
39-
import numpy as np
40-
```
41-
4243
+++ {"slideshow": {"slide_type": "notes"}}
4344

4445
The "local" in local filtering simply means that a pixel is adjusted by values in some surrounding neighborhood. These surrounding elements are identified or weighted based on a "footprint", "structuring element", or "kernel".
@@ -508,7 +509,6 @@ Here's a small demo of convolution in action.
508509
#--------------------------------------------------------------------------
509510
# Convolution Demo
510511
#--------------------------------------------------------------------------
511-
from skimage import color
512512
from scipy import ndimage as ndi
513513
from matplotlib import patches
514514
@@ -518,19 +518,21 @@ def mean_filter_demo(image, vmax=1):
518518
519519
image_cache = []
520520
521+
fig = plt.figure(figsize=(10, 5))
522+
521523
def mean_filter_step(i_step):
522524
while i_step >= len(image_cache):
523525
filtered = image if i_step == 0 else image_cache[-1][-1][-1]
524526
filtered = filtered.copy()
525527
526528
(i, j), mask, subimage = next(iter_kernel_and_subimage)
527-
filter_overlay = color.label2rgb(mask, image, bg_label=0,
529+
filter_overlay = ski.color.label2rgb(mask, image, bg_label=0,
528530
colors=('cyan', 'red'))
529531
filtered[i, j] = np.sum(mean_factor * subimage)
530532
image_cache.append(((i, j), (filter_overlay, filtered)))
531533
532534
(i, j), images = image_cache[i_step]
533-
fig, axes = plt.subplots(1, len(images), figsize=(10, 5))
535+
axes = fig.subplots(1, len(images))
534536
535537
for ax, imc in zip(axes, images):
536538
ax.imshow(imc, vmax=vmax, cmap="gray")
@@ -592,9 +594,7 @@ Let's consider a real image now. It'll be easier to see some of the filtering we
592594
slideshow:
593595
slide_type: fragment
594596
---
595-
from skimage import data
596-
597-
image = data.camera()
597+
image = ski.data.camera()
598598
pixelated = image[::10, ::10]
599599
fig, (ax0, ax1) = plt.subplots(1, 2, figsize=(10, 5))
600600
ax0.imshow(image, cmap="gray")
@@ -610,10 +610,8 @@ Here we use a step of 10, giving us every tenth column and every tenth row of th
610610
We are actually going to be using the pattern of plotting multiple images side by side quite often, so we are going to make the following helper function:
611611

612612
```{code-cell} ipython3
613-
from skimage import img_as_float
614-
615613
def imshow_all(*images, titles=None):
616-
images = [img_as_float(img) for img in images]
614+
images = [ski.util.img_as_float(img) for img in images]
617615
618616
if titles is None:
619617
titles = [''] * len(images)
@@ -672,11 +670,9 @@ slideshow:
672670
slide_type: notes
673671
---
674672
# Rename module so we don't shadow the builtin function
675-
from skimage import filters
676-
677673
smooth_mean = ndi.correlate(bright_square, mean_kernel)
678674
sigma = 1
679-
smooth = filters.gaussian(bright_square, sigma)
675+
smooth = ski.filters.gaussian(bright_square, sigma)
680676
imshow_all(bright_square, smooth_mean, smooth,
681677
titles=['original', 'result of mean filter', 'result of gaussian filter'])
682678
```
@@ -692,11 +688,10 @@ For a real image, we get the following:
692688
slideshow:
693689
slide_type: fragment
694690
---
695-
from skimage import img_as_float
696691
# The Gaussian filter returns a float image, regardless of input.
697692
# Cast to float so the images have comparable intensity ranges.
698-
pixelated_float = img_as_float(pixelated)
699-
smooth = filters.gaussian(pixelated_float, sigma=1)
693+
pixelated_float = ski.util.img_as_float(pixelated)
694+
smooth = ski.filters.gaussian(pixelated_float, sigma=1)
700695
imshow_all(pixelated_float, smooth)
701696
```
702697

@@ -711,8 +706,8 @@ slideshow:
711706
---
712707
size = 20
713708
structuring_element = np.ones((3*size, 3*size))
714-
smooth_mean = filters.rank.mean(image, structuring_element)
715-
smooth_gaussian = filters.gaussian(image, size)
709+
smooth_mean = ski.filters.rank.mean(image, structuring_element)
710+
smooth_gaussian = ski.filters.gaussian(image, size)
716711
titles = ['mean', 'gaussian']
717712
imshow_all(smooth_mean, smooth_gaussian, titles=titles)
718713
```
@@ -736,7 +731,7 @@ sidelen = 45
736731
sigma = (sidelen - 1) // 2 // 4
737732
spot = np.zeros((sidelen, sidelen), dtype=float)
738733
spot[sidelen // 2, sidelen // 2] = 1
739-
kernel = filters.gaussian(spot, sigma=sigma)
734+
kernel = ski.filters.gaussian(spot, sigma=sigma)
740735
741736
imshow_all(spot, kernel / np.max(kernel))
742737
```
@@ -829,7 +824,7 @@ The Sobel filter, the most commonly used edge filter, should look pretty similar
829824
slideshow:
830825
slide_type: fragment
831826
---
832-
imshow_all(bright_square, filters.sobel(bright_square))
827+
imshow_all(bright_square, ski.filters.sobel(bright_square))
833828
```
834829

835830
+++ {"slideshow": {"slide_type": "notes"}}
@@ -843,7 +838,7 @@ Like any derivative, noise can have a strong impact on the result:
843838
slideshow:
844839
slide_type: fragment
845840
---
846-
pixelated_gradient = filters.sobel(pixelated)
841+
pixelated_gradient = ski.filters.sobel(pixelated)
847842
imshow_all(pixelated, pixelated_gradient)
848843
```
849844

@@ -856,7 +851,7 @@ Smoothing is often used as a preprocessing step in preparation for feature detec
856851
slideshow:
857852
slide_type: fragment
858853
---
859-
gradient = filters.sobel(smooth)
854+
gradient = ski.filters.sobel(smooth)
860855
titles = ['gradient before smoothing', 'gradient after smoothing']
861856
# Scale smoothed gradient up so they're of comparable brightness.
862857
@@ -874,7 +869,7 @@ Notice how the edges look more continuous in the smoothed image.
874869
Let's pretend we have an image and a "ground truth" image of what we want to detect:
875870

876871
```{code-cell} ipython3
877-
target = (filters.sobel_h(image) > 0.07)
872+
target = (ski.filters.sobel_h(image) > 0.07)
878873
imshow_all(image, target, titles=['source', 'target'])
879874
```
880875

@@ -912,9 +907,8 @@ The median filter is the classic edge-preserving filter. As the name implies, th
912907
slideshow:
913908
slide_type: fragment
914909
---
915-
from skimage.morphology import disk
916-
neighborhood = disk(radius=1) # "selem" is often the name used for "structuring element"
917-
median = filters.rank.median(pixelated, neighborhood)
910+
neighborhood = ski.morphology.disk(radius=1) # "selem" is often the name used for "structuring element"
911+
median = ski.filters.rank.median(pixelated, neighborhood)
918912
titles = ['image', 'gaussian', 'median']
919913
imshow_all(pixelated, smooth, median, titles=titles)
920914
```
@@ -928,10 +922,10 @@ This difference is more noticeable with a more detailed image.
928922
slideshow:
929923
slide_type: fragment
930924
---
931-
neighborhood = disk(10)
932-
coins = data.coins()
933-
mean_coin = filters.rank.mean(coins, neighborhood)
934-
median_coin = filters.rank.median(coins, neighborhood)
925+
neighborhood = ski.morphology.disk(10)
926+
coins = ski.data.coins()
927+
mean_coin = ski.filters.rank.mean(coins, neighborhood)
928+
median_coin = ski.filters.rank.median(coins, neighborhood)
935929
titles = ['image', 'mean', 'median']
936930
imshow_all(coins, mean_coin, median_coin, titles=titles)
937931
```

0 commit comments

Comments
 (0)