99 lines
4.6 KiB
HTML
Executable file
99 lines
4.6 KiB
HTML
Executable file
id: ed
|
||
title: Edge Detection
|
||
date_created: 2021-02-01
|
||
date_last_updated: 2021-02-01
|
||
description: Edge detection algorithm project for a ML course I took for my Masters
|
||
---
|
||
<h2>
|
||
Edge Detection
|
||
</h2>
|
||
<p>
|
||
This was a project that I did with two classmates for a parallel programming class.
|
||
Source code <a href="https://github.com/Avi-1/cp631">here</a>.
|
||
The programming was done in C except for a python script for image pre-processing (it was just much faster to write).
|
||
</p>
|
||
<p>
|
||
Edge detection is usually done with convolutions.
|
||
A convolution is a matrix of values (kernel) that detects the difference in colour density of pixels in an image.
|
||
The kernel is overlayed on the pixel values in the image and each pixel value is multiplied by the value in the kernel above it.
|
||
All the resulting values are added together into a single value.
|
||
The design of the kernel dictates what sort of feature will be detected.
|
||
A large resulting value indicates the presence of the desired feature.
|
||
</p>
|
||
<p>
|
||
This is the sample input image we used for some of the testing.
|
||
</p>
|
||
<figure>
|
||
<img src="/assets/images/InputImage.png" alt="Input" />
|
||
<figcaption>Input image</figcaption>
|
||
</figure>
|
||
<p>
|
||
This image has a lot of both horizontal and vertical lines for detection.
|
||
The image gets converted into grayscale during preprocessing for ease of use.
|
||
</p>
|
||
<p>
|
||
We used Sobel Kernels as opposed to designing our own.
|
||
These are very commonly used for edge detection.
|
||
The larger the dimensions of the kernel the larger an area of the image it inspect.
|
||
A smaller kernel will only find very well defined edges.
|
||
3×3 was the smallest kernel that we used.
|
||
</p>
|
||
<figure>
|
||
<img src="/assets/images/Horizontal3x3.png" alt="Horizontal line 3x3 kernel" />
|
||
<img src="/assets/images/Vertical3x3.png" alt="Vertical line 3x3 kernel" />
|
||
<figcaption>3x3 Soebel Kernels (left:Horizontal, right:Vertical)</figcaption>
|
||
</figure>
|
||
<p>
|
||
These kernels found the very defined edges on the sides of the trees and branches.
|
||
This includes their reflections in the water below, though the reflection did dampen the edges a fair bit.
|
||
</p>
|
||
<figure>
|
||
<img src="/assets/images/Output3x3.png" alt="3x3 detection output" />
|
||
<figcaption>3x3 Edge detection output</figcaption>
|
||
</figure>
|
||
<p>
|
||
As you can see it picked up almost nothing from the sky in the image.
|
||
We also tested kernels of size 5×5, 7×7, and 9×9.
|
||
Here are the 9×9 kernels we used.
|
||
</p>
|
||
<figure>
|
||
<img src="/assets/images/Horizontal9x9.png" alt="Horizontal line 9x9 kernel" />
|
||
<img src="/assets/images/Vertical9x9.png" alt="Horizontal line 9x9 kernel" />
|
||
<figcaption>9x9 Soebel Kernels (left:Horizontal, right:Vertical)</figcaption>
|
||
</figure>
|
||
<p>
|
||
These large kernels will detect differences in gradient across a much larger portion of the image at once.
|
||
This results in a much more textured image.
|
||
</p>
|
||
<figure>
|
||
<img src="/assets/images/Output9x9.png" alt="9x9 detection output" />
|
||
<figcaption>9x9 Edge detection output</figcaption>
|
||
</figure>
|
||
<p>
|
||
As you can see the trees are almost a uniform mass of edges.
|
||
The reflections less so but still very dense.
|
||
It did also manage to pick up the texture of the clouds.
|
||
Different kernels are good at detecting different types of edges.
|
||
A smaller kernel will be much better for sharp edges and will ignore the rest.
|
||
A larger kernel will get much less well defined edges.
|
||
</p>
|
||
<p>
|
||
There is also a large difference in the speed of the program, a larger kernel has significantly more operations that need to be performed.
|
||
After the application of the convolutions the rest of the project was parallelizing this process in an effort to speed it up.
|
||
We used both Message Passing Interface (MPI) and CUDA for parallelization in order to compare them.
|
||
MPI uses the CPU and so is limited by the number of cores the CPU of the device has.
|
||
CUDA uses the graphics card so has many more cores to work with but has more overhead.
|
||
</p>
|
||
<figure>
|
||
<img src="/assets/images/ConvolutionTime.png" alt="Convolution time graph" />
|
||
</figure>
|
||
<p>
|
||
Unless you have access to a large number of CPU cores CUDA is almost always better.
|
||
For a general application as long as you have access to a graphics card CUDA is the way to go.
|
||
</p>
|
||
<p>
|
||
This project was very enlightening as to how the underlying processes for image recognition work.
|
||
I have done a little bit of machine learning with convolutional neural networks, but for most libraries this portion is already done for you.
|
||
Understanding what is going on under the hood was very interesting.
|
||
</p>
|