R栅格包将图像分割成多个

use*_*622 4 split r image raster image-processing

我的图像如下.它是2579*2388像素.让我们假设它的左下角是0,0.从该图像我想创建如下的多个图像并将它们保存在工作文件夹中.每张图片的大小为100*100像素.每个图像将通过它的左下角坐标保存.

  1. 第一张图片的左下角为0,0.右上角将是100,100,图像将保存为0-0.jpg
  2. 第二个将其左下角设为10,0.右上角将是110,100,图像将保存为10-0.jpg
  3. 完成底行后,Y坐标将移动10.如果是第二行,则第一个图像将位于0,10,该图像将保存为0-10.jpg

最快的方法是什么?是否有任何R包可以很快完成?

据我所知,在当前图像的情况下,它会将其分成大约257*238个图像.但我有足够的磁盘空间,我需要每个图像来执行文本检测.

在此输入图像描述

小智 11

这里使用"raster"包的另一种方法.该函数在空间上聚合要切割的栅格,聚合的栅格单元格变为多边形,然后每个多边形的范围用于裁剪输入栅格.

我确信有复杂而紧凑的方法可以做到这一点,但这种方法适合我,我发现它也很直观.我希望你也觉得它很有用.注意下面的第4和第5部分仅用于测试,它们不是该功能的一部分.

在此输入图像描述

第1部分:加载和绘制样本栅格数据

logo <- raster(system.file("external/rlogo.grd", package="raster"))
plot(logo,axes=F,legend=F,bty="n",box=FALSE)
Run Code Online (Sandbox Code Playgroud)

第2部分:函数本身:

# 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)
}
Run Code Online (Sandbox Code Playgroud)

第3部分:测试功能

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. 
Run Code Online (Sandbox Code Playgroud)

第4部分:在每个部分上运行代码并将它们保存回目录

# 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
Run Code Online (Sandbox Code Playgroud)

第5部分:让我们把各个部分放在一起

# 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)
Run Code Online (Sandbox Code Playgroud)


jba*_*ums 5

这是一种方法,使用 GDAL via gdalUtils,并根据需要进行并行化。

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))
}
Run Code Online (Sandbox Code Playgroud)

将函数应用于单个窗口的示例:

split_rast('R1fqE.jpg', xy$nm[1], xy$llx[1], xy$lly[1], 100, 100)
Run Code Online (Sandbox Code Playgroud)

将其应用于前 10 个窗口的示例:

mapply(split_rast, 'R1fqE.jpg', xy$nm[1:10], xy$llx[1:10], xy$lly[1:10], 100, 100)
Run Code Online (Sandbox Code Playgroud)

使用 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)
Run Code Online (Sandbox Code Playgroud)