|
1 | 1 | """
|
2 | 2 | ==================
|
3 |
| -Image Antialiasing |
| 3 | +Image antialiasing |
4 | 4 | ==================
|
5 | 5 |
|
6 | 6 | Images are represented by discrete pixels, either on the screen or in an
|
|
13 | 13 | used.
|
14 | 14 |
|
15 | 15 | Other anti-aliasing filters can be specified in `.Axes.imshow` using the
|
16 |
| -*interpolation* kwarg. |
| 16 | +*interpolation* keyword argument. |
17 | 17 | """
|
18 | 18 |
|
19 | 19 | import numpy as np
|
20 | 20 | import matplotlib.pyplot as plt
|
21 | 21 |
|
22 | 22 | ###############################################################################
|
23 |
| -# First we generate an image with varying frequency content: |
| 23 | +# First we generate a 500x500 px image with varying frequency content: |
24 | 24 | x = np.arange(500) / 500 - 0.5
|
25 | 25 | y = np.arange(500) / 500 - 0.5
|
26 | 26 |
|
|
32 | 32 |
|
33 | 33 |
|
34 | 34 | ###############################################################################
|
35 |
| -# The following images are subsampled from 1000 data pixels to 604 rendered |
36 |
| -# pixels. The Moire patterns in the "nearest" interpolation are caused by the |
37 |
| -# high-frequency data being subsampled. The "antialiased" image |
| 35 | +# The following images are subsampled from 500 data pixels to 303 rendered |
| 36 | +# pixels. The Moire patterns in the 'nearest' interpolation are caused by the |
| 37 | +# high-frequency data being subsampled. The 'antialiased' image |
38 | 38 | # still has some Moire patterns as well, but they are greatly reduced.
|
39 | 39 | fig, axs = plt.subplots(1, 2, figsize=(7, 4), constrained_layout=True)
|
40 |
| -for n, interp in enumerate(['nearest', 'antialiased']): |
41 |
| - im = axs[n].imshow(a, interpolation=interp, cmap='gray') |
42 |
| - axs[n].set_title(interp) |
| 40 | +for ax, interp in zip(axs, ['nearest', 'antialiased']): |
| 41 | + ax.imshow(a, interpolation=interp, cmap='gray') |
| 42 | + ax.set_title(f"interpolation='{interp}'") |
43 | 43 | plt.show()
|
44 | 44 |
|
45 | 45 | ###############################################################################
|
46 |
| -# Even up-sampling an image will lead to Moire patterns unless the upsample |
47 |
| -# is an integer number of pixels. |
48 |
| -fig, ax = plt.subplots(1, 1, figsize=(5.3, 5.3)) |
49 |
| -ax.set_position([0, 0, 1, 1]) |
50 |
| -im = ax.imshow(a, interpolation='nearest', cmap='gray') |
| 46 | +# Even up-sampling an image with 'nearest' interpolation will lead to Moire |
| 47 | +# patterns when the upsampling factor is not integer. The following image |
| 48 | +# upsamples 500 data pixels to 530 rendered pixels. You may note a grid of |
| 49 | +# 30 line-like artifacts which stem from the 524 - 500 = 24 extra pixels that |
| 50 | +# had to be made up. Since interpolation is 'nearest' they are the same as a |
| 51 | +# neighboring line of pixels and thus stretch the image locally so that it |
| 52 | +# looks distorted. |
| 53 | +fig, ax = plt.subplots(figsize=(6.8, 6.8)) |
| 54 | +ax.imshow(a, interpolation='nearest', cmap='gray') |
| 55 | +ax.set_title("upsampled by factor a 1.048, interpolation='nearest'") |
51 | 56 | plt.show()
|
52 | 57 |
|
53 | 58 | ###############################################################################
|
54 |
| -# The patterns aren't as bad, but still benefit from anti-aliasing |
55 |
| -fig, ax = plt.subplots(1, 1, figsize=(5.3, 5.3)) |
56 |
| -ax.set_position([0, 0, 1, 1]) |
57 |
| -im = ax.imshow(a, interpolation='antialiased', cmap='gray') |
| 59 | +# Better antialiasing algorithms can reduce this effect: |
| 60 | +fig, ax = plt.subplots(figsize=(6.8, 6.8)) |
| 61 | +ax.imshow(a, interpolation='antialiased', cmap='gray') |
| 62 | +ax.set_title("upsampled by factor a 1.048, interpolation='antialiased'") |
58 | 63 | plt.show()
|
59 | 64 |
|
60 | 65 | ###############################################################################
|
61 |
| -# If the small Moire patterns in the default "hanning" antialiasing are |
62 |
| -# still undesireable, then we can use other filters. |
| 66 | +# Apart from the default 'hanning' antialiasing `~.Axes.imshow` supports a |
| 67 | +# number of different interpolation algorithms, which may work better or |
| 68 | +# worse depending on the pattern. |
63 | 69 | fig, axs = plt.subplots(1, 2, figsize=(7, 4), constrained_layout=True)
|
64 |
| -for n, interp in enumerate(['hanning', 'lanczos']): |
65 |
| - im = axs[n].imshow(a, interpolation=interp, cmap='gray') |
66 |
| - axs[n].set_title(interp) |
| 70 | +for ax, interp in zip(axs, ['hanning', 'lanczos']): |
| 71 | + ax.imshow(a, interpolation=interp, cmap='gray') |
| 72 | + ax.set_title(f"interpolation='{interp}'") |
67 | 73 | plt.show()
|
68 | 74 |
|
69 | 75 |
|
|
0 commit comments