Raster package R will split the image into multiples

I have an image as shown below. It is 2579 * 2388 pixels. Let's assume the bottom left corner is 0.0. From this image, I want to create some images as follows and save them in the working folder. Each image will be 100 * 100 pixels in size. Each image will be saved by its lower left hand coordinates.

  • The first image will have a bottom left corner of 0.0. In the upper right corner, the manual angle will be 100 100 and the image will be saved as 0-0.jpg
  • the second will have a bottom left corner of 10.0. The upper right hand corner will be at 110 100 and the image will be saved as 10-0.jpg
  • Once the bottom line is complete, the Y coordinate will move to 10. In the case of the second line, the first image will be at 0.10 and this image will be saved as 0-10.jpg

What's the fastest way to do this? is there an R package that can do this very quickly?

I understand that in the case of the current image, it will split it into 257 * 238 images. But I have enough disk space and need every image to do text detection.

enter image description here

+3


source to share


5 answers


Here's a different approach using the "bitmap" package. The function spatially aggregates the raster to be cut, the aggregated raster cells are turned into polygons, then each polygon region is used to trim the input raster.

I'm sure there are complex and compact ways to do this, but this approach works for me and I found it intuitive. I hope you find it helpful. Note. Parts 4 and 5 below are for testing purposes only and are not part of the function.

enter image description here

Part 1: Download and Print Sample Raster Data

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

      

Part 2: the function itself:

# 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)
}

      



Part 3. Function check

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. 

      

Part 4: Run the code for each part and save them in the directory

# 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

      

Part 5: Let's put the pieces back together

# 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)

      

+7


source


Here's one way to do it using GDAL via gdalUtils

, and parallelize if desired.

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))
}

      

An example of applying a function to one window:

split_rast('R1fqE.jpg', xy$nm[1], xy$llx[1], xy$lly[1], 100, 100)

      



An example of applying it to the first 10 windows:

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

      

An example of using parLapply for parallel work:

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


source


Don't find a direct implementation using r exclusively I used the following approach using that may be of interest to others. It generates extents and visits the original raster. Hope this helps!

## create dummy raster
n <- 50
r <- raster(ncol=n, nrow=n, xmn=4, xmx=10, ymn=52, ymx=54)
projection(r) <- "+proj=longlat +datum=WGS84 +ellps=WGS84 +towgs84=0,0,0"
values(r)     <- 1:n^2+rnorm(n^2)


n.side <-  2  # number of tiles per side
dx     <- (extent(r)[2]- extent(r)[1])/ n.side  # extent of one tile in x direction
dy     <- (extent(r)[4]- extent(r)[3])/ n.side  # extent of one tile in y direction
xs     <- seq(extent(r)[1], by= dx, length= n.side) #lower left x-coordinates
ys     <- seq(extent(r)[3], by= dy, length= n.side) #lower left y-coordinates
cS     <- expand.grid(x= xs, y= ys)

## loop over extents and crop
for(i in 1:nrow(cS)) {
  ex1 <- c(cS[i,1], cS[i,1]+dx, cS[i,2], cS[i,2]+dy)  # create extents for cropping raster
  cl1 <- crop(r, ex1) # crop raster by extent
  writeRaster(x = cl1, filename=paste("test",i,".tif", sep=""), format="GTiff", overwrite=T) # write to file
}

## check functionality...
test <- raster(paste("test1.tif", sep=""))
plot(test)

      

+1


source


This is a bit late, but might be helpful for others coming across this question. Package SpaDES has a handy feature called splitRaster () , which does what you need.

Example:

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

      

Which gives you the following: enter image description here Now split using the SpaDES package . Set nx

and ny

according to the number of tiles you want on the x and y axis - if we need 4 tiles, set them like nx=2

and ny=2

. If you haven't installed path

it should write the files to your current directory. There are other suggestions like buffering - see ?splitRaster

:

# Split into sections - saves automatically to path
sections=splitRaster(the_grid, nx=2, ny=2, path="/your_output_path/")

      

The variable sections

is a list of rasters, one for each section the_grid

- accessed as:

split_1=sections[[1]]

      

If you want to store them on purpose, just use writeRaster () .

Use mergeRaster () to create a merged bitmap repeat .

+1


source


You can use gdal and r as shown in this link .

Then you will change line 23 to make a suitable offset to allow overlap between the generated tiles.

0


source







All Articles