Skip to content

Commit 7a07f64

Browse files
committed
adding final draft for convolution chapter
1 parent 427e36e commit 7a07f64

File tree

7 files changed

+36
-13
lines changed

7 files changed

+36
-13
lines changed

SUMMARY.md

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,6 @@
1717
* [Convolutions in 1D](contents/convolutions/1d/1d.md)
1818
* [Convolutions of images (2D)](contents/convolutions/2d/2d.md)
1919
* [Convolutional Theorem](contents/convolutions/convolutional_theorem/convolutional_theorem.md)
20-
* [Sorting and Searching](contents/sorting_and_searching/sorting_and_searching.md)
21-
* [Bubble Sort](contents/bubble_sort/bubble_sort.md)
22-
* [Bogo Sort](contents/bogo_sort/bogo_sort.md)
2320
* [Tree Traversal](contents/tree_traversal/tree_traversal.md)
2421
* [Euclidean Algorithm](contents/euclidean_algorithm/euclidean_algorithm.md)
2522
* [Monte Carlo](contents/monte_carlo_integration/monte_carlo_integration.md)

contents/convolutions/1d/1d.md

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,10 @@ With this in mind, we can almost directly transcribe the discrete equation into
5555
[import:29-48, lang:"julia"](../code/julia/1d_convolution.jl)
5656
{% endmethod %}
5757

