View source: R/extract_radiometry.R
extract_radiometry | R Documentation |
Buid a datasets for vignetting modeling by sistematically extracting
radiometry from images taken with the aid of a portable light source and the
calibration board detailed in calibrate_lens()
.
extract_radiometry(l, size_px = NULL)
l |
list of preprocessed images (terra::SpatRaster) suitable for radiometry sampling. Images must comply with the equidistant projection. |
size_px |
numeric vector of length one. Diameter (pixels) of the
circular sampling area at the image center; off-center, the sampled region
becomes an ellipse under the equidistant projection. If |
data.frame
con dos columnas:
theta
zenith angle en radianes.
radiometry
digital number normalizado.
Lenses have the inconvenient property of increasingly attenuating light along the direction orthogonal to the optical axis. This phenomenon is known as the vignetting effect and varies with lens model and aperture setting. The method outlined here, known as the simple method, is explained in details in \insertCiteDiaz2024;textualrcaiman. Next explanation might serve mostly as a quick recap of it.
The development of the simple method was done with a Kindle Paperwhite eBooks
reader of 6" with built-in light. However, an iPhone 6 plus was also tested
in the early stages of development and no substantial differences were
observed. A metal bookends desk book holder was used to fasten the eBook
reader upright and a semi-transparent paper to favor a Lambertian light
distribution. In addition, the latter was used to draw on in order to
guide pixel sampling. The book holder also facilitated the alignment of the
screen with the dotted lines of the printed quarter-circle.
As a general guideline, a wide variety of mobile devices could be used as
light sources, but if scattered data points are obtained with it, then other
light sources should be tested in order to double check that the light
quality is not the reason for points scattering.
With the room only illuminated by the portable light source, nine photographs
should be taken with the light source located in the equivalent to 0, 10, 20,
30, 40, 50, 60, 70, and 80 degrees of zenith angle, respectively. Camera
configuration should be in manual mode and set with the aperture (f/number)
for which a vignetting function is required. The shutter speed should be
regulated to obtain light-source pixels with middle grey values. The nine
photographs should be taken without changing the camera configuration and
the light conditions.
This code exemplifies how to use the function to obtain data and base R
functions to obtain the vignetting function (
f_v
).
zenith_colrow <- c(1500, 997) diameter <- 947*2 z <- zenith_image(diameter, c(0.689, 0.0131, -0.0295)) a <- azimuth_image(z) .read_raw <- function(path_to_raw_file) { r <- read_caim_raw(path_to_raw_file, only_blue = TRUE) r <- crop_caim(r, zenith_colrow - diameter/2, diameter, diameter) r <- fisheye_to_equidistant(r, z, a, m, radius = diameter/2, k = 1, p = 1, rmax = 100) } l <- Map(.read_raw, dir("raw/up/", full.names = TRUE)) up_data <- extract_radiometry(l) l <- Map(.read_raw, dir("raw/down/", full.names = TRUE)) down_data <- extract_radiometry(l) l <- Map(.read_raw, dir("raw/right/", full.names = TRUE)) right_data <- extract_radiometry(l) l <- Map(.read_raw, dir("raw/left/", full.names = TRUE)) left_data <- extract_radiometry(l) ds <- rbind(up_data, down_data, right_data, left_data) plot(ds, xlim = c(0, pi/2), ylim= c(0.5,1.05), col = c(rep(1,9),rep(2,9),rep(3,9),rep(4,9))) legend("bottomleft", legend = c("up", "down", "right", "left"), col = 1:4, pch = 1) fit <- lm((1 - ds$radiometry) ~ poly(ds$theta, 3, raw = TRUE) - 1) summary(fit) coef <- -fit$coefficients #did you notice the minus sign? .fv <- function(x) 1 + coef[1] * x + coef[2] * x^2 + coef[3] * x^3 curve(.fv, add = TRUE, col = 2) coef
Once one of the aperture settings is calibrated, it can be used to calibrate all the rest. To do so, the equipment should be used to take photographs in all desired exposition and without moving the camera, including the aperture already calibrated and preferably under an open sky in stable diffuse light conditions. Below code can be used as a template.
zenith_colrow <- c(1500, 997) diameter <- 947*2 z <- zenith_image(diameter, c(0.689, 0.0131, -0.0295)) a <- azimuth_image(z) files <- dir("raw/", full.names = TRUE) l <- list() for (i in seq_along(files)) { if (i == 1) { # because the first aperture was the one already calibrated .read_raw <- function(path_to_raw_file) { r <- read_caim_raw(path_to_raw_file, only_blue = TRUE) r <- crop_caim(r, zenith_colrow - diameter/2, diameter, diameter) r <- correct_vignetting(r, z, c(0.0302, -0.320, 0.0908)) r <- fisheye_to_equidistant(r, z, a, m, radius = diameter/2, k = 1, p = 1, rmax = 100) } } else { .read_raw <- function(path_to_raw_file) { r <- read_caim_raw(path_to_raw_file, only_blue = TRUE) r <- crop_caim(r, zenith_colrow - diameter/2, diameter, diameter) r <- fisheye_to_equidistant(r, z, a, m, radius = diameter/2, k = 1, p = 1, rmax = 100) } } l[[i]] <- .read_raw(files[i]) } ref <- l[[1]] rings <- ring_segmentation(zenith_image(ncol(ref), lens()), 3) theta <- seq(1.5, 90 - 1.5, 3) * pi/180 .fun <- function(r) { r <- extract_feature(r, rings, return = "vector") r/r[1] } l <- Map(.fun, l) .fun <- function(x) { x / l[[1]][] # because the first is the one already calibrated } radiometry <- Map(.fun, l) l <- list() for (i in 2:length(radiometry)) { l[[i-1]] <- data.frame(theta = theta, radiometry = radiometry[[i]][]) } ds <- l[[1]] head(ds)
The result is one dataset (ds) for each file. This is all what it is needed before using base R functions to fit a vignetting function
This function does not fit the vignetting function itself. The output is a dataset to be used in subsequent modeling steps. See above sections for guidance.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.