Vincent GODARD - V2- 19/01/2024
Freely inspired by :
Sources :
Landsat Thematic Mapper (TM) data from September 10, 1987, West of Worcester, Massachusetts (from the https://clarklabs.org/download/)
scikit-image https://scikit-image.org/
matplotlib https://matplotlib.org/
Compressed file to download => here.
Some libraries are already preinstalled (e.g. Matplotlib). The Skimage library is not, and must be installed.
You then need to load them (Import function).
# To install Skimage, delete the # (before the "!").
# !pip install scikit-image
import skimage # Image processing library
import skimage.io as io # Utility for reading and writing images in various formats (shortened to io).
import matplotlib.pyplot as plt # Library for plotting and visualizing data in graphical form (shortened to plt).
## To find out the version of skimage
skimage.__version__ # warning to "." after skiimage
Importing the skimage version may generate an error message, such as incompatibility with numpy, for example. One of the libraries is too old for the other. An update is therefore required.
## SciPy is a project that brings together Python libraries for scientific use.
## Scipy uses tables and matrices from the NumPy module (https://fr.wikipedia.org/wiki/SciPy).
## Updating scipy, delete the # (before the "!") if necessary.
#!pip install --upgrade scipy
## Then you have to import it
#import scipy
## Then check that this new version is compatible
#scipy.__version__
You may find it useful to take a look at the https://scikit-learn.org/stable/ or https://scikit-image.org/ libraries, some of which have their own wikis in French^^! : https://fr.wikipedia.org/wiki/Scikit-learn or https://fr.wikipedia.org/wiki/Scikit-image.
Reading an image file centered on the Howe Hill region, west of Worcester in Massachusetts (USA). This is the TM4 band (PIR, near infrared) of the Landsat Thematic Mapper (TM) of September 10, 1987.
# Reading with the imread() function before displaying
HOW87TM4 = io.imread('data/how87tm4_grey.jpg')
## Displaying the number of rows, columns and number of channels (if applicable)
## Using the .shape function of the .io module
print(HOW87TM4.shape)
## If you want to dress up the output (text between '', then "," before the .shape function on the HOW87TM4 variable)
print('(number of rows, number of columns):', HOW87TM4.shape)
We may also want to know the depth of our variable (its coding) by its type.
○ The type of a Python object determines what kind of object it is: https://docs.python.org/3/glossary.html#term-type
## Displaying information
print('type :', HOW87TM4.dtype )
The type is an integer (unsigned integer 8bits) encoded on one byte (256 levels of gray, for example).
## Displaying the image in gray level, using the imshow() function of the plt module:
plt.imshow(HOW87TM4, 'gray')
## To choose another color: https://matplotlib.org/stable/tutorials/colors/colormaps.html
## Write anything in place of 'gray', it generates an error message!
## At ValueError, in the list of colors, try others such as :
## viridis' (default color) or 'tab20c_r' to see the effect.
## Pay attention, it's case-sensitive (SHIFT/min)!
## If the image appears too small, we can define a figure dimension where to display our image
plt.figure(figsize = (10,10)) # find who is H and who is L (keywords: plt.figure figsize)
plt.imshow(HOW87TM4, 'gray')
## Be careful to respect proportionality.
## To see, try the 'aspect' parameter (, aspect='auto')
## It's generally unsuitable for geography, as it distorts the proportions in x and y!
plt.imshow(HOW87TM4, 'gray', aspect='auto')
It can be interesting not to work on an entire file, but rather on a sub-region of interest.
## Extracting a region of interest (ROI)
ROI = HOW87TM4[360:460, 120:220] # sub-window size of 100 by 100 pixels in rows and columns
plt.imshow(ROI, 'gray')
## Displaying the number of rows, columns and number of channels (if applicable) of the ROI
print(ROI.shape)
This is its description in number of rows and columns.
## Sampling the original image every 5 pixels
r = HOW87TM4[::5, ::5] # sampling (r = resample) 5x5 without making a subwindow
print('(number of rows, number of columns):', r.shape) # to display the new image size
## To see the effect of sampling
plt.imshow(r, 'gray')
## Sampling the original image every 10 pixels
r = HOW87TM4[::10, ::10] # sampling (r = resample) 10x10 without making a subwindow
print('(number of rows, number of columns):', r.shape) # to display the new image size
## To see the effect of sampling
plt.imshow(r, 'gray')
Here, the image still occupies the same space, but the pixels that make it up are fewer in number and therefore larger!
Does resolution increase or decrease?
It's less fine, it's decreasing!
What happens if you vary the number of rows and columns independently?
## Sample the original image every x pixels in rows and y pixels in columns
y = 2 # select a y value (lines)
x = 4 # select a value for x (columns)
r = HOW87TM4[::y, ::x] # sampling (r = resample) without subwindowing
print('(number of lines, number of columns):', r.shape) # to display the new image size
## To see the effect of sampling
plt.imshow(r, 'gray')
Iterative sampling (Loop) using larger and larger steps without changing the display dimensions.
## Successive sampling in steps from 1 to 50
## Loop successively through all steps
## Beware of ":" at the end of the for loop.
for s in [1, 2, 3, 4, 5, 10, 20, 50]:
r = HOW87TM4[::s, ::s] # s is the sampling step defined in the top line
print(r.shape) # size of sampled image, displayed as title (above)
plt.imshow(r, 'gray') # display of the reduction effect on definition, in gray
plt.show() # line (required) to display successive results stored in memory
There is a degradation in resolution. Pixels get bigger and there are fewer of them for the same space.
## Increase then decrease display dimensions in steps of 0.5 to 50
for s in [0.5, 1, 2, 3, 4, 5, 10, 20, 50]:
plt.figure(figsize=(8/s, 8/s)) # impact of the sample step as denominator on the size of the figure
print('Zoom effect for a sample step value of',s) # sample value displayed as title (above)
plt.imshow(HOW87TM4, 'gray') # dimensional effect display
plt.show() # line (required) to display successive results stored in memory
Equivalent to section 4.2, but where the display is replaced by a recording.
## Successive recordings of sampling steps from 1 to 50
## Loop successively through all steps
## Beware of ":" at the end of the for loop.
for s in [1, 2, 3, 4, 5, 10, 20, 50]:
r = HOW87TM4[::s, ::s] # "s" is the sampling step defined in the top line
io.imsave("data/test{}.png".format(s), r) # successive recording of images called test{s}.png, where {s} takes the sample step
Check in your "data" directory that test{s}.png files, where {s} is replaced by the sample increment value, are present.
Their pixel content is inversely proportional to the step size.
Indicates the number of pixels (dots) per unit of length (dpi, dots per inch) on a physical medium (screen, print, etc.).
## Constant resolution despite reduced definition (pixelation) by sampling in steps of 1 to 50
for s in [1, 2, 3, 4, 5, 10, 20, 50]:
plt.figure(figsize=(8/s, 8/s)) # impact of the sample step as denominator on the size of the figure
r = HOW87TM4[::s, ::s]
print('Number of rows and number of columns',r.shape, 'for a sample step value of', s)
plt.imshow(r, 'gray')
plt.show()
Can you zoom the extract h87tm4_grey.jpg by a factor of 2 (recall 0.5), 3 and then 4?
What is the sampling factor that makes the extract h87tm4_grey.jpg disappear?