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

时间:2015-08-04 04:25:29

标签: r image image-processing

当灰度图像由矩阵表示时,矩阵的每个元素确定相应像素的强度。为方便起见,大多数当前的数字文件使用0之间的整数(表示黑色,最小强度的颜色)和255(表示白色,最大强度),总共256 = 2 ^ 8个不同的灰度级。

有没有办法在R中获得灰度图像的像素矩阵,其像素值的范围是0到255?

知道我是否可以在R中调整首选维度(例如,$ 28 \ times 28 $)中的图像,然后将它们转换为像素矩阵(其元素范围从0到255)也会很有帮助?

如果原始图像是RGB但我想要灰度矩阵会发生什么?

2 个答案:

答案 0 :(得分:7)

R包png提供readPNG()函数,它可以将PNG格式的光栅图形(由“像素矩阵”组成)读入R.它返回一个灰度值为[0的单个矩阵,1]或三个矩阵,RGB值在[0,1]中。

对于在[0,1]和{0,...,255}之间进行转换,只需乘以或除以255并舍入(如果需要)。

要在RGB和灰度之间进行转换,您可以使用desaturate()包中的colorspace函数。

例如,让我们下载您建议的图片:

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)

colored and desaturated picture

如果你有一个更大的图像,并希望将它带到28 x 28,我将平均相应行/列的灰度值,并将结果插入到所需维度的矩阵中。

最后注意事项:虽然可以在R中完成所有这些操作,但使用图像处理软件可能会更方便。根据您的目标,可能更容易使用ImageMagick的mogrify,例如:

mogrify -resize 28 -type grayscale twitter.png

答案 1 :(得分: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