我正在使用一些相当大的图像文件(航空测量马赛克,通常> 10亿像素),这样将整个图像加载到内存中将是我系统上的问题。我想将它们逐个加入R中,以便我可以在“网格”部分处理它们。
注意:我不依赖于特定的图片格式,因此tiff
,png
,bmp
等都可以作为输入。
我可以使用readJPEG
在这些行上做一些事情,但这需要先将整个文件加载到内存中,所以它并没有真正解决我的问题,但希望能够显示我想要实现的目标。 / p>
image.file <- "~/Desktop/penguins.jpg"
grid.size <- 100
v <- 3
h <- 1
library( jpeg )
image <- readJPEG( image.file )[ seq.int( (v-1)*grid.size+1, (v)*grid.size, 1 ),
seq.int( (h-1)*grid.size+1, h*grid.size, 1 ), ]
以上仅加载了grid.size
,v
和h
指定的图像样本,因此很容易将其构建为循环以分析分段图像。
是否有可能在没有将整个图像加载到内存中的情况下实现此?使用read.csv
和skip
参数之类的n
之类的东西是合理的(它至少只能一次加载一个垂直部分,所需的内存比{{ 1}})。
答案 0 :(得分:4)
在 RBioFormats 的帮助下,几乎可以在任何图像格式中轻松完成此操作,可以从GitHub获取。
devtools::install_github("aoles/RBioFormats")
可以在subset
的{{1}}参数中指定块大小。以下示例说明了如何在不将整个文件加载到内存中的情况下逐个处理图像。
read.image()
您可能还想查看 EBImage ,这是R的图像处理工具箱。它提供了查看图像和执行各种转换和过滤的功能。
答案 1 :(得分:3)
如果您安装了ImageMagick,可以在将其读入R之前crop the image from the command line。使用此图片的示例:http://www.worldatlas.com/worldmaps/worldpoliticallarge.jpg
创建裁剪图像:
x <- 800 ## x and y are offsets
y <- 400
w <- 200 ## width and height of cropped image
h <- 100
filename <- "worldpoliticallarge.jpg"
outname <- "crop.jpg"
cmd <- sprintf("jpegtran -crop %dx%d+%d+%d -copy none %s > %s", w, h, x, y, filename, outname)
system(cmd)
检查新图像是否包含我们想要的区域:
library(jpeg)
original <- readJPEG(filename)
cropped <- readJPEG(outname)
all.equal(original[(y+1):(y+h), (x+1):(x+w), ], cropped)
# [1] TRUE