# Working with Images Using NumPy

I finished reading “Measure What Matters: How Google, Bono, and the Gates Foundation Rock the World with OKRs” by John Doerr. The book describes a process based on something called OKR. KPIs are in some cases confused with OKRs. OKRs are like KPIs on steroids.

In a nutshell, one specifies an objective / goal and then defines a set of OKRs which need to be completed to achieve the objective. The process has been used by many successful companies and organizations worldwide.

The book is easy and interesting to read. I already created two objectives and a set of OKRs for each. Will let you know in about three months how my OKRs worked.

In one chapter, the book deals with a set of objectives by Bono. The objectives are for Africa. I believe the number one objective was to eradicate HIV/AIDS in Africa. In that same chapter Johannesburg in South Africa is also mentioned.

I know a few things about how hard it is to get a work visa for South Africa. There are large areas containings slums inhabited by millions. Power shortages occur a day at a time every other day.

There are also very large complexes surrounded by barbed wire fences in which higher end homes, stores, schools, golf courses are protected by armed guards.

Perhaps HIV/AIDS has been eradicated using OKRs and people now need to work on so many other issues to get their citizens to the standards of cities in the 21st century.

I recommend the book for the OKRs and how to deploy and use them. I purchased my copy via Amazon Prime.

Now to the main topic of this post which is part of the course “Building Image Processing Applications Using scikit-image” by Janani Ravi offered by PluralSight.

I am taking the course which uses Jupyter notebooks for all exercises. I decided to write the code using Python scripts on VS Code using GitHub Copilot. If interested in the use of Jupyter Notebook I suggest signing up for the PluralSight course. I believe you would enjoy it.

The Python code for this post follows. Note that the associated images are presented in the order they are generated by the script. If we would be using a Jupyter notebook the images would appear immediately following the code that generated them.

```# **** Open folder using VS Code:
#      cd C:\Documents\_Image Processing\scikit-image-building-image-processing-applications\02\demos
#      Run:
#      python WorkingWithImagesUsingNumPy.py ****

# **** imports ****
import skimage                          # skimage is a collection of algorithms for image processing
from skimage import data                # skimage.data is a module that contains a collection of test images

# **** display skimage version ****
print(f"skimage version: {skimage.__version__}")

# **** import numpy ****
import numpy as np                      # NumPy is the fundamental package for scientific computing with Python
import matplotlib.pyplot as plt         # matplotlib.pyplot is a collection of command style functions that make matplotlib work like MATLAB

# used by Jupyter notebook (not needed in VSCode)
# %matplotlib inline

# **** sample_image of 300 x 300 random numbers ****
sample_image = np.random.random((300, 300))

# **** dump sample_image ****
print(f"sample_image: {sample_image}")

# **** display shape of sample_image ****
print(f"sample_image.shape: {sample_image.shape}")

# **** plot sample_image ****
plt.imshow( sample_image,
cmap='gray',                # to display gray images
interpolation='nearest')    # to fill in unknown values using nearest neighbor interpolation
plt.title("sample_image - gray")        # set image title
#plt.xticks([])                         # remove x ticks
#plt.yticks([])                         # remove y ticks

# **** plt. show() starts an event loop, looks for all currently active figure objects,
#      and opens one or more interactive windows that display your figure or figures ****
plt.show()                             # display the plot
```

The associated image follows:

```# **** display sample_image using a different colormap ****
plt.imshow( sample_image,
cmap='Spectral',            # to display spectral images
interpolation='nearest')    # to fill in unknown values using nearest neighbor interpolation
plt.title("sample_image - Spectral")    # set image title
plt.show()                              # display the plot
```

```# **** ****
camera = data.camera()                  # load the camera image

# **** display camera image ****
plt.figure(figsize=(8, 6))              # set the figure width and height in inches
plt.imshow( camera,                     # display the camera image
cmap='gray',                # to display gray images
interpolation='nearest')    # to fill in unknown values using nearest neighbor interpolation
plt.title("camera - gray")              # set the title
plt.show()                              # display the plot
```

```# **** display shape of camera ****
print(f"camera.shape: {camera.shape}")

# **** display contents of camera ****
print(f"camera: {camera}")

# **** display camera type ****
print(f"camera type: {type(camera)}")

# **** display camera size ****
print(f"camera size: {camera.size}")

# **** display camera min, max, and mean ****
print(f"camera min: {camera.min()}")    # min of all pixels
print(f"camera max: {camera.max()}")    # max of all pixels
print(f"camera mean: {camera.mean()}")  # mean (or average) of all pixels

# **** load the tree image ****

# ***** display tree image ****
plt.imshow( tree,
cmap='gray',
interpolation='nearest')    # display the tree image
plt.title("tree - gray")                # set the title
plt.show()                              # display the plot
```

