如何从 R 中的灰度图像获取像素矩阵?
How to get a pixel matrix from grayscale image in R?
当灰度图像由矩阵表示时,矩阵的每个元素决定相应像素的强度。为方便起见,大多数当前数字文件使用介于 0(表示黑色,强度最小的颜色)和 255(表示白色,强度最大的颜色)之间的整数,总共给出 256 = 2^8 种不同的灰色级别。
有没有办法在 R 中获取像素值范围为 0 到 255 的灰度图像像素矩阵?
知道我是否可以在 R 中按首选尺寸(例如,$28 \times 28$)调整图像大小,然后将它们转换为元素范围为 0 到 255 的像素矩阵,这也会很有帮助?
如果原始图像是 RGB 但我想要灰度矩阵会怎样?
R包png
提供了readPNG()
函数,可以将PNG格式的光栅图形(由"pixel matrices"组成)读入R。它returns要么是单个灰度值在 [0, 1] 中的矩阵或 RGB 值在 [0, 1] 中的三个矩阵。
要在 [0, 1] 和 {0, ..., 255} 之间进行转换,只需乘以或除以 255 并根据需要进行舍入。
对于 RGB 和灰度之间的转换,您可以使用 colorspace
包中的 desaturate()
函数。
例如,让我们下载您建议的图片:
download.file("http://www.greenmountaindiapers.com/skin/common_files/modules/Socialize/images/twitter.png",
destfile = "twitter.png")
然后我们加载上面提到的包:
library("png")
library("colorspace")
首先,我们将 PNG 图像读入尺寸为 28 x 28 x 4 的数组 x
。因此,图像具有 28 x 28 像素和四个通道:红色、绿色、蓝色和 alpha(对于半透明)。
x <- readPNG("twitter.png")
dim(x)
## [1] 28 28 4
现在我们可以将其转换为各种其他格式:y
是十六进制字符串的向量,在 R 中指定颜色。yg
是相应的去饱和颜色(再次作为十六进制字符)仅 灰度 。 yn
是 数字 灰度。所有三个对象在最后排列成 28 x 28 的矩阵
y <- rgb(x[,,1], x[,,2], x[,,3], alpha = x[,,4])
yg <- desaturate(y)
yn <- col2rgb(yg)[1, ]/255
dim(y) <- dim(yg) <- dim(yn) <- dim(x)[1:2]
我希望这些版本中至少有一个是您要找的。为了检查像素矩阵,我编写了一个用于可视化的小便利函数:
pixmatplot <- function (x, ...) {
d <- dim(x)
xcoord <- t(expand.grid(1:d[1], 1:d[2]))
xcoord <- t(xcoord/d)
par(mar = rep(1, 4))
plot(0, 0, type = "n", xlab = "", ylab = "", axes = FALSE,
xlim = c(0, 1), ylim = c(0, 1), ...)
rect(xcoord[, 2L] - 1/d[2L], 1 - (xcoord[, 1L] - 1/d[1L]),
xcoord[, 2L], 1 - xcoord[, 1L], col = x, border = "transparent")
}
为了便于说明,让我们看一下:
pixmatplot(y)
pixmatplot(yg)
如果您有更大的图像并希望将其调整为 28 x 28,我会从相应的 rows/columns 中平均灰度值并将结果插入到所需尺寸的矩阵中。
最后说明:虽然在 R 中当然可以完成所有这些操作,但使用图像处理软件可能更方便。根据您的目标,使用 ImageMagick 的 mogrify
可能更容易,例如:
mogrify -resize 28 -type grayscale twitter.png
下面是一个从灰度 png 转换和绘制图像的示例。请确保先安装相关包。
library(png)
library(RCurl)
myurl = "https://postgis.net/docs/manual-dev/images/apple_st_grayscale.png"
my_image = readPNG(getURLContent(myurl))
img_mat=my_image[,,1] # will hold the grayscale values divided by 255
img_mat=t(apply(img_mat, 2, rev)) # otherwise the image will be rotated
image(img_mat, col = gray((0:255)/255)) # plot in grayscale
当灰度图像由矩阵表示时,矩阵的每个元素决定相应像素的强度。为方便起见,大多数当前数字文件使用介于 0(表示黑色,强度最小的颜色)和 255(表示白色,强度最大的颜色)之间的整数,总共给出 256 = 2^8 种不同的灰色级别。
有没有办法在 R 中获取像素值范围为 0 到 255 的灰度图像像素矩阵?
知道我是否可以在 R 中按首选尺寸(例如,$28 \times 28$)调整图像大小,然后将它们转换为元素范围为 0 到 255 的像素矩阵,这也会很有帮助?
如果原始图像是 RGB 但我想要灰度矩阵会怎样?
R包png
提供了readPNG()
函数,可以将PNG格式的光栅图形(由"pixel matrices"组成)读入R。它returns要么是单个灰度值在 [0, 1] 中的矩阵或 RGB 值在 [0, 1] 中的三个矩阵。
要在 [0, 1] 和 {0, ..., 255} 之间进行转换,只需乘以或除以 255 并根据需要进行舍入。
对于 RGB 和灰度之间的转换,您可以使用 colorspace
包中的 desaturate()
函数。
例如,让我们下载您建议的图片:
download.file("http://www.greenmountaindiapers.com/skin/common_files/modules/Socialize/images/twitter.png",
destfile = "twitter.png")
然后我们加载上面提到的包:
library("png")
library("colorspace")
首先,我们将 PNG 图像读入尺寸为 28 x 28 x 4 的数组 x
。因此,图像具有 28 x 28 像素和四个通道:红色、绿色、蓝色和 alpha(对于半透明)。
x <- readPNG("twitter.png")
dim(x)
## [1] 28 28 4
现在我们可以将其转换为各种其他格式:y
是十六进制字符串的向量,在 R 中指定颜色。yg
是相应的去饱和颜色(再次作为十六进制字符)仅 灰度 。 yn
是 数字 灰度。所有三个对象在最后排列成 28 x 28 的矩阵
y <- rgb(x[,,1], x[,,2], x[,,3], alpha = x[,,4])
yg <- desaturate(y)
yn <- col2rgb(yg)[1, ]/255
dim(y) <- dim(yg) <- dim(yn) <- dim(x)[1:2]
我希望这些版本中至少有一个是您要找的。为了检查像素矩阵,我编写了一个用于可视化的小便利函数:
pixmatplot <- function (x, ...) {
d <- dim(x)
xcoord <- t(expand.grid(1:d[1], 1:d[2]))
xcoord <- t(xcoord/d)
par(mar = rep(1, 4))
plot(0, 0, type = "n", xlab = "", ylab = "", axes = FALSE,
xlim = c(0, 1), ylim = c(0, 1), ...)
rect(xcoord[, 2L] - 1/d[2L], 1 - (xcoord[, 1L] - 1/d[1L]),
xcoord[, 2L], 1 - xcoord[, 1L], col = x, border = "transparent")
}
为了便于说明,让我们看一下:
pixmatplot(y)
pixmatplot(yg)
如果您有更大的图像并希望将其调整为 28 x 28,我会从相应的 rows/columns 中平均灰度值并将结果插入到所需尺寸的矩阵中。
最后说明:虽然在 R 中当然可以完成所有这些操作,但使用图像处理软件可能更方便。根据您的目标,使用 ImageMagick 的 mogrify
可能更容易,例如:
mogrify -resize 28 -type grayscale twitter.png
下面是一个从灰度 png 转换和绘制图像的示例。请确保先安装相关包。
library(png)
library(RCurl)
myurl = "https://postgis.net/docs/manual-dev/images/apple_st_grayscale.png"
my_image = readPNG(getURLContent(myurl))
img_mat=my_image[,,1] # will hold the grayscale values divided by 255
img_mat=t(apply(img_mat, 2, rev)) # otherwise the image will be rotated
image(img_mat, col = gray((0:255)/255)) # plot in grayscale