---
# System prepended metadata

title: Untitled

---

## Concurrent project - Convolution 2D
Besmir Silka & Dylan Wacker
Concurrent computing
HEPIA - 2021

## Contents

1. [Short description](#short-description)
2. [Authors](#authors)
3. [Project state](#project-state)
4. [Concurrent approach](#concurrent-approach)
5. [How to run?](#how-to-run?)

## Short description
Discrete 2D convolution is a very common operation in image processing, as it allows to apply a wide range of filters to an image, such as edge detection blurring effects, sharpening, etc.
The disadvantage of this method is that it is relatively heavy to calculate. The goal of this practical work
is to parallelize the computation of the discrete 2D convolution in order to accelerate the computation, this thanks to
the use of threads on modern multi-core processor architectures.
The 2D discrete convolution C between the kernel K (filter) of dimension N and the image I is defined at
point (x,y) of the image by the following equation :

![equationconvolution](res/equationconvolution.png)

## Project state
The two versions are working, sequential and multi-threads. The dimensions of the filters matrix doesn't matter, you can put a 3x3, 5x5, 7x7, etc.. The only important things is that the matrix must be odd and have a minimum size of 3. We tested with these filters: 

![equationconvolution](res/filtres.png)

In our method we decided to ignore the image border, so the output images lost the border of the original image. We could have decided to replace the non-existent pixels with "0" in order to keep the borders.


## Concurrent approach
We decided to cut the image in portion of number of threads

    int size_portion = (img->width * img->height) / nb_threads;
    
Each thread will calculate a portion of the image independently. For example, if we have a image of 16x10, each thread will will take care of a different color on the example image below.   

![equationconvolution](res/exemple_cut.png)

We decided to do like this, because you can choose how many thread you want. The work is equitably shared between thread.

## Performance
The difference between the sequential version(1 thread) and multi-threads version is significative. More threads you add, better is the result. But by going beyond 64, most of the time we lose performance, this is probably due to the creation time of all threads which slows down the execution.

![equationconvolution](res/performance.png)

## How to run?
    $> make main

Sequential version
    
    $> ./main image_source.ppm image_destination.ppm filtername

Multi-threads version
    
    $> ./main image_source.ppm image_destination.ppm filtername threads_number

    
## Authors
* **Silka Besmir** - *Worked on all the project* - [Silka Besmir](https://gitedu.hesge.ch/besmir.silka)
* **Wacker Dylan** - *Worked on all the project* - [Wacker Dylan](https://gitedu.hesge.ch/dylan.wacker)
