Skip to content
This repository has been archived by the owner on Jul 6, 2024. It is now read-only.

Commit

Permalink
Update How_Tos
Browse files Browse the repository at this point in the history
  • Loading branch information
PolinaSavelyeva committed Sep 12, 2023
1 parent 1337244 commit b2e0ef6
Show file tree
Hide file tree
Showing 6 changed files with 307 additions and 55 deletions.
7 changes: 4 additions & 3 deletions .fsdocs/cache

Large diffs are not rendered by default.

165 changes: 137 additions & 28 deletions docs/How_Tos/Doing_A_Thing.html

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions docs/Tutorials/Getting_Started.html
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,9 @@ <h3><a name="Using-Your-Own-Code" class="anchor" href="#Using-Your-Own-Code">Usi
<span class="k">let</span> <span class="id">device</span> <span class="o">=</span> <span class="id">Brahma</span><span class="pn">.</span><span class="id">FSharp</span><span class="pn">.</span><span class="id">ClDevice</span><span class="pn">.</span><span class="id">GetFirstAppropriateDevice</span><span class="pn">(</span><span class="pn">)</span>
<span class="k">let</span> <span class="id">clContext</span> <span class="o">=</span> <span class="id">Brahma</span><span class="pn">.</span><span class="id">FSharp</span><span class="pn">.</span><span class="id">ClContext</span><span class="pn">(</span><span class="id">device</span><span class="pn">)</span>

<span class="k">let</span> <span class="id">applyFilterGPU</span> <span class="o">=</span> <span class="id">GPU</span><span class="pn">.</span><span class="id">applyFilter</span> <span class="id">clContext</span> <span class="n">64</span>
<span class="k">let</span> <span class="id">rotateGPU</span> <span class="o">=</span> <span class="id">GPU</span><span class="pn">.</span><span class="id">rotate</span> <span class="id">clContext</span> <span class="n">64</span>

<span class="k">let</span> <span class="id">applyCustomFilterOnGPU</span> <span class="pn">(</span><span class="id">image</span><span class="pn">:</span> <span class="id">MyImage</span><span class="pn">)</span> <span class="pn">(</span><span class="id">pathToSave</span> <span class="pn">:</span> <span onmouseout="hideTip(event, 'fs1', 4)" onmouseover="showTip(event, 'fs1', 4)" class="id">string</span><span class="pn">)</span> <span class="o">=</span>
<span class="k">let</span> <span class="id">blurredImage</span> <span class="o">=</span> <span class="id">image</span> <span class="o">|&gt;</span> <span class="id">applyFilterGPU</span> <span class="id">gaussianBlurKernel</span>
<span class="k">let</span> <span class="id">rotatedImage</span> <span class="o">=</span> <span class="id">blurredImage</span> <span class="o">|&gt;</span> <span class="id">rotateGPU</span> <span class="k">true</span>
Expand Down
2 changes: 1 addition & 1 deletion docs/index.json

Large diffs are not rendered by default.

182 changes: 159 additions & 23 deletions docsSrc/How_Tos/Doing_A_Thing.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,72 +44,145 @@ ImageProcessing supports the following features, which you can use when implemen
For detailed descriptions of all features visit [Api Reference]().


## Simple CPU Example

## Processing on CPU

---

### CPU filter kernels