58+
The easiest way to think about this is to read it as you might read a textbook.
59+
For each element in the output domain, we are summing a certain subsets of elements from `i-length(filter)` to `i` after multiplying it by the reversed filter (filter[i-j]`).
60+
In this way, it is precisely the same as the mathematical notation mentioned before.
61+
5862
In contrast to the animation, where the filter continuously reappears on the left edge of the screen, the code we have written for this part of the chapter requires the user to specify what they expect the output array length to be.
5963
Determining what should happen at the edges of the convolution is a somewhat hotly debated topic and differs depending on what the user actually wants, so we will be discussing this in greater detail later in this chapter.
6064

@@ -166,11 +170,13 @@ Your browser does not support the video tag.
166170
</div>
167171

168172
Similar to the case without boundary conditions, this convolution needs to "ramp up," but not "ramp down."
169-
This is because the convolution output no longer extends past the bounds of the original signal.
173+
This is because the convolution output no longer extends past the bounds of the original signal so the bounded convolution is a subset of the full convolution.
170174
More than that, the convolution does not go all the way to 0 on the right side.
171175
This means that we are actually ignoring a rather important part of the convolution!
172176

173177
This is 100% true; however, if the signal is large and the filter is small (as is the case with most of image processing), we do not really care that much about the bits of the convolution we missed.
178+
In addition, there is a way to center the convolution by modifying the location where the filter starts.
179+
For example, we could have half of the filter already existing and overlapping with the signal for the very first computed point of the convolution.
174180
For this reason, simple bounds are used frequently when performing convolutions on an image.
175181

176182
In the previous code snippet, we were able to perform both a bounded and unbounded convolution.
@@ -196,7 +202,16 @@ On the other hand, the bounded call would set the output array size to simply be
196202
[import:65-66, lang:"julia"](../code/julia/1d_convolution.jl)
197203
{% endmethod %}
198204

199-
As another note, the point we are computing for the convolution in the previous animation seems to be at the very front of the Gaussian to match the code; however, it is possible to compute the convolution at the center of the filter by giving the iterations through `j` an offset.
205+
Finally, as we mentioned before, it is possible to center bounded convolutions by changing the location where we calculate the each point along the filter.
206+
This can be done by modifying the following line:
207+
208+
{% method %}
209+
{% sample lang="jl" %}
210+
[import:37-37, lang:"julia"](../code/julia/1d_convolution.jl)
211+
{% endmethod %}
212+
213+
Here, `j` counts from `i-length(filter)` to `i`.
214+
To center the convolution, it would need to count from `i-(length(filter)/2)` to `i+(length(filter)/2)` instead.
200215

201216
I think this is a good place to stop discussions on the simple boundary conditions.
202217
Now let us talk a bit more in detail about the case where we want to filter to continuously reappear every loop.
@@ -329,13 +344,23 @@ This will be discussed in further detail when we talk about the Schonhage-Strass
329344
## Example Code
330345

331346
For the full code, we have used the convolution to generate a few files for the full convolution, along with the periodic and simple boundary conditions discussed in this chapter.
332-
At a test case, we have chosen to use a random distribution for the input signal and a Gaussian filter.
333347

334348
{% method %}
335349
{% sample lang="jl" %}
336350
[import, lang:"julia"](../code/julia/1d_convolution.jl)
337351
{% endmethod %}
338352

353+
At a test case, we have chosen to use two sawtooth functions, which should produce the following images:
354+
355+
| Description | Image |
356+
| ----------- | ----- |
357+
| Simple Boundaries | <img class="center" src="../res/simple_linear.png" style="width:100%" /> |
358+
| Full | <img class="center" src="../res/full_linear.png" style="width:100%" /> |
359+
| Cyclic | <img class="center" src="../res/cyclic.png" style="width:100%" /> |
360+
361+
As a sanity check, make sure that the bounded convolution is a subset of the full convolution.
362+
In this example, the bounded convolution is the start of the full convolution, but it is entirely possible it could be the middle or somewhere else entirely depending on how you counted within the inner, summation loop for the convolution.
363+
339364
<script>
340365
MathJax.Hub.Queue(["Typeset",MathJax.Hub]);
341366
</script>
@@ -357,6 +382,9 @@ The code examples are licensed under the MIT license (found in [LICENSE.md](http
357382
- The video "[Sawtooth Square Convolution](../res/1d_sawtooth.mp4)" was created by [James Schloss](https://github.com/leios) and is licensed under the [Creative Commons Attribution-ShareAlike 4.0 International License](https://creativecommons.org/licenses/by-sa/4.0/legalcode).
358383
- The video "[Full Random Convolution](../res/1d_rand_gaussian_full.mp4)" was created by [James Schloss](https://github.com/leios) and is licensed under the [Creative Commons Attribution-ShareAlike 4.0 International License](https://creativecommons.org/licenses/by-sa/4.0/legalcode).
359384
- The video "[Simple Random Convolution](../res/1d_rand_gaussian_simple.mp4)" was created by [James Schloss](https://github.com/leios) and is licensed under the [Creative Commons Attribution-ShareAlike 4.0 International License](https://creativecommons.org/licenses/by-sa/4.0/legalcode).
385+
- The image "[Simple Linear](../res/simple_linear.png)" was created by [James Schloss](https://github.com/leios) and is licensed under the [Creative Commons Attribution-ShareAlike 4.0 International License](https://creativecommons.org/licenses/by-sa/4.0/legalcode).
386+
- The image "[Full Linear](../res/full_linear.png)" was created by [James Schloss](https://github.com/leios) and is licensed under the [Creative Commons Attribution-ShareAlike 4.0 International License](https://creativecommons.org/licenses/by-sa/4.0/legalcode).
387+
- The image "[Cyclic](../res/cyclic.png)" was created by [James Schloss](https://github.com/leios) and is licensed under the [Creative Commons Attribution-ShareAlike 4.0 International License](https://creativecommons.org/licenses/by-sa/4.0/legalcode).
360388

361389

362390
##### Text

contents/convolutions/2d/2d.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -144,8 +144,8 @@ We will definitely return to this topic in the future as new algorithms require
144144

145145
## Example Code
146146

147-
For the full code in this section, we have modified the code from the [one-dimensional convolution chapter](../1d/1d.md) to add a two-dimensional variant for an image of random white noise.
148-
We have also added code to create the Gaussian kernel and Sobel operator.
147+
For the full code in this section, we have modified the visualizations from the [one-dimensional convolution chapter](../1d/1d.md) to add a two-dimensional variant for an image of random white noise.
148+
We have also added code to create the Gaussian kernel and Sobel operator and apply it to the circle, as shown in the text.
149149

150150
{% method %}
151151
{% sample lang="jl" %}

contents/convolutions/code/julia/1d_convolution.jl

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -49,11 +49,9 @@ end
4949

5050
function main()
5151

52-
# Random distribution in x
53-
x = rand(100)
54-
55-
# Gaussian signals
56-
y = [exp(-((i-50)/100)^2/.01) for i = 1:100]
52+
# sawtooth functions for x and y
53+
x = [float(i)/200 for i = 1:200]
54+
y = [float(i)/200 for i = 1:200]
5755

5856
# Normalization is not strictly necessary, but good practice
5957
normalize!(x)

contents/convolutions/res/cyclic.png

26.3 KB
Loading
25.3 KB
Loading
20.1 KB
Loading

0 commit comments

Comments
 (0)