在 R 中只打开图像的一部分(JPEG/TIFF 等)
Open only part of an image (JPEG/TIFF etc.) in R
我正在用 R 分析非常大的图像,大约有数万像素见方。不幸的是,即使使用 64 GB RAM,这些图像有时也无法装入内存,而当它们装入内存时,我一次只能打开一个,从而无法并行化。
我目前的策略是使用 JPEG 或 TIFF 包加载它们。例如:
image <- readJPEG('image.jpg')
但是,由于我只执行可以逐个执行的简单数学操作(求和、阈值等),是否可以通过指定尺寸来一次只打开图像的一部分加载?如果是这样,我可以编写一个循环来打开 1024 x 1024 大小的图块。 JPEG 和 TIFF 包不提供执行此操作的选项。
如果您要处理非常大的图像,libvips
可能是您的最佳选择。您可以使用 system()
.
从 R
shell 输出它
你的问题不是很具体,但让我们用 ImageMagick 制作一个 10,000x10,000 像素的 TIFF,它是一个黑白渐变:
convert -size 10000x10000 gradient: -depth 8 a.tif
现在 vips
将阈值设置为 50% 并检查所需的内存:
vips im_thresh a.tif b.tif 128 --vips-leak
memory: high-water mark 292.21 MB
很节俭,不是吗?相比之下,等效的 ImageMagick 命令需要 1.6GB 的 RAM:
/usr/bin/time -l convert a.tif -threshold 50% b.tif
示例输出
...
1603895296 maximum resident set size
...
使用 im_gadd
为每个像素添加 64 如何:
usage: vips im_gadd a in1 b in2 c out
where:
a is of type "double"
in1 is of type "image"
b is of type "double"
in2 is of type "image"
c is of type "double"
out is of type "image"
calculate a*in1 + b*in2 + c = outfile
所以我们使用:
vips im_gadd 1 a.tif 0 b.tif 64 c.tif --vips-leak
memory: high-water mark 584.41 MB
需要做一些统计吗?
vips im_stats c.tif
band minimum maximum sum sum^2 mean deviation
all 64 319 1.915e+10 4.20922e+12 191.5 73.6206
1 64 319 1.915e+10 4.20922e+12 191.5 73.6206
事实证明,有一个 R 包 - RBioFormats - 允许您指定正在打开的图像的一部分(尽管它在 CRAN 上不可用)。它可以从 Git 安装如下:
source("https://bioconductor.org/biocLite.R")
biocLite("aoles/RBioFormats") # You might need to first run `install.packages("devtools")`
library(RBioFormats)
无需打开图像即可从元数据中读取图像的尺寸:
metadata <- read.metadata('image.tiff')
xdim <- metadata@.Data[[1]]$sizeX
ydim <- metadata@.Data[[1]]$sizeY
假设我们要加载左上角的512 x 512像素,我们使用subset
函数:
image <- read.image('image.tiff', subset = list(X = 1:512, y = 1:512))
据此编写一个循环来迭代处理整个大图像是微不足道的。 RBioFormats 是 Java BioFormats 库的 R 接口,可以打开 Tiff、PNG、JPEG 以及许多专有图像格式。
我正在用 R 分析非常大的图像,大约有数万像素见方。不幸的是,即使使用 64 GB RAM,这些图像有时也无法装入内存,而当它们装入内存时,我一次只能打开一个,从而无法并行化。
我目前的策略是使用 JPEG 或 TIFF 包加载它们。例如:
image <- readJPEG('image.jpg')
但是,由于我只执行可以逐个执行的简单数学操作(求和、阈值等),是否可以通过指定尺寸来一次只打开图像的一部分加载?如果是这样,我可以编写一个循环来打开 1024 x 1024 大小的图块。 JPEG 和 TIFF 包不提供执行此操作的选项。
如果您要处理非常大的图像,libvips
可能是您的最佳选择。您可以使用 system()
.
R
shell 输出它
你的问题不是很具体,但让我们用 ImageMagick 制作一个 10,000x10,000 像素的 TIFF,它是一个黑白渐变:
convert -size 10000x10000 gradient: -depth 8 a.tif
现在 vips
将阈值设置为 50% 并检查所需的内存:
vips im_thresh a.tif b.tif 128 --vips-leak
memory: high-water mark 292.21 MB
很节俭,不是吗?相比之下,等效的 ImageMagick 命令需要 1.6GB 的 RAM:
/usr/bin/time -l convert a.tif -threshold 50% b.tif
示例输出
...
1603895296 maximum resident set size
...
使用 im_gadd
为每个像素添加 64 如何:
usage: vips im_gadd a in1 b in2 c out
where:
a is of type "double"
in1 is of type "image"
b is of type "double"
in2 is of type "image"
c is of type "double"
out is of type "image"
calculate a*in1 + b*in2 + c = outfile
所以我们使用:
vips im_gadd 1 a.tif 0 b.tif 64 c.tif --vips-leak
memory: high-water mark 584.41 MB
需要做一些统计吗?
vips im_stats c.tif
band minimum maximum sum sum^2 mean deviation
all 64 319 1.915e+10 4.20922e+12 191.5 73.6206
1 64 319 1.915e+10 4.20922e+12 191.5 73.6206
事实证明,有一个 R 包 - RBioFormats - 允许您指定正在打开的图像的一部分(尽管它在 CRAN 上不可用)。它可以从 Git 安装如下:
source("https://bioconductor.org/biocLite.R")
biocLite("aoles/RBioFormats") # You might need to first run `install.packages("devtools")`
library(RBioFormats)
无需打开图像即可从元数据中读取图像的尺寸:
metadata <- read.metadata('image.tiff')
xdim <- metadata@.Data[[1]]$sizeX
ydim <- metadata@.Data[[1]]$sizeY
假设我们要加载左上角的512 x 512像素,我们使用subset
函数:
image <- read.image('image.tiff', subset = list(X = 1:512, y = 1:512))
据此编写一个循环来迭代处理整个大图像是微不足道的。 RBioFormats 是 Java BioFormats 库的 R 接口,可以打开 Tiff、PNG、JPEG 以及许多专有图像格式。