Calculating Canopy Gap Fraction With ImageJ From A Hemispherical Photo Hemiphot Guide

User Manual:

Open the PDF directly: View PDF PDF.
Page Count: 3

DownloadCalculating Canopy Gap Fraction With ImageJ From A Hemispherical Photo Hemiphot Guide
Open PDF In BrowserView PDF
Calculating canopy gap fraction with imageJ from a hemispherical
photo
John Godlee
2018_09_02

Part 1 - Taking hemispherical photos
A list of tips for taking good hemispherical photos:
Take photos under a uniformly overcast sky, ideally before the sun has risen too high in the sky, or just before sunset. I find in the morning the photos are generally better and at high latitudes
you will have more time than in the tropics..
Ensure that the camera is level and the lens is pointing straight up. Use the spirit level on the camera hotshoe to do this.
Adjust the tripod so that the top of the camera lens is 1 m above the ground, or above any understorey vegetation, whichever is higher.
Turn the camera so the top of the camera body is facing north, take a compass! This ensures that the top of the captured photo is also facing north, which is necessary for calculating LAI..
Make use of the articulated display on the camera to get a good view of the photo before you take it.
Set the camera:
Manual shooting mode
Manual focus
Set the focus to infinity
Exposure compensation = -0.7
Capturing fine jpeg & RAW images at the same time
The camera time and date is accurate (this is purely for ease of matching photos to sites)
Set the Aperture to 5
Adjust the ISO and shutter speed so the photo is neutrally exposed but the shutter speed is always over 1/60sec, otherwise you will introduce camera shake when you press the button
Take all photos in landscape dimensions, never portait.
Make sure you all duck down below the camera when the image is being taken!
Make sure there is battery and you have the spare battery
Make sure there is an SD card in the camera, and take a spare.
Cover the lens with the lens cap between photos. PLEASE PLEASE PLEASE!!!

Kit list for taking hemispherical photos:
Camera with appropriate fisheye lens
Lens cap for camera
Lens cleaning solution and lens cloth
Tripod
Fully charged battery for camera
SD card for camera
Spirit level hotshoe attachment for camera
Compass
Notebook and pencil
GPS unit
tape measure > 2 m
Waterproof bag to cover camera

Part 2 - Creating a black and white thresholded image
1. Open ImageJ
2. File -> Open , then select an image
3. Visually inspect the image to see that there isn't massive amounts of lens flare. If you have lots of lens flare, the photo should be thrown out! This is what lens flare looks like:

4. Image -> Type -> 8-bit
5. Image -> Adjust -> Threshold , manually adjust the image so all the branches are red and the sky is white, or as near as you can get it.
6. Save the newly thresholded image as a jpeg in a folder called img .
7. Rinse and repeat for all images.

The above process can be automated with a macro, but this assumes that the images are all uniformly exposed.
This is the macro, saved as a .ijm file. This is untested so use at your own risk:

// Automatically create a thresholded image for use in further analysis. Change the values of setThreshold to achieve different results.
// Partially tested
// Save as a Jpeg in the Batch macro dialog in ImageJ
run("8-bit");
run("Threshold...");
setThreshold(0, 146);
setOption("BlackBackground", false);
run("Convert to Mask");

Part 3 - Calculating Leaf Area Index
1. Open RStudio.
2. Open a new script ( File -> New File -> R Script )
3. Save the script in a folder above the images folder:
4. Enter the following preamble into the R script:

# Set working directory to location of thresholded images
setwd("LOCATION_OF_ANALYSIS")
# Source the functions used to calculate stuff
source("hemiphot.R")
# Packages
library(jpeg)

5. Add white_image.jpg to the same folder where the thresholded images are found
6. Read in all the thresholded images and create an empty data frame which will later be filled with canopy trait statistics like LAI and canopy openness.

# List all images in the directory
all_images <- list.files("img/", pattern = ".JPG")
# How many images
img_length = length(all_images)
# Create empty dataframe, 6x7 and fill it with zeroes
all_data = data.frame(matrix(data = 0, nrow = img_length, ncol = 7))
names(all_data) = c("File", "CanOpen", "LAI", "DirectAbove", "DiffAbove", "DirectBelow", "DiffBelow")
# Fill first column with image names
all_data[,1] = all_images

7. Read in the reference image ( white_img.jpg ) as a matrix of pixel values:

white_img <- readJPEG("img/white_image.jpg", native = F)

8. Set some parameters for the location the photos are being taken. Approximate location (0.1 degrees latitude) is good enough for our purposes. Note that the values below are for somewhere in
Africa and should be changed:

location.latitude
location.altitude
location.day
location.days

=
=
=
=

-15
200
30
seq(15,360,30)

# roughly each mid of the 12 months

9. Set some parameters for the images, cropping them to a circle and setting the threshold. These parameters are ones I have used on this camera, so don't need to be changed:

## Image parameters
### Drawing circles and identifying the image centre point
hemi_dim <- dim(white_img)
radius <- max(rowSums(white_img[,,1] > 0.4) / 2)
### determine using
location.cx
location.cy
location.cr
location.threshold

a
=
=
=
=

single image
(hemi_dim[2]
(hemi_dim[1]
radius
0.42 # Must

and fill in here for batch processing
/ 2)
# x coordinate of center of image
/ 2)
# y coordinate of center image
# radius of circle
get this to match all images, or maybe could use a lookup table / dictionary?

Does R have dictionaries?

10. Set some atmospheric parameters. I've loosely estimated these for this location, but by no means is it scientific. I would not have much confidence in the statistics generated using these
parameters, namely DirectAbove , DiffAbove , DirectBelow and DiffBelow .

# atmospheric parameters
## Atmospheric transmissivity - Normally set at 0.6, but can vary between 0.4-0.6 in the tropics
location.tau = 0.6
## Amount of direct light that is used as diffuse light in the Uniform Ovecast Sky (UOC)
location.uoc = 0.15

11. Run a big for loop to calculate the statistics for each photo

for(i in 1:img_length){
## read file
image <- readJPEG(paste("test_img/", all_images[i], sep = ""), native = F)
## conver to Hemi image
image <- Image2Hemiphot(image)
## set cirlce parameters
image <- SetCircle(image, cx = location.cx, cy = location.cy, cr = location.cr)
## select blue channel
image <- SelectRGB(image, "B")
#threshold
image <- ThresholdImage(im = image, th = location.threshold, draw.image = F)
# canopy openness
gap.fractions <- CalcGapFractions(image)
all_data[i,2] = CalcOpenness(fractions = gap.fractions)
## calculate LAI according to Licor's LAI Analyzer
all_data[i,3] = CalcLAI(fractions = gap.fractions)
## Photosynthetic Photon Flux Density (PPDF, umol m-1 s-1) P
rad <- CalcPAR.Day(im = image,
lat = location.latitude, d = location.days,
tau = location.tau, uoc = location.uoc,
draw.tracks = F, full.day = F)
all_data[i,4] = rad[1]
all_data[i,5] = rad[2]
all_data[i,6] = rad[3]
all_data[i,7] = rad[4]
}

12. Finally, look at the output, which is stored in all_data

all_data



Source Exif Data:
File Type                       : PDF
File Type Extension             : pdf
MIME Type                       : application/pdf
PDF Version                     : 1.4
Linearized                      : No
Title                           : Calculating canopy gap fraction with imageJ from a hemispherical photo
Creator                         : wkhtmltopdf 0.12.5
Producer                        : Qt 4.8.7
Create Date                     : 2018:09:08 10:21:11+01:00
Page Count                      : 3
Page Mode                       : UseOutlines
EXIF Metadata provided by EXIF.tools

Navigation menu