The goal of this document is to show an example of a processing flow using images. The steps to be followed to build new image processing pipes and how the new flow would be defined are described below. The script for this example can be found at the Github repository:
https://github.com/miferreiro/bdpar/blob/master/articleExample/exampleImage/exampleImage.R
First of all, it is necessary to include the bdpar package and the imager package, which will be used to read and transform the images.
First it is necessary to create the extractor that will allow reading the images to be processed.
library(R6)
ExtractorImage <- R6Class(
classname = "ExtractorImage",
inherit = Instance,
public = list(
initialize = function(path) {
super$initialize(path)
},
obtainSource = function() {
source <- imager::load.image(super$getPath())
super$setSource(source)
super$setData(source)
}
)
)
Secondly, it is necessary to indicate to bdpar with which extension the created extractor is associated, in this case, .png.
For this example, four pipes have been developed to treat the images. It should be noted that the first pipe is necessary to read the image with the extractor created previously and the next pipes manage the changes of the image.
library(R6)
Image2Pipe <- R6Class(
"Image2Pipe",
inherit = GenericPipe,
public = list(
initialize = function(propertyName = "",
alwaysBeforeDeps = list(),
notAfterDeps = list()) {
super$initialize(propertyName, alwaysBeforeDeps, notAfterDeps)
},
pipe = function(instance) {
instance$obtainSource()
instance
}
)
)
ImageCroppingPipe <- R6Class(
"ImageCroppingPipe",
inherit = GenericPipe,
public = list(
initialize = function(propertyName = "",
alwaysBeforeDeps = list(),
notAfterDeps = list()) {
super$initialize(propertyName, alwaysBeforeDeps, notAfterDeps)
},
pipe = function(instance) {
data <- instance$getData()
data <- imager::imsub(data, x > height/2)
instance$setData(data)
instance
}
)
)
ImageResizePipe <- R6Class(
"ImageResizePipe",
inherit = GenericPipe,
public = list(
initialize = function(propertyName = "",
alwaysBeforeDeps = list(),
notAfterDeps = list()) {
super$initialize(propertyName, alwaysBeforeDeps, notAfterDeps)
},
pipe = function(instance) {
data <- instance$getData()
data <- imager::imrotate(data, 30)
instance$setData(data)
instance
}
)
)
Once the pipes to be used have been created, it is time to build the flow of pipes to be used using the DynamicPipeline class.