# Import modules
import numpy as np
import matplotlib.pyplot as plt
# Suppress warning about diving by zero
= 'ignore'); np.seterr(divide
79 Canopy cover
In this exercise we will learn how to quantify the percent of green canopy cover from downward-facing digital images collected using a point-and-shoot camera or mobile device.
The classification technique uses information in the Red, Green, and Blue (RGB) bands of the image. Each band consists of a 2D matrix of m rows by n columns.
Read and process a single image
# Read example image
= plt.imread('../datasets/images/grassland.jpg')
rgb
# Display image
plt.imshow(rgb)'off')
plt.axis( plt.show()
# Inspect shape
print(rgb.shape)
print(rgb.dtype)
(512, 512, 3)
float32
Images are often represented as unsigned integers of 8 bits. This means that each pixel in each band can only hold one of 256 integer values. Because the range is zero-index, the pixel values can range from 0 to 255. The color of a pixel is repreented by triplet, for example the triplet (0,0,0) represents black, while (255,255,255) represents white. Similarly, the triplet (255,0,0) represents red and (255,220,75) represents a shade of yellow.
# Extract data in separate variable for easier manipulation.
= rgb[:, :, 0] #Extract matrix of red pixel values (m by n matrix)
red = rgb[:, :, 1] #Extract matrix of green pixel values
green = rgb[:, :, 2] #Extract matrix of blue pixel values blue
# Compare shape with original image
print(red.shape)
(512, 512)
# Show information in single bands
=(12,8))
plt.figure(figsize
2,3,1)
plt.subplot(="gray")
plt.imshow(red, cmap'off')
plt.axis(
2,3,2)
plt.subplot(="gray")
plt.imshow(green, cmap'off')
plt.axis(
2,3,3)
plt.subplot(="gray")
plt.imshow(blue, cmap'off')
plt.axis(
# Add histograms using Doane's rule for histogram bins
2,3,4)
plt.subplot(='doane')
plt.hist(red.flatten(), bins
2,3,5)
plt.subplot(='doane')
plt.hist(green.flatten(), bins
2,3,6)
plt.subplot(='doane')
plt.hist(blue.flatten(), bins plt.show()
Find out more about all the different methods for generating hsitogram bins here
# Calculate red to green ratio for each pixel. The result is an m x n array.
= red/green
red_green_ratio
# Calculate blue to green ratio for each pixel. The result is an m x n array.
= blue/green
blue_green_ratio
# Excess green
= 2*green - red - blue ExG
# Let's check the resulting data type of the previous computation
print(red_green_ratio.shape)
print(blue_green_ratio.dtype)
(512, 512)
float32
The size of the array remains unchanged, but Python automatically changes the data type from uint8 to float64. This is great because we need to make use of a continuous numerical scale to classify our green pixels. By generating the color ratios our scale also changes. Let’s look a this using a histogram.
# Plot histogram
plt.figure()='scott')
plt.hist(red_green_ratio.flatten(), bins0.5,1.5)
plt.xlim( plt.show()
# Classification of green pixels
= (red_green_ratio<0.95) & (blue_green_ratio<0.95) & (ExG*255>20) bw
print(bw.shape)
print(bw.dtype)
print(bw.size)
(512, 512)
bool
262144
See that we started with an m x n x 3 (original image) and we finished with and m x n x 2 (binary or classified image)
# Compute percent green canopy cover
= np.sum(bw) / np.size(bw) * 100
canopy_cover print('Green canopy cover:',round(canopy_cover,2),' %')
Green canopy cover: 55.96 %
=(12,4))
plt.figure(figsize
# Original image
1, 2, 1)
plt.subplot(
plt.imshow(rgb)'Original')
plt.title('off')
plt.axis(
# CLassified image
1, 2, 2)
plt.subplot(='gray')
plt.imshow(bw, cmap'Classified')
plt.title('off')
plt.axis(
plt.show()
Classified pixels are displayed in white. The classification for this image is exceptional due to the high contrast between the plant and the background. There are also small regions where our appraoch misclassified grren canopy cover as a consequence of bright spots on the leaves. For many applications this error is small and can be ignored, but this issue highlights the importance of taking high quality pictures in the field.
If possible, take your time to collect high-quality and consistent images. Effective image analysis starts with high quality images.
References
Patrignani, A. and Ochsner, T.E., 2015. Canopeo: A powerful new tool for measuring fractional green canopy cover. Agronomy Journal, 107(6), pp.2312-2320.