Engee documentation
Notebook

Application of simplex method for optimisation of rank filtering parameters

This paper discusses the implementation and comparison of image processing algorithms in Julia and MATLAB. The main objective is to apply the simplex method to optimise the rank filtering parameters to maximise the contrast of a barcode image.

The algorithm includes the following steps.

  1. Rank-based filtering - noise suppression on the image with adaptive thresholds.
  2. Contrast calculation - estimation of differences between black and white elements of the barcode.
  3. Simplex Optimisation - Find filter parameters that provide the highest possible image quality.

The paper presents code in both languages, provides visual comparison of results and analyses implementation peculiarities.

In [ ]:
Pkg.add("Statistics")

Let's start with visualisation of input data. The figure below shows the initial image of the barcode that we will be working with later.

In [ ]:
using Images
Folder = @__DIR__
puth_to_photo = "$Folder/Img.bmp"
cdata = load(puth_to_photo)  # Загружаем изображение
Out[0]:
No description has been provided for this image

Detailed description of image processing algorithms

1. Ranked filtering (rangefilt)

Purpose: suppresses impulse noise in the barcode image using adaptive thresholds.

Realisations:

  • MATLAB: rangefilt(Initial_Img, T, step)
  • Julia: rangefilt(Initial_Img, T, step=1)

Input parameters:

  • Initial_Img - input image (brightness matrix),
  • T - vector of threshold values,
  • step - filter offset step (by default 1).

Output data:

  • Filtered image (matrix).

Principle of operation:

  1. for each pixel its neighbourhood of size (2*length(T)+1) is analysed;
  2. the median of the neighbourhood is calculated;
  3. the pixel is replaced by the median if the difference with its neighbours exceeds the threshold T.

Key differences between the implementations: | Aspect | MATLAB | Julia | |--------------|---------------------------------|---------------------------------| | Typing | Dynamic | Strict with type annotations | | | Boundary handling | Implicit | Explicit size control | | Vectorisation | Embedded | Using broadcast (.+) | | Performance | JIT compilation | LLVM compilation |

2. Contrast calculation (contrastBC)

Purpose: Quantifies the differences between black and white bar code elements.

Realisations:

  • MATLAB: [contrast, MeanImg] = contrastBC(Initial_Img)
  • Julia: contrast, MeanImg = contrastBC(Initial_Img)

Input parameters:

  • Initial_Img - input image after filtering.

Output data:

  • contrast - numerical estimation of contrast (scalar),
  • MeanImg - image with averaged brightness levels.

Algorithm:

  1. calculation of average brightness profile by columns,
  2. automatic determination of threshold AdaptiveLevel = (Min + Max)/2,
  3. separation into black (BElPos) and white (WElPos) elements,
  4. calculation of contrast using the formula:
 contrast = ((MeanW - MeanB)/255)*(Max - Min)/(Max + Min)

Special features of implementations

  • MATLAB uses the inbuilt function mean with a special output format.
  • Julia uses statistical processing with explicit dimensionality (dims=1).
  • The Julia version requires explicit type conversion for arithmetic operations.

3. simplex optimisation

Purpose: search for optimal filtering parameters maximising contrast.

Realisations:

  • MATLAB: [Xr, I1, MeanImg] = simplex(Xin, J, I)
  • Julia: Xr, I1, MeanImg = simplex(Xin, J, I)

Input parameters:

  • Xin - initial values of factors,
  • J - intervals of variation,
  • I - initial image.

Output data:

  • Xr - matrix of all trial points and target function values,
  • I1 - optimal filtered image,
  • MeanImg - image with selected black/white elements.

The key steps of the algorithm:

  1. construction of the initial simplex (regular polyhedron);
  2. cyclic execution of operations:
    • reflection of the worst vertex,
    • calculation of the target function (contrastBC),
    • adaptation of the simplex shape;
  3. Stopping criterion - reaching 50 iterations.

Comparison of implementations:

Component MATLAB Julia
Working with matrices Built-in operators LinearAlgebra package
Indexing 1-based 0-based for arrays
Memory management Implicit Explicit allocation (similar())
Vectorisation Automatic Requires . operations
OOP approach Procedural Multimethods

** Features of the Julia implementation:**

  • explicit type specification to improve performance,
  • use of broadcasting operations (.+, .*),
  • modular structure with separate functions,
  • multithreading support (not used in this implementation).

Features of MATLAB-implementation:

  • compact recording of matrix operations,
  • automatic processing of boundary conditions,
  • inbuilt support of work with images,
  • use of global workspace for data exchange.

Comparison of algorithms

In [ ]:
using MATLAB
mat"""cd($Folder)"""
@time mat"test_m"
>> >> >>     "X = 8"    "X = 18"    "X = 28"

    "S = 0.73263"    "S = 0.73263"    "S = 0.73263"

  7.044407 seconds (72 allocations: 3.586 KiB)
In [ ]:
@time include("$Folder/test_jl.jl")
X = [8.0 18.0 28.0]
S = [0.7326267443914503 0.7326267443914503 0.7326267443914503]
  3.121629 seconds (27.54 M allocations: 1.824 GiB, 8.88% gc time, 47.39% compilation time)

Analysing the code results, we can notice a difference in the running time by about two times. And we can also see that although the general logic of the algorithms is preserved, the choice of language significantly affects:

  1. the way boundary conditions are processed,
  2. methods of performance optimisation,
  3. the style of code organisation,
  4. the possibilities of extending functionality.

Julia demonstrates a more modern approach with explicit typing and better opportunities for optimisation, whereas MATLAB offers a more compact notation for matrix operations.

Visualisation of results

In [ ]:
function center_text(text::String, width::Int)
    padding = " " ^ div(width - length(text), 2)
    println(padding * text)
end
Out[0]:
center_text (generic function with 1 method)
In [ ]:
# Загружаем изображения
Img_contrastBC_julia = load("$Folder/Img_contrastBC_julia.png")
Img_contrastBC_matlab = load("$Folder/Img_contrastBC_matlab.png")
Img_rangfilt_julia = load("$Folder/Img_rangfilt_julia.png")
Img_rangfilt_matlab = load("$Folder/Img_rangfilt_matlab.png")

# Объединяем изображения
center_text("Julia and MATLAB", 140)
println()
center_text("rangfilt", 140)
display(hcat(Img_rangfilt_julia, Img_rangfilt_matlab))
println()
center_text("contrastBC", 140)
display(hcat(Img_contrastBC_julia, Img_contrastBC_matlab))
                                                              Julia and MATLAB

                                                                  rangfilt
No description has been provided for this image
                                                                 contrastBC
No description has been provided for this image

As we can see, the images are identical, indicating that the algorithms implemented are of the same type.

Conclusions

  1. Both languages have successfully coped with the task, but MATLAB showed more concise syntax when working with matrices.
  2. The implemented simplex method effectively optimised the filtering parameters, as evidenced by the visual improvement in contrast.
  3. Comparison of images after processing (rangfilt and contrastBC) demonstrates similar results.

Further research could be directed towards:

  1. speeding up the computation in Julia by applying parallel computing,
  2. testing on more complex noisy images,
  3. comparison with other optimisation methods (gradient descent, genetic algorithms).