fit_cie_model: Fit CIE sky model

View source: R/fit_cie_model.R

fit_cie_modelR Documentation

Fit CIE sky model

Description

Fit the CIE sky model to data sampled from a canopy photograph using general-purpose optimization.

Usage

fit_cie_model(
  rr,
  sun_angles,
  custom_sky_coef = NULL,
  std_sky_no = NULL,
  general_sky_type = NULL,
  method = c("Nelder-Mead", "BFGS", "CG", "SANN")
)

Arguments

rr

list, typically the output of extract_rr(). If generated by other means, it must contain:

zenith_dn

numeric vector of length one.

sky_points

data.frame with columns a (azimuth, deg), z (zenith, deg), and rr (relative radiance).

sun_angles

named numeric vector of length two, with components z and a in degrees, e.g., c(z = 49.3, a = 123.1). See estimate_sun_angles() for details.

custom_sky_coef

numeric vector of length five, or numeric matrix with five columns. Custom starting coefficients for optimization. If not provided, coefficients are initialized from standard skies.

std_sky_no

numeric vector. Standard sky numbers as in cie_table. If not provided, all are used.

general_sky_type

character vector of length one. Must be "Overcast", "Clear", or "Partly cloudy". See column general_sky_type in cie_table for details. If not provided, all sky types are used.

method

character vector. Optimization methods passed to stats::optim(). See that function for supported names.

Details

The method is based on \insertCiteLang2010;textualrcaiman. For best results, the input data should show a linear relation between digital numbers and the amount of light reaching the sensor. See extract_radiometry() and read_caim_raw() for details. As a compromise solution, invert_gamma_correction() can be used.

Value

List with the following components:

rr

The input rr with an added pred column in sky_points, containing predicted values.

opt_result

List returned by stats::optim().

coef

Numeric vector of length five. CIE model coefficients.

sun_angles

Numeric vector of length two. Sun zenith and azimuth (degrees).

method

Character string. Optimization method used.

start

Numeric vector of length five. Starting parameters.

metric

Numeric value. Mean squared deviation as in \insertCiteGauch2003;textualrcaiman.

Background

This function is based on \insertCiteLang2010;textualrcaiman. In theory, the best result would be obtained with data showing a linear relation between digital numbers and the amount of light reaching the sensor. See extract_radiometry() and read_caim_raw() for further details. As a compromise solution, invert_gamma_correction() can be used.

Digitizing sky points with ImageJ

The point selection tool of ‘ImageJ’ software can be used to manually digitize points and create a CSV file from which to read coordinates (see Examples). After digitizing the points on the image, this is a recommended workflow: 1. Use the dropdown menu Analyze > Measure to open the Results window. 2. Use File > Save As... to obtain the CSV file.

Use this code to create the input sky_points from ImageJ data:

sky_points <- read.csv(path)
sky_points <- sky_points[c("Y", "X")]
colnames(sky_points) <- c("row", "col")

Digitizing sky points with QGIS

To use the QGIS software to manually digitize points, drag and drop the image in an empty project, create an new vector layer, digitize points manually, save the editions, and close the project.

To create the new vector layer, this is a recommended workflow:

  1. Fo to the dropdown menu Layer > Create Layer > New Geopackage Layer...

  2. Choose "point" in the Geometry type dropdown list

  3. Make sure the CRS is EPSG:7589.

  4. Click on the Toogle Editing icon

  5. Click on the Add Points Feature icon.

Use this code to create the input sky_points from QGIS data:

sky_points <- terra::vect(path)
sky_points <- terra::extract(caim, sky_points, cells = TRUE)
sky_points <- terra::rowColFromCell(caim, sky_points$cell) %>% as.data.frame()
colnames(sky_points) <- c("row", "col")

References

\insertAllCited

Examples

## Not run: 
caim <- read_caim()
z <- zenith_image(ncol(caim), lens())
a <- azimuth_image(z)

# Manual method following Lang et al. (2010)
path <- system.file("external/sky_points.csv",
                    package = "rcaiman")
sky_points <- read.csv(path)
sky_points <- sky_points[c("Y", "X")]
colnames(sky_points) <- c("row", "col")
head(sky_points)
plot(caim$Blue)
points(sky_points$col, nrow(caim) - sky_points$row, col = 2, pch = 10)

# x11()
# plot(caim$Blue)
# sun_angles <- click(c(z, a), 1) %>% as.numeric()
sun_angles <- c(z = 49.5, a = 27.4) #taken with above lines then hardcoded

sun_row_col <- row_col_from_zenith_azimuth(z, a,
                                           sun_angles["z"],
                                           sun_angles["a"])
points(sun_row_col[2], nrow(caim) - sun_row_col[1],
       col = "yellow", pch = 8, cex = 3)

rr <- extract_rr(caim$Blue, z, a, sky_points)

set.seed(7)
model <- fit_cie_model(rr, sun_angles,
                           general_sky_type = "Clear")

plot(model$rr$sky_points$rr, model$rr$sky_points$pred)
abline(0,1)
lm(model$rr$sky_points$pred~model$rr$sky_points$rr) %>% summary()

sky <- cie_image(z, a, model$sun_angles, model$coef) * model$rr$zenith_dn

plot(sky)
ratio <- caim$Blue/sky
plot(ratio)
plot(ratio > 1.05)
plot(ratio > 1.15)

## End(Not run)

rcaiman documentation built on Sept. 9, 2025, 5:42 p.m.