将图像数组转换为 RGB 到 HSL/HSV 并返回?
Converting image array to RGB to HSL/HSV and back?
我使用 jpeg
包中的 readJPEG()
读取彩色 jpg 图像。现在我在 R 中将图像作为三维数组(宽度、高度、通道)
我想将这些图像数组转换成 HSL 或 HSV 颜色 space,对图像进行变异并再次将它们保存为 RGB 格式的 JPG。但是,由于图像非常大 (5000 x 8000),遍历每个单元格太耗时。我发现包 OpenImageR
可以快速将图像转换为 HSV 颜色 space,但是,我对“饱和度”通道中的大负值感到困惑。此外,该软件包不包含将图像转换回来的功能。
是否有任何包可以执行从 RGB 到 HSL 或 HSV(以及返回)的快速转换?或者有没有其他快速转换的方法?
这些是我目前尝试转换为单向元素的尝试:
# load packages
library(jpeg)
library(plotwidgets)
# load image
img <- readJPEG(img_path)
img <- img * 255
# new empty image
img_new <- array(NA, dim = dim(img))
# this takes way too long
for (img_row in 1:dim(img)[1]) {
for (img_col in 1:dim(img)[2]) {
img_new[img_row,img_col,] <- round(rgb2hsl(as.matrix(img[img_row,img_col,])))
}
}
# this takes also way too long
for (img_row in 1:dim(img)[1]) {
img_new[img_row,,] <- t(round(rgb2hsl(t(matrix(img[img_row,,], ncol = 3)))))
}
# this takes also ages
rgb_hsl_fun <- function(x) {
as.numeric(rgb2hsl(matrix(x)))
}
img_hsl <- apply(X = img, MARGIN = c(1,2), FUN = rgb_hsl_fun)
整个事情做起来很简单。
为此使用 colorspace
库。
这是我的原始 img.jpg 文件。
这是代码。
library(jpeg)
library(colorspace)
#Reading a jpg file
img = readJPEG("img.jpg") * 255
#Row-by-row conversion
for(i in 1:dim(img)[1]){
#Convert to HSV format
hsv = RGB(img[i,,1], img[i,,2], img[i,,3]) |> as("HSV")
#Mutation of H, S, V components
attributes(hsv)$coords[,"H"] = attributes(hsv)$coords[,"H"]/2
attributes(hsv)$coords[,"S"] = attributes(hsv)$coords[,"S"]*.998
attributes(hsv)$coords[,"V"] = attributes(hsv)$coords[,"V"]-1
#Convert to RGB format and save to the current line.
rgb = as(hsv, "RGB")
img[i,,1] = attributes(rgb)$coords[,"R"]
img[i,,2] = attributes(rgb)$coords[,"G"]
img[i,,3] = attributes(rgb)$coords[,"B"]
}
#Save to JPG file
writeJPEG(img / 255, "img_hsv.jpg")
请注意,要获取单独的 H、S、V(或 R、G、B)组件,您必须使用 coords
属性。
如您所见,我对组件 H、S、V 的修改如下:
- H = H / 2
- S = S * 0.998
- V = V-1
经过这次突变,原来的文件看起来是这样的。
但是,如果您更喜欢在 HLS 调色板上进行突变,也是可以的。
#Reading a jpg file
img = readJPEG("img.jpg") * 255
#Row-by-row conversion
for(i in 1:dim(img)[1]){
#Convert to HLS format
hls = RGB(img[i,,1], img[i,,2], img[i,,3]) |> as("HLS")
#Mutation of H, S, V components
attributes(hls)$coords[,"H"] = attributes(hls)$coords[,"H"]/2
attributes(hls)$coords[,"L"] = attributes(hls)$coords[,"L"]/2
attributes(hls)$coords[,"S"] = attributes(hls)$coords[,"S"]/2
#Convert to RGB format and save to the current line.
rgb = as(hls, "RGB")
img[i,,1] = attributes(rgb)$coords[,"R"]
img[i,,2] = attributes(rgb)$coords[,"G"]
img[i,,3] = attributes(rgb)$coords[,"B"]
}
#Save to JPG file
writeJPEG(img / 255, "img_hls.jpg")
这是经过 H/2、L/2 和 S/2 转换后的图像。
希望这就是您要找的。
向 Github repository 提出问题是明智的(以防 HSV 转换的错误案例有快速修复)。作为记录,我是 OpenImageR 包的作者和维护者。
我再次查看了 RGB_to_HSV 函数的代码,正如我在 Rcpp 代码函数顶部提到的那样,实现基于论文
饱和通道的负值极有可能与下面一行的错误有关,
S(i) = 1.0 - (3.0 * s_val) * (R(i) + G(i) + B(i));
实际上(根据论文)应该是:
S(i) = 1.0 - (3.0 * s_val) / (R(i) + G(i) + B(i));
(最后一项的除法而不是乘法)
我已将更新版本上传到 Github,您可以使用
安装它
remotes::install_github('mlampros/OpenImageR')
如果有效请反馈,以便我可以将新版本上传到 CRAN。
该包不包括从 HSV 到 RGB 的转换(根据我的理解,您想修改像素值然后转换为 RGB)。
我使用 jpeg
包中的 readJPEG()
读取彩色 jpg 图像。现在我在 R 中将图像作为三维数组(宽度、高度、通道)
我想将这些图像数组转换成 HSL 或 HSV 颜色 space,对图像进行变异并再次将它们保存为 RGB 格式的 JPG。但是,由于图像非常大 (5000 x 8000),遍历每个单元格太耗时。我发现包 OpenImageR
可以快速将图像转换为 HSV 颜色 space,但是,我对“饱和度”通道中的大负值感到困惑。此外,该软件包不包含将图像转换回来的功能。
是否有任何包可以执行从 RGB 到 HSL 或 HSV(以及返回)的快速转换?或者有没有其他快速转换的方法?
这些是我目前尝试转换为单向元素的尝试:
# load packages
library(jpeg)
library(plotwidgets)
# load image
img <- readJPEG(img_path)
img <- img * 255
# new empty image
img_new <- array(NA, dim = dim(img))
# this takes way too long
for (img_row in 1:dim(img)[1]) {
for (img_col in 1:dim(img)[2]) {
img_new[img_row,img_col,] <- round(rgb2hsl(as.matrix(img[img_row,img_col,])))
}
}
# this takes also way too long
for (img_row in 1:dim(img)[1]) {
img_new[img_row,,] <- t(round(rgb2hsl(t(matrix(img[img_row,,], ncol = 3)))))
}
# this takes also ages
rgb_hsl_fun <- function(x) {
as.numeric(rgb2hsl(matrix(x)))
}
img_hsl <- apply(X = img, MARGIN = c(1,2), FUN = rgb_hsl_fun)
整个事情做起来很简单。
为此使用 colorspace
库。
这是我的原始 img.jpg 文件。
这是代码。
library(jpeg)
library(colorspace)
#Reading a jpg file
img = readJPEG("img.jpg") * 255
#Row-by-row conversion
for(i in 1:dim(img)[1]){
#Convert to HSV format
hsv = RGB(img[i,,1], img[i,,2], img[i,,3]) |> as("HSV")
#Mutation of H, S, V components
attributes(hsv)$coords[,"H"] = attributes(hsv)$coords[,"H"]/2
attributes(hsv)$coords[,"S"] = attributes(hsv)$coords[,"S"]*.998
attributes(hsv)$coords[,"V"] = attributes(hsv)$coords[,"V"]-1
#Convert to RGB format and save to the current line.
rgb = as(hsv, "RGB")
img[i,,1] = attributes(rgb)$coords[,"R"]
img[i,,2] = attributes(rgb)$coords[,"G"]
img[i,,3] = attributes(rgb)$coords[,"B"]
}
#Save to JPG file
writeJPEG(img / 255, "img_hsv.jpg")
请注意,要获取单独的 H、S、V(或 R、G、B)组件,您必须使用 coords
属性。
如您所见,我对组件 H、S、V 的修改如下:
- H = H / 2
- S = S * 0.998
- V = V-1
经过这次突变,原来的文件看起来是这样的。
但是,如果您更喜欢在 HLS 调色板上进行突变,也是可以的。
#Reading a jpg file
img = readJPEG("img.jpg") * 255
#Row-by-row conversion
for(i in 1:dim(img)[1]){
#Convert to HLS format
hls = RGB(img[i,,1], img[i,,2], img[i,,3]) |> as("HLS")
#Mutation of H, S, V components
attributes(hls)$coords[,"H"] = attributes(hls)$coords[,"H"]/2
attributes(hls)$coords[,"L"] = attributes(hls)$coords[,"L"]/2
attributes(hls)$coords[,"S"] = attributes(hls)$coords[,"S"]/2
#Convert to RGB format and save to the current line.
rgb = as(hls, "RGB")
img[i,,1] = attributes(rgb)$coords[,"R"]
img[i,,2] = attributes(rgb)$coords[,"G"]
img[i,,3] = attributes(rgb)$coords[,"B"]
}
#Save to JPG file
writeJPEG(img / 255, "img_hls.jpg")
这是经过 H/2、L/2 和 S/2 转换后的图像。
希望这就是您要找的。
向 Github repository 提出问题是明智的(以防 HSV 转换的错误案例有快速修复)。作为记录,我是 OpenImageR 包的作者和维护者。
我再次查看了 RGB_to_HSV 函数的代码,正如我在 Rcpp 代码函数顶部提到的那样,实现基于论文
饱和通道的负值极有可能与下面一行的错误有关,
S(i) = 1.0 - (3.0 * s_val) * (R(i) + G(i) + B(i));
实际上(根据论文)应该是:
S(i) = 1.0 - (3.0 * s_val) / (R(i) + G(i) + B(i));
(最后一项的除法而不是乘法)
我已将更新版本上传到 Github,您可以使用
安装它remotes::install_github('mlampros/OpenImageR')
如果有效请反馈,以便我可以将新版本上传到 CRAN。
该包不包括从 HSV 到 RGB 的转换(根据我的理解,您想修改像素值然后转换为 RGB)。