我的图像如下。它是2579 * 2388像素。让我们假设它的左下角是0,0。从该图像我想创建如下的多个图像并将它们保存在工作文件夹中。每张图片的大小为100 * 100像素。每个图像都将通过它的左下角坐标保存。
最快的方法是什么?是否有任何R包可以非常快地完成?
据我所知,在当前图像的情况下,它会将其分成大约257 * 238个图像。但是我有足够的磁盘空间,我需要每个图像来执行文本检测。
答案 0 :(得分:11)
这里使用“raster”包的另一种方法。该函数在空间上聚合要切碎的栅格,聚合的栅格单元格变为多边形,然后每个多边形的范围用于裁剪输入栅格。
我确信有复杂而紧凑的方法可以做到这一点,但这种方法适用于我,我发现它也很直观。我希望你也觉得它很有用。注意第4部分和以下5仅用于测试,它们不属于该功能。
logo <- raster(system.file("external/rlogo.grd", package="raster"))
plot(logo,axes=F,legend=F,bty="n",box=FALSE)
# The function spatially aggregates the original raster
# it turns each aggregated cell into a polygon
# then the extent of each polygon is used to crop
# the original raster.
# The function returns a list with all the pieces
# in case you want to keep them in the memory.
# it saves and plots each piece
# The arguments are:
# raster = raster to be chopped (raster object)
# ppside = pieces per side (integer)
# save = write raster (TRUE or FALSE)
# plot = do you want to plot the output? (TRUE or FALSE)
SplitRas <- function(raster,ppside,save,plot){
h <- ceiling(ncol(raster)/ppside)
v <- ceiling(nrow(raster)/ppside)
agg <- aggregate(raster,fact=c(h,v))
agg[] <- 1:ncell(agg)
agg_poly <- rasterToPolygons(agg)
names(agg_poly) <- "polis"
r_list <- list()
for(i in 1:ncell(agg)){
e1 <- extent(agg_poly[agg_poly$polis==i,])
r_list[[i]] <- crop(raster,e1)
}
if(save==T){
for(i in 1:length(r_list)){
writeRaster(r_list[[i]],filename=paste("SplitRas",i,sep=""),
format="GTiff",datatype="FLT4S",overwrite=TRUE)
}
}
if(plot==T){
par(mfrow=c(ppside,ppside))
for(i in 1:length(r_list)){
plot(r_list[[i]],axes=F,legend=F,bty="n",box=FALSE)
}
}
return(r_list)
}
SplitRas(raster=logo,ppside=3,save=TRUE,plot=TRUE)
# in this example we chopped the raster in 3 pieces per side
# so 9 pieces in total
# now the raster pieces should be ready
# to be processed in the default directory
# A feature I like about this function is that it plots
# the pieces in the original order.
# notice if you cropped a rasterbrick
# use "brick" instead of "raster" to read
# the piece back in R
list2 <- list()
for(i in 1:9){ # change this 9 depending on your number of pieces
rx <- raster(paste("SplitRas",i,".tif",sep=""))
# piece_processed <- HERE YOU RUN YOUR CODE
writeRaster(piece_processed,filename=paste("SplitRas",i,sep=""),
format="GTiff",datatype="FLT4S",overwrite=TRUE)
}
# once a code has been ran on those pieces
# we save them back in the directory
# with the same name for convenience
# read each piece back in R
list2 <- list()
for(i in 1:9){ # change this 9 depending on your number of pieces
rx <- raster(paste("SplitRas",i,".tif",sep=""))
list2[[i]] <- rx
}
# mosaic them, plot mosaic & save output
list2$fun <- max
rast.mosaic <- do.call(mosaic,list2)
plot(rast.mosaic,axes=F,legend=F,bty="n",box=FALSE)
writeRaster(rast.mosaic,filename=paste("Mosaicked_ras",sep=""),
format="GTiff",datatype="FLT4S",overwrite=TRUE)
答案 1 :(得分:3)
以下是一种方法,通过gdalUtils
使用GDAL,并根据需要进行并行化。
library(gdalUtils)
# Get the dimensions of the jpg
dims <- as.numeric(
strsplit(gsub('Size is|\\s+', '', grep('Size is', gdalinfo('R1fqE.jpg'), value=TRUE)),
',')[[1]]
)
# Set the window increment, width and height
incr <- 10
win_width <- 100
win_height <- 100
# Create a data.frame containing coordinates of the lower-left
# corners of the windows, and the corresponding output filenames.
xy <- setNames(expand.grid(seq(0, dims[1], incr), seq(dims[2], 0, -incr)),
c('llx', 'lly'))
xy$nm <- paste0(xy$llx, '-', dims[2] - xy$lly, '.png')
# Create a function to split the raster using gdalUtils::gdal_translate
split_rast <- function(infile, outfile, llx, lly, win_width, win_height) {
library(gdalUtils)
gdal_translate(infile, outfile,
srcwin=c(llx, lly - win_height, win_width, win_height))
}
将函数应用于单个窗口的示例:
split_rast('R1fqE.jpg', xy$nm[1], xy$llx[1], xy$lly[1], 100, 100)
将其应用于前10个窗口的示例:
mapply(split_rast, 'R1fqE.jpg', xy$nm[1:10], xy$llx[1:10], xy$lly[1:10], 100, 100)
使用parLapply并行运行的示例:
library(parallel)
cl <- makeCluster(4) # e.g. use 4 cores
clusterExport(cl, c('split_rast', 'xy'))
system.time({
parLapply(cl, seq_len(nrow(xy)), function(i) {
split_rast('R1fqE.jpg', xy$nm[i], xy$llx[i], xy$lly[i], 100, 100)
})
})
stopCluster(cl)
答案 2 :(得分:1)
没有找到使用r的直接实现我使用raster操作使用了以下方法,这可能对其他人感兴趣。它会生成范围并将原始栅格裁剪给它们。希望这有帮助!
datastore = DatastoreOptions.getDefaultInstance().getService();
答案 3 :(得分:1)
这有点晚了,但对于遇到这个问题的其他人可能会有用。 SpaDES包有一个名为splitRaster()的便捷功能,可以完成您之后的工作。
一个例子:
library(raster)
library(SpaDES)
# Create grid
the_grid=raster(xmn=0, xmx=100, ymn=0, ymx=100, resolution=1)
# Set some values
the_grid[0:50,0:50] <- 1
the_grid[51:100,51:100] <- 2
the_grid[51:100,0:50] <- 3
the_grid[0:50,51:100] <- 4
哪个给你这个:
现在使用SpaDES package进行拆分。根据您想要沿着x和y轴的切片数量设置nx
和ny
- 如果我们需要4个切片,请将它们设置为nx=2
和ny=2
。如果您未设置path
,则应将文件写入当前目录。还有其他一些东西可以提供缓冲 - 请参阅?splitRaster
:
# Split into sections - saves automatically to path
sections=splitRaster(the_grid, nx=2, ny=2, path="/your_output_path/")
变量sections
是一个栅格列表,每个the_grid
部分都有一个栅格 - 访问它们:
split_1=sections[[1]]
如果您想专门保存它们,只需使用writeRaster()。
要再次创建组合栅格,请使用mergeRaster()。
答案 4 :(得分:0)
您可以使用gdal和r,如此link所示。
然后,您可以修改第23行以产生合适的偏移量,以允许生成的图块之间重叠。
答案 5 :(得分:0)
我认为您需要为处理部分创建一个函数(将其称为“ fnc”)和一个表,其中列出了已制作的图块数量(将其称为“ tile.tbl”),并且假设您的地理大数据称为“ obj”
obj=GDALinfo("/pathtodata.tif")
tile.tbl <- getSpatialTiles(obj, block.x= your size of interest, return.SpatialPolygons=FALSE)
,然后使用降雪包将其并行化。这是一个示例:
library(snowfall)
sfInit(parallel=TRUE, cpus=parallel::detectCores())
sfExport("tile.tbl", "fnc")
sfLibrary(rgdal)
sfLibrary(raster)
out.lst <- sfClusterApplyLB(1:nrow(tile.tbl), function(x){ fnc(x, tile.tbl) })
sfStop()
有关详细说明,请参见HERE