---
title: "Munsell Color Conversion"
output: rmarkdown::html_vignette
vignette: >
  %\VignetteIndexEntry{Munsell Color Conversion}
  %\VignetteEngine{knitr::rmarkdown}
  %\VignetteEncoding{UTF-8}
---

```{r setup, echo=FALSE, results='hide', warning=FALSE}
knitr::opts_chunk$set(
  message = FALSE,
  warning = FALSE,
  background = '#F7F7F7',
  fig.align = 'center',
  dev = 'png',
  dpi = 96,
  optipng = knitr::hook_optipng,
  comment = "#>"
)

# keep examples from using more than 2 cores
data.table::setDTthreads(Sys.getenv("OMP_THREAD_LIMIT", unset = 2))

options(width = 100, stringsAsFactors = FALSE, timeout = 600)

suppressMessages(library(aqp, quietly = TRUE))
```

Soil color is most often described using the [Munsell color system](https://en.wikipedia.org/wiki/Munsell_color_system). The `aqp` package provides several functions for converting to and from Munsell color notation, into other representations suitable for on-screen display ([sRGB](https://en.wikipedia.org/wiki/SRGB)) or numerical analysis ([CIELAB](https://en.wikipedia.org/wiki/CIELAB_color_space)). 


## Color Conversion Functions

Conversion of Munsell notation to "something" that can be displayed on-screen (sRGB color representation) is probably the most common color transformation applied to soil morphology data. The `munsell2rgb()` function is convenient for this operation when Munsell notation has been split into vectors of hue, value, and chroma. These could be columns in a `data.frame` or separate vectors. The `parseMunsell()` function is convenient when a full Munsell notation is given as a character vector. Note that `parseMunsell()` is a wrapper to `munsell2rgb()`. For example, converting `10YR 4/6` with either function can return:

  * hex-notation of a color: `#805921FF`, or
  * sRGB color coordinates: `0.5002233 0.3489249 0.1287694`, or
  * CIELAB color coordinates: `40.95021 10.31088 37.49513`.


Selection of the closest `n` Munsell color "chips", given sRGB or CIELAB colorspace coordinates is performed with the `col2Munsell()` function. Input to this function can be colorspace coordinates, named colors (e.g. `red`), or hex-notation of a color. For example, the selection of the closest Munsell chip for CIELAB coordinates `(51.4337, 9.917916, 38.6889)` results in `10YR 5/6` with a reported sigma (error) of `1.5e-6`. This error is estimated as the [CIE2000 distance](https://en.wikipedia.org/wiki/Color_difference#CIEDE2000) between the source CIELAB coordinates and the CIELAB coordinates of the closest Munsell chip.


A representative Munsell color can be estimated from reflectance spectra in the range of 380nm to 730nm with the `spec2Munsell()` function.

```{r echo = FALSE, fig.width=8, fig.height=4}
.m <- '10YR 6/6'

data("munsell.spectra.wide")
w <- munsell.spectra.wide[, 1]
s <- munsell.spectra.wide[, .m]

par(mar = c(4.5, 4.5, 2, 1), cex.axis = 0.75, lend = 2)
plot(w, s, xlab = 'Wavelength (nm)', ylab = 'Reflectance', type = 'b', main = .m, cex = 0.8, pch = 16, axes = FALSE)
rect(xleft = 400, ybottom = 0.35, xright = 450, ytop = 0.4, col = parseMunsell(.m), border = 1, lwd = 1)
axis(side = 1, at = seq(380, 730, by = 20))
axis(side = 2, las = 1)
```


## Special Cases

Neutral colors are commonly specified two ways in the Munsell system: `N 3/` or `N 3/0`, either format will work with `munsell2rgb()` and `parseMunsell()`.

Non-standard Munsell notation (e.g. `3.6YR 4.4 / 5.6`), possibly collected with a sensor vs. color book, can be approximated with `getClosestMunsellChip()`. A more accurate conversion can be performed with the [`munsellinterpol` package.](https://cran.r-project.org/package=munsellinterpol).


## Examples

```{r}
# Munsell -> hex color
parseMunsell('5PB 4/6')

# Munsell -> sRGB
parseMunsell('5PB 4/6',  return_triplets = TRUE)

# Munsell -> CIELAB
parseMunsell('5PB 4/6',  returnLAB = TRUE)

# hex color -> Munsell
col2Munsell('#476189FF')

# neutral color
parseMunsell('N 5/')

# non-standard notation
getClosestMunsellChip('3.3YR 4.4/6.1', convertColors = FALSE)
```