```# **** display shape of tree ****
print(f"tree.shape: {tree.shape}")

# **** generate tree_copy ****
tree_copy = tree.copy()

# **** display pixel at specified location ****
print(f"tree_copy[100, 200]: {tree_copy[100, 200]}")

# **** set pixel at specified location ****
tree_copy[100, 200] = 0

# **** display pixel at specified location ****
print(f"tree_copy[100, 200]: {tree_copy[100, 200]}")

# **** use index slicing operations to set first 100 rows to 0 ****
tree_copy[:100] = 0

# **** print the first 101 rows of tree_copy ****
print(f"tree_copy[:101]: {tree_copy[:101]}")

# **** display tree_copy ****
plt.imshow( tree_copy,
cmap='gray',
interpolation='nearest')    # display the tree image
plt.title("tree_copy - gray")           # set the title
plt.show()                              # display the plot
```

```# **** make a new copy of tree_copy ****
tree_copy = tree.copy()

# **** generate a boolean mask of tree_copy ****

# **** set tree_copy to 255 when mask is true ****
tree_copy[mask] = 255                   # set tree_copy to 255 when mask is true

# **** ****
plt.figure(figsize=(8, 6))              # set the figure width and height in inches

# **** display tree_copy ****
plt.imshow(tree_copy,                   # display the tree image
cmap='gray',                 # to display gray images
interpolation='nearest')     # to fill in unknown values using nearest neighbor interpolation
plt.title("tree_copy - mask == 255")    # set the title
plt.show()                              # display the plot
```

```# **** make a new copy of tree_copy ****
tree_copy = tree.copy()

# **** display tree_copy ****
plt.imshow( tree_copy,                  # display the tree image
cmap='gray',                # to display gray images
interpolation='nearest')    # to fill in unknown values using nearest neighbor interpolation
plt.title("tree_copy - mask == 0")      # set the title
plt.show()                              # display the plot
```

```# **** read parrot image ****

# **** set figure size ****
plt.figure(figsize=(6, 6))              # set the figure width and height in inches

# **** display parrot ****
plt.imshow( parrot,                     # display the parrot image
interpolation='nearest')    # to fill in unknown values using nearest neighbor interpolation
plt.title("parrot")                     # set the title
plt.show()                              # display the plot
```

```# **** display shape of parrot (width, height, channels) ****
print(f"parrot.shape: {parrot.shape}")

# **** display parrot array (R, G, B) ****
print(f"parrot: {parrot}")

# **** RGB, channel at index 2 is the blue channel,
#      the mask finds those pixels where B < 15 ****
blue_mask = parrot[:, :, 2] < 15

# **** generate parrot_copy ****
parrot_copy = parrot.copy()

# **** set pixels where blue_mask is true to 255 ****

# **** set plot figure size ****
plt.figure(figsize=(8, 8))              # set the figure width and height in inches

# **** display parrot_copy ****
plt.imshow( parrot_copy)                # display the parrot image
plt.title("parrot_copy - blue_mask")    # set the title
plt.show()                              # display the plot
```

```# **** RGB, channel at index 0 is the red channel,
#      the mask finds those pixels where R < 15 ****
red_mask = parrot[:, :, 0] < 15

# **** generate parrot_copy ****
parrot_copy = parrot.copy()

# **** set pixels where red_mask is true to 255 ****

# **** set plot figure size ****
plt.figure(figsize=(8, 8))              # set the figure width and height in inches

# **** display parrot_copy ****
plt.imshow(parrot_copy)                 # display the parrot image
plt.title("parrot_copy - red_mask")     # set the title
plt.show()                              # display the plot
```

```# **** zoom on parrot's eye using array slicing operations ****
parrot_zoom = parrot[900:1100, 450:900] # zoom on parrot

# **** display parrot_zoom ****
plt.imshow(parrot_zoom)                 # display the parrot image
plt.title("parrot_zoom")                # set the title
plt.show()                              # display the plot
```

