如何在R中从灰度图像获取像素矩阵?

5
当灰度图像用矩阵表示时,矩阵的每个元素决定了相应像素的强度。为方便起见,大多数当前数字文件使用0到255之间的整数来表示不同级别的灰度(0表示黑色,最小强度颜色;255表示白色,最大强度),共256 = 2^8种不同的灰度级别。
在R中有一种方法可以获取灰度图像的像素矩阵,其像素值范围从0到255。
同时,在R中是否可以将图像调整为所需的尺寸(例如$28 \times 28$),然后将其转换为像素矩阵,其元素范围为0到255?
如果原始图像是RGB格式,但我想要灰度矩阵会发生什么?
2个回答

10

R包png提供了readPNG()函数,可以将PNG格式的光栅图形(由“像素矩阵”组成)读入R。它返回一个灰度值在[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图像读入到一个数组x中,该数组的维度为28 x 28 x 4。因此,该图像具有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的大小,可以对应行/列中的灰度值取平均并将结果插入到所需维度的矩阵中。

最后注意:虽然在R中完全可以完成上述步骤,但使用图像处理软件可能更为方便。例如,根据你的需求,使用ImageMagick的mogrify可能会更容易:

mogrify -resize 28 -type grayscale twitter.png

谢谢你的回答。请问如果我有一个名为“image.png”的图像,如何使用desaturate()命令获得灰度图像?还有关于如何在R中将图像调整为首选尺寸(例如,28x28像素)的问题? - Blain Waan
如果我读取这张图片(http://www.greenmountaindiapers.com/skin/common_files/modules/Socialize/images/twitter.png),为什么它会给我一个28x28x4的矩阵?你能解释一下吗?再次感谢。 - Blain Waan
我在回复中添加了一个带有解释的示例。 - Achim Zeileis
我真的很喜欢这个答案。它还解决了在R中解决图像相关问题时可能出现的其他疑问。 - Manish Sharma

1
这是一个将灰度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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接