Filter kernels are used to call ``applyFilter`` function.
You can create 2D byte array as new kernel or use implemented [kernels](https://polinasavelyeva.github.io/ImageProcessing/reference/global-kernels.html) such as:

* Gaussian Blur
* Edges
* Sharpen
* Lighten
* Darken

### Multi-threaded processing on CPU

You can use either single-threaded CPU-based image processing or multi-threaded image processing.
Multithreading is performed using logger and agent functions, which specified in this [section](https://polinasavelyeva.github.io/ImageProcessing/reference/global-agents.html).

Four of them are implemented:

* Logger, which is used to inform user about status of operations, i.e work of another agents
* Saver agent, which save images stored in queue and send messages to logger
* Processing agent, which process images stored in queue using specified transformation and and send messages to logger
* Full processing agent, which do both saving and processing


### Simple CPU Example

Open library and load image to process:

```fsharp
open ImageProcessing
open ImageProcessing.MyImage
open ImageProcessing.CPU
let myImage = MyImage.load ("Full/Path/To/Images/Folder/image_name.jpg")
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 it on CPU:

```fsharp
let applyCustomFilterOnCPU (image: MyImage) (pathToSave : string) =
let blurredImage = image |> CPU.applyFilter gaussianBlurKernel
let rotatedImage = blurredImage |> CPU.rotate true
let blurredImage = image |> applyFilter gaussianBlurKernel
let rotatedImage = blurredImage |> rotate true
MyImage.save rotatedImage pathToSave
save rotatedImage pathToSave
```

The result:

```fsharp
open ImageProcessing
open ImageProcessing.MyImage
open ImageProcessing.CPU
let myImage = MyImage.load ("Full/Path/To/Images/Folder/image_name.jpg")
let myImage = load ("Full/Path/To/Images/Folder/image_name.jpg")
let applyCustomFilterOnCPU (image: MyImage) (pathToSave : string) =
let blurredImage = image |> CPU.applyFilter gaussianBlurKernel
let rotatedImage = blurredImage |> CPU.rotate true
let blurredImage = image |> applyFilter gaussianBlurKernel
let rotatedImage = blurredImage |> rotate true
MyImage.save rotatedImage pathToSave
save rotatedImage pathToSave
let pathToSave = "Path/To/Directory/image_name.jpg"
applyCustomFilterOnCPU myImage pathToSave
```

## Simple GPU Example
## Processing on GPU

---

### GPU filter kernels

Filter kernels are used to call ``applyFilter`` function.
You can create 2D byte array as new kernel or use implemented [kernels](https://polinasavelyeva.github.io/ImageProcessing/reference/global-kernels.html) such as:

* Gaussian Blur
* Edges
* Sharpen
* Lighten
* Darken

### GPU processing kernels

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](https://yaccconstructor.github.io/Brahma.FSharp/Articles/Custom_Kernels.html).
But if you have no need in creating new GPU kernels just use implemented [ones](https://polinasavelyeva.github.io/ImageProcessing/reference/global-gpu.html), 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.

### Multi-threaded processing on GPU

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](https://polinasavelyeva.github.io/ImageProcessing/reference/global-agents.html).

Four of them are implemented:

* Logger, which is used to inform user about status of operations, i.e work of another agents
* Saver agent, which save images stored in queue and send messages to logger
* Processing agent, which process images stored in queue using specified transformation and and send messages to logger
* Full processing agent, which do both saving and processing

Note that using logger via GPU-processing functions can cause unpredictable behavior, i.e the order in which the events occur will be broken due to the specifics of GPU operations.


### Simple GPU Example

Open library and load image to process:

```fsharp
open ImageProcessing
open ImageProcessing.MyImage
open ImageProcessing.GPU
let myImage = MyImage.load ("Full/Path/To/Images/Folder/image_name.jpg")
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 it on GPU. But before it we need to do some steps for diagnosing graphical device.
Create new function which sequentially applies blur filter and clockwise rotation to images and saves it on GPU.
But before it 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:
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:

```fsharp
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:
Next, define new values for filter and rotation functions.
This action is necessary because of compiling [kernel function](#gpu-processing-kernels) once:

```fsharp
let applyFilterGPU = GPU.applyFilter clContext 64
let rotateGPU = GPU.rotate clContext 64
let applyFilterGPU = applyFilter clContext 64
let rotateGPU = rotate clContext 64
```

And the final function:
Expand All @@ -119,26 +192,89 @@ let applyCustomFilterOnGPU (image: MyImage) (pathToSave : string) =
let blurredImage = image |> applyFilterGPU gaussianBlurKernel
let rotatedImage = blurredImage |> rotateGPU true
MyImage.save rotatedImage pathToSave
save rotatedImage pathToSave
```

The result:

```fsharp
open ImageProcessing
open ImageProcessing.MyImage
open ImageProcessing.GPU
let myImage = MyImage.load ("Full/Path/To/Images/Folder/image_name.jpg")
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
MyImage.save rotatedImage pathToSave
save rotatedImage pathToSave
let pathToSave = "Path/To/Directory/image_name.jpg"
applyCustomFilterOnGPU myImage pathToSave
```

## Processing of Multiple Images via Directories

---

### Process parameters

The ``processImage`` function is designed to process directories with various configuration options.
It allows you to choose the type of [agent support](https://polinasavelyeva.github.io/ImageProcessing/reference/process-agentssupport.html) for processing:

* Full, which uses a single agent to open, process and save
* Partial, which uses different agents for each transformation and saving
* PartialUsingComposition, which uses one agent for transformation and one for save
* No, which uses naive image processing function

And define a list of [transformations](https://polinasavelyeva.github.io/ImageProcessing/reference/process-transformations.html) to apply to the image, and specify the [processing unit](https://polinasavelyeva.github.io/ImageProcessing/reference/process-processingunits.html) (CPU or GPU) for the operation.

### Simple Directory Processing Example

Open library and define directories:

```fsharp
open ImageProcessing.Process
open ImageProcessing.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. [Transformations](https://polinasavelyeva.github.io/ImageProcessing/reference/process-transformations.html) type is used to define it:

```fsharp
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](https://polinasavelyeva.github.io/ImageProcessing/reference/process-processingunits.html#CPU) and [multithreading mode](https://polinasavelyeva.github.io/ImageProcessing/reference/process-agentssupport.html).

```fsharp
let processingUnit = GPU Brahma.FSharp.Platform.Nvidia
let agentsSupport = AgentSupport.Full
```

The result:

```fsharp
open ImageProcessing.Process
open ImageProcessing.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
```

3 changes: 3 additions & 0 deletions docsSrc/Tutorials/Getting_Started.md
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,9 @@ let applyCustomFilterOnCPU (image: MyImage) (pathToSave : string) =
let device = Brahma.FSharp.ClDevice.GetFirstAppropriateDevice()
let clContext = Brahma.FSharp.ClContext(device)
let applyFilterGPU = GPU.applyFilter clContext 64
let rotateGPU = GPU.rotate clContext 64
let applyCustomFilterOnGPU (image: MyImage) (pathToSave : string) =
let blurredImage = image |> applyFilterGPU gaussianBlurKernel
let rotatedImage = blurredImage |> rotateGPU true
Expand Down

0 comments on commit b2e0ef6

Please sign in to comment.