```# **** list of images ****
many_trees = np.array([tree.copy(), tree.copy(), tree.copy(), tree.copy()])

# **** display shape of many_trees (batch_size, height, width) ****
print(f"many_trees.shape: {many_trees.shape}")

# **** generate many parrots ****
many_parrots = np.array([parrot.copy(), parrot.copy(), parrot.copy(), parrot.copy()])

# **** display shape of many_parrots (batch_size, height, width, channels) ****
print(f"many_parrots.shape: {many_parrots.shape}")
```

At this point we have looked at the code and the associated images. Now let’s do a separate pass in which we show the output of the script and the associated images. Note that the images are placed close to where they are generated. If you wish to see a perfect match, then using a Jupyter notebook would be what you are looking for.

```(base) C:\Users\johnc>cd C:\Documents\_Image Processing\scikit-image-building-image-processing-applications\02\demos

(base) C:\Documents\_Image Processing\scikit-image-building-image-processing-applications\02\demos>python WorkingWithImagesUsingNumPy.py
skimage version: 0.20.0
sample_image: [[0.10882985 0.29425012 0.88627065 ... 0.73092717 0.63474604 0.4454356 ]
[0.4426709  0.53180812 0.97602203 ... 0.74006019 0.56982596 0.93546777]
[0.15857075 0.01701707 0.85018165 ... 0.99760108 0.23733934 0.2449101 ]
...
[0.42561409 0.50630503 0.49685106 ... 0.51497759 0.42900991 0.96104672]
[0.03097512 0.43025996 0.02957007 ... 0.72037716 0.08366776 0.91265067]
[0.47070373 0.39533001 0.19200217 ... 0.72305484 0.76436109 0.4893941 ]]
sample_image.shape: (300, 300)
camera.shape: (512, 512)
camera: [[200 200 200 ... 189 190 190]
[200 199 199 ... 190 190 190]
[199 199 199 ... 190 190 190]
...
[ 25  25  27 ... 139 122 147]
[ 25  25  26 ... 158 141 168]
[ 25  25  27 ... 151 152 149]]
camera type: <class 'numpy.ndarray'>
camera size: 262144
camera min: 0
camera max: 255
camera mean: 129.06072616577148
tree.shape: (350, 526)
tree_copy[100, 200]: 0.7450980392156863
tree_copy[100, 200]: 0.0
tree_copy[:101]: [[0.         0.         0.         ... 0.         0.         0.        ]
[0.         0.         0.         ... 0.         0.         0.        ]
[0.         0.         0.         ... 0.         0.         0.        ]
...
[0.         0.         0.         ... 0.         0.         0.        ]
[0.         0.         0.         ... 0.         0.         0.        ]
[0.90588235 0.90588235 0.90196078 ... 0.92156863 0.92156863 0.92156863]]
mask: [[False False False ... False False False]
[False False False ... False False False]
[False False False ... False False False]
...
[False False False ... False False False]
[False False False ... False False False]
[False False False ... False False False]]
parrot.shape: (2848, 4272, 3)
parrot: [[[15 23 12]
[15 23 12]
[16 22 12]
...
[19 20 14]
[19 20 15]
[19 20 15]]

[[15 23 12]
[15 23 12]
[16 22 12]
...
[19 20 14]
[19 20 15]
[19 20 15]]

[[15 23 12]
[15 23 12]
[15 22 14]
...
[19 20 14]
[18 19 14]
[18 19 14]]

...

[[18 32 19]
[18 32 19]
[18 32 17]
...
[15 18 11]
[15 18 11]
[15 18 11]]

[[17 31 18]
[17 31 18]
[18 30 18]
...
[15 18 11]
[15 18 11]
[15 18 11]]

[[16 30 17]
[17 31 18]
[18 30 18]
...
[15 18 11]
[15 18 11]
[15 18 11]]]
blue_mask: [[ True  True  True ...  True False False]
[ True  True  True ...  True False False]
[ True  True  True ...  True  True  True]
...
[False False False ...  True  True  True]
[False False False ...  True  True  True]
[False False False ...  True  True  True]]
red_mask: [[False False False ... False False False]
[False False False ... False False False]
[False False False ... False False False]
...
[False False False ... False False False]
[False False False ... False False False]
[False False False ... False False False]]
many_trees.shape: (4, 350, 526)
many_parrots.shape: (4, 2848, 4272, 3)
```

Looks like mixing Python scripts and images does not convey the best results. My intent is to experiment with VS Code and Github Copilot. That sais, using a Python notebook seems the best approach to present the results. Not sure if I can use Copilot directly from my Python notebook.

Hope you enjoyed this post. The code can be found in my GitHub repository.

John

This site uses Akismet to reduce spam. Learn how your comment data is processed.