ImageProcessing supports the following features, which you can use when implementing your examples:
Directory with pictures processing tool
Also you can specify:
For detailed descriptions of all features visit Api Reference.
Filter kernels are used to call applyFilter
function.
You can create 2D float32 array as new kernel or use implemented kernels such as:
You can use either single-threaded CPU-based image processing or multi-threaded image processing. Multithreading is performed using logger and agent functions, which is specified in this section.
Four of them are implemented:
Open library and load image to process:
open MyImage
open CPU
let myImage = load ("Full/Path/To/Images/Folder/image_name.jpg")
Create new function which sequentially applies blur filter and clockwise rotation to images and saves the result:
let applyCustomFilterOnCPU (image: MyImage) (pathToSave : string) =
let blurredImage = image |> applyFilter gaussianBlurKernel
let rotatedImage = blurredImage |> rotate true
save rotatedImage pathToSave
The result:
open MyImage
open CPU
let myImage = load ("Full/Path/To/Images/Folder/image_name.jpg")
let applyCustomFilterOnCPU (image: MyImage) (pathToSave : string) =
let blurredImage = image |> applyFilter gaussianBlurKernel
let rotatedImage = blurredImage |> rotate true
save rotatedImage pathToSave
let pathToSave = "Path/To/Directory/image_name.jpg"
applyCustomFilterOnCPU myImage pathToSave
Filter kernels are used to call applyFilter
function.
You can create 2D float32 array as new kernel or use implemented kernels such as:
GPU kernels are used to call GPU-processing functions. They have specific defining style, so for more information about how they work I recommended to visit Brahma.Fsharp tutorial. But if you have no need in creating new GPU kernels just use implemented ones, such as:
applyFilterGPUKernel
rotateGPUKernel
flipGPUKernel
All of them take clContext
(which is device's environment abstraction) and localWorkSize
(which shows the size of local work group) as input parameters.
You can use either single-threaded GPU-based image processing or multi-threaded image processing. Multithreading is performed using logger and agent functions, which specified in this section.
Four of them are implemented:
Open library and load image to process:
open MyImage
open GPU
let myImage = load ("Full/Path/To/Images/Folder/image_name.jpg")
Before creating our function we need to do some steps for diagnosing graphical device.
Define the device
value by specifying the brand of your GPU or whatever the program finds (embedded graphics cards are also suitable).
And make OpenCL context of it:
let device = Brahma.FSharp.ClDevice.GetFirstAppropriateDevice()
let clContext = Brahma.FSharp.ClContext(device)
Next, define new values for filter and rotation functions. This action is necessary because of compiling kernel function once:
let applyFilterGPU = applyFilter clContext 64
let rotateGPU = rotate clContext 64
Create new function which sequentially applies blur filter and clockwise rotation to images and saves the result:
let applyCustomFilterOnGPU (image: MyImage) (pathToSave : string) =
let blurredImage = image |> applyFilterGPU gaussianBlurKernel
let rotatedImage = blurredImage |> rotateGPU true
save rotatedImage pathToSave
The result:
open MyImage
open GPU
let myImage = load ("Full/Path/To/Images/Folder/image_name.jpg")
let device = Brahma.FSharp.ClDevice.GetFirstAppropriateDevice()
let clContext = Brahma.FSharp.ClContext(device)
let applyFilterGPU = applyFilter clContext 64
let rotateGPU = rotate clContext 64
let applyCustomFilterOnGPU (image: MyImage) (pathToSave : string) =
let blurredImage = image |> applyFilterGPU gaussianBlurKernel
let rotatedImage = blurredImage |> rotateGPU true
save rotatedImage pathToSave
let pathToSave = "Path/To/Directory/image_name.jpg"
applyCustomFilterOnGPU myImage pathToSave
The processImage
function is designed to process directories with various configuration options.
It allows you to choose the type of agent support for processing:
Full
, which uses a single agent for opening, processing and savingPartial
, which uses different agents for each transformation and savingPartialUsingComposition
, which uses one agent for transformation and one for savingNo
, which uses naive image processing functionAnd define a list of transformations to apply to the image, and specify the processing unit (CPU or GPU) for the operation.
Open library and define directories:
open Process
open AgentSupport
let inputDirectory = "Full/Path/To/Input/Images/Folder/"
let outputDirectory = "Full/Path/To/Output/Images/Folder/"
Define list of transformations and filters that will be used:
let imageEditorsList = [Darken; Edges; RotationL]
Note that transformations and filters will be applied sequentially, one-by-one on each image in the specific directory. Choose and define processing unit and multithreading mode.
let processingUnit = GPU Brahma.FSharp.Platform.Nvidia
let agentsSupport = AgentSupport.Full
The result:
open Process
open AgentSupport
let inputDirectory = "Full/Path/To/Input/Images/Folder/"
let outputDirectory = "Full/Path/To/Output/Images/Folder/"
let imageEditorsList = [Darken; Edges; RotationL]
let processingUnit = GPU Brahma.FSharp.Platform.Nvidia
let agentsSupport = AgentSupport.Full
processImages inputDirectory outputDirectory processingUnit imageEditorsList agentsSupport