rgb2hsv {grDevices} | R Documentation |
rgb2hsv
transforms colors
from RGB space (red/green/blue)
into HSV space (hue/saturation/value).
rgb2hsv(r, g = NULL, b = NULL, gamma = 1, maxColorValue = 255)
r |
vector of ‘red’ values in |
g |
vector of ‘green’ values, or |
b |
vector of ‘blue’ values, or |
gamma |
a gamma-correction (supposedly applied to the
r,g,b values previously), see |
maxColorValue |
number giving the maximum of the RGB color values
range. The default |
Value (brightness) gives the amount of light in the color.
Hue describes the dominant wavelength.
Saturation is the amount of Hue mixed into the color.
A matrix with a column for each color. The three rows of the matrix
indicate hue, saturation and value and are named "h"
,
"s"
, and "v"
accordingly.
R interface by Wolfram Fischer wolfram@fischer-zim.ch;
C code mainly by Nicholas Lewin-Koh nikko@hailmail.net.
hsv
, col2rgb
, rgb
.
## These (saturated, bright ones) only differ by hue
(rc <- col2rgb(c("red", "yellow","green","cyan", "blue", "magenta")))
(hc <- rgb2hsv(rc))
6 * hc["h",] # the hues are equispaced
(rgb3 <- floor(256 * matrix(stats::runif(3*12), 3,12)))
(hsv3 <- rgb2hsv(rgb3))
## Consistency :
stopifnot(rgb3 == col2rgb(hsv(h=hsv3[1,], s=hsv3[2,], v=hsv3[3,])),
all.equal(hsv3, rgb2hsv(rgb3/255, maxColorValue = 1)))
## A (simplified) pure R version -- originally by Wolfram Fischer --
## showing the exact algorithm:
rgb2hsvR <- function(rgb, gamma = 1, maxColorValue = 255)
{
if(!is.numeric(rgb)) stop("rgb matrix must be numeric")
d <- dim(rgb)
if(d[1] != 3) stop("rgb matrix must have 3 rows")
n <- d[2]
if(n == 0) return(cbind(c(h=1,s=1,v=1))[,0])
rgb <- rgb/maxColorValue
if(gamma != 1) rgb <- rgb ^ (1/gamma)
## get the max and min
v <- apply( rgb, 2, max)
s <- apply( rgb, 2, min)
D <- v - s # range
## set hue to zero for undefined values (gray has no hue)
h <- numeric(n)
notgray <- ( s != v )
## blue hue
idx <- (v == rgb[3,] & notgray )
if (any (idx))
h[idx] <- 2/3 + 1/6 * (rgb[1,idx] - rgb[2,idx]) / D[idx]
## green hue
idx <- (v == rgb[2,] & notgray )
if (any (idx))
h[idx] <- 1/3 + 1/6 * (rgb[3,idx] - rgb[1,idx]) / D[idx]
## red hue
idx <- (v == rgb[1,] & notgray )
if (any (idx))
h[idx] <- 1/6 * (rgb[2,idx] - rgb[3,idx]) / D[idx]
## correct for negative red
idx <- (h < 0)
h[idx] <- 1+h[idx]
## set the saturation
s[! notgray] <- 0;
s[notgray] <- 1 - s[notgray] / v[notgray]
rbind( h=h, s=s, v=v )
}
## confirm the equivalence:
all.equal(rgb2hsv (rgb3),
rgb2hsvR(rgb3), tol=1e-14) # TRUE