The whole point of this package is to make it easier to use other methods!
You can also tour the functions in the function gallery.
Making color maps is an obviously visual process, so it’s good to use
visual feedback as much as possible. We’ve already seen a few of these
functions in action, specifically plotColorPalette
and
plotImageArray
, which are used in almost every function
that produces a recolorize
object. I’ll point out three
others that I think are quite useful: imDist
,
plotColorClusters
, and splitByColor
(which
also doubles as an export function).
imDist
Compares two versions of the same image by calculating the color
distance between the colors of each pair of pixels
(imDist
), and gives you a few more options for plotting the
results (imHeatmap
). You can use it to get the distances
between the original image and the color map:
library(recolorize)
img <- system.file("extdata/ephippigera.png", package = "recolorize")
rc <- recolorize2(img, plotting = FALSE)
#>
#> Using 2^3 = 8 total bins
layout(matrix(1:2, nrow = 1))
par(mar = c(0, 0, 2, 1))
# calculates the distance matrix and plots the results
dist_original <- imDist(readImage(img),
recoloredImage(rc),
color_space = "sRGB",
main = "Unscaled distances")
# more plotting options - setting the range is important for comparing
# across images (max is sqrt(3) in sRGB space, ~120 in Lab)
imHeatmap(dist_original, range = c(0, sqrt(3)),
main = "Scaled distances")
The resulting object is a simple matrix of distances between each pair
of pixels in the given color space. These are essentially residuals:
A word of warning here: it is easy to look at this and decide to come up with a procedure for automatically fitting color maps using a kind of AIC metric, trying to get the lowest SSE with the minimum set of color centers. You’re welcome to try that, but given that this is discarding spatial information, it is probably not a general solution (I haven’t had much luck with it). But there is probably some room to play here.
splitByColor
This is a dual-use function: by splitting up the color map into individual layers, you not only can examine the individual layers and decide whether they need any editing or merging, but you also get out a binary mask representing each layer, so you can export individual patches.
img <- system.file("extdata/corbetti.png", package = "recolorize")
rc <- recolorize2(img, cutoff = 45, plotting = FALSE)
#>
#> Using 2^3 = 8 total bins
layout(matrix(1:10, nrow = 2, byrow = TRUE))
par(mar = c(0, 0, 2, 0))
# 'overlay' is not always the clearest option, but it is usually the prettiest:
layers <- splitByColor(rc, plot_method = "overlay")
# layers is a list of matrices, which we can just plot:
for (i in 1:length(layers)) {
plotImageArray(layers[[i]], main = i)
}
The most direct thing you can do is simply export your recolored images as images, then pass those to whatever other tool you’d like to use, although obviously this doesn’t take full advantage of the format:
You can also convert a recolorize object to a classify object in the
wonderful pavo
package and then run an adjacency analysis.
Bonus points if you have reflectance spectra for each of your color
patches: by combining the spatial information in the color map with the
coldist
object generated by spectral measurements, you can
run adjacency analysis for the visual system(s) of your choice right out
of the box!
# convert to a classify object
as_classify <- classify_recolorize(rc, imgname = "corbetti")
adj_analysis <- pavo::adjacent(as_classify, xscale = 10)
# run adjacent directly using human perceptual color distances (i.e. no spectral data - proceed with caution)
adj_human <- recolorize_adjacency(rc)
You can also run an adjacency analysis with
recolorize_adjacency
, but only as long as you keep your
skeptic hat on. This function works by calculating a
coldist
object right from the CIE Lab colors in the color
maps, which are themselves probably derived from your RGB image, which
is at best a very loose representation of how these colors appear to
human eyes. The only reason this is at all reasonable is that it’s
producing these values for human vision, so you will be able to see if
it’s completely unreasonable. This is fine for getting some preliminary
results or if you’re working with aggregate data from many sources and
you’re content with specifically human (not just non-UV, but only human)
vision. Otherwise, it’s probably a last resort.
Because of the way patternize is structured, going from recolorize to patternize is slightly more involved. See the GitHub (https://github.com/hiweller) for links to a worked example of this, but the general process is:
patternize
and align them into a list
of rasters, using e.g. alignLan()
.brick_to_array
to convert the list of rasters to a
list of images.recolorize_to_patternize
to convert clustered
images back to a raster list.patternize
analyses.