-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
7 changed files
with
593 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
# This is a basic workflow to help you get started with Actions | ||
|
||
name: CI | ||
|
||
# Controls when the workflow will run | ||
on: | ||
# Triggers the workflow on push or pull request events but only for the "main" branch | ||
push: | ||
branches: [ "main" ] | ||
pull_request: | ||
branches: [ "main" ] | ||
|
||
# Allows you to run this workflow manually from the Actions tab | ||
workflow_dispatch: | ||
|
||
|
||
jobs: | ||
cleanup: | ||
runs-on: ubuntu-latest | ||
permissions: write-all | ||
|
||
steps: | ||
- name: Delete deployment | ||
uses: strumwolf/delete-deployment-environment@v2 | ||
with: | ||
token: ${{ secrets.GITHUB_TOKEN }} | ||
environment: github-pages | ||
onlyRemoveDeployments: true | ||
|
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
{"cells":[{"cell_type":"markdown","id":"fb204713-3bbd-40e3-a23e-bf628ab08497","metadata":{},"source":"Code for Digital Image Processing\n=================================\n\n"},{"cell_type":"markdown","id":"025d85bb-fe4d-49a0-866e-1bdc325996c5","metadata":{},"source":["These are the code snippets used in Mathematical Fundamentals\npart of Digital Image Processing.\n\n"]},{"cell_type":"markdown","id":"59189747-5928-40e8-a56a-8d44c91f10ca","metadata":{},"source":["### Introduction\n\n"]},{"cell_type":"markdown","id":"15c29ce1-0134-461d-84a1-20582c5fc081","metadata":{},"source":["The following code uses the standard matplotlib along with the\ncustom ChalcedonPy which is detailed in its source code here.\n\nThe code is used primarily in the following code as a means to\nsave figures for use in slides.\n\n"]},{"cell_type":"code","execution_count":1,"id":"45db9e58-7e8e-4f80-ac86-8ca0eb429df5","metadata":{},"outputs":[],"source":["import matplotlib.pyplot as plt\nimport ChalcedonPy as cp\n\n# Initialise ChalcedonPy\ncp.init(save_path=\"Mathematical-Fundamentals\",\n display_mode=\"slide\")"]},{"cell_type":"markdown","id":"6f895dc3-731f-4c32-91e3-43a122f88d1d","metadata":{},"source":["### Introduction\n\n"]},{"cell_type":"markdown","id":"4ece5898-7146-4d3b-9ab7-e05402f5f650","metadata":{},"source":["The following code covers the topic of mathematical fundamentals, which\nincludes some examples on:\n\n- convolution,\n- fourier transform,\n- spectral leakage,\n- information theory.\n\n"]},{"cell_type":"markdown","id":"da33ca9c-454d-40d4-81bc-6e592e374308","metadata":{},"source":["### Exercise: Convolution 1D\n\n"]},{"cell_type":"markdown","id":"5cea3c99-c05a-43ff-9fa7-3ebbd040efde","metadata":{},"source":["The following is the solution to the 1D Convolution question given\nin the lecture\n\n"]},{"cell_type":"code","execution_count":1,"id":"4806c080-9900-49fc-af2d-55c376e1c38f","metadata":{},"outputs":[],"source":["import numpy as np\ndef convolve_1d(signal, kernel):\n kernel = kernel[::-1]\n k = len(kernel)\n s = len(signal)\n signal = [0]*(k-1)+signal+[0]*(k-1)\n n = s+(k-1)\n res = []\n for i in range(s+k-1):\n res.append(np.dot(signal[i:(i+k)], kernel))\n return res"]},{"cell_type":"markdown","id":"931edcbf-dfbf-4347-8ecd-362f76641c66","metadata":{},"source":["Now the function is defined, it is a matter of entering the two arrays\nand printing the function.\n\n"]},{"cell_type":"code","execution_count":1,"id":"634fde00-ba71-4607-b631-194620958165","metadata":{},"outputs":[],"source":["A = [1,1,2,2,1]\nB = [1,1,1,3]\n\nprint(convolve_1d(A, B))"]},{"cell_type":"markdown","id":"a71d0184-79c8-4315-bb06-b62c717680f9","metadata":{},"source":["### Shannon Nyquist Sampling Theorem\n\n"]},{"cell_type":"markdown","id":"7c72dfc9-5045-4fd0-9264-1c1b2dc29636","metadata":{},"source":["Below is an unused code which showcases the practical\nlimitation of the Shannon-Nyquist theorem.\n\n"]},{"cell_type":"code","execution_count":1,"id":"930f5784-b6f1-4dd2-9299-e12c6e028ca9","metadata":{},"outputs":[],"source":["import numpy as np\nfrom matplotlib import pyplot as plt\n\nwave_freq = 5\ndomain = 1\n\nsample_rates = (\n (wave_freq * 2 - 1, 'below Nyquist rate'),\n (wave_freq * 2, '(exclusive) lower bound according to Nyquist?'),\n (wave_freq * 2 + 1, 'bit more than Nyquist'),\n (wave_freq * 4, 'double Nyquist'),\n)\n\nn_plots = len(sample_rates) + 1\n\nfig = plt.figure(figsize=(8, 10))\nax = fig.add_subplot(n_plots, 1, 1)\ntime = np.linspace(0, domain, 1000, endpoint=False) # take enough samples to make a seemingly perfect sine wave\nhi_res = np.sin(2 * np.pi * wave_freq * time)\nax.axhline(color=\"0.7\")\nax.plot(time, hi_res, label=f'{wave_freq}Hz wave')\nax.legend(loc=1)\nylim = ax.get_ylim()\n\nfor i, (sample_rate, title) in enumerate(sample_rates):\n ax = fig.add_subplot(n_plots, 1, i+2)\n\n t = np.linspace(0, domain, sample_rate, endpoint=False)\n samples = np.sin((2 * np.pi * wave_freq) * t)\n ax.axhline(color=\"0.7\")\n ax.plot(time, hi_res, label=f'{wave_freq}Hz wave', color='0.8') # show what we're aiming for\n ax.plot(t, samples, marker='o', label=f'{sample_rate}Hz sample rate ({sample_rate/wave_freq}x)')\n ax.set_ylim(*ylim)\n ax.legend(loc=1)\n ax.set_title(title)\n \nplt.show()"]},{"cell_type":"markdown","id":"c6ee94b6-7e93-4595-98d7-5f138199c0a3","metadata":{},"source":["### Spectral Leakage\n\n"]},{"cell_type":"markdown","id":"e82448b9-f165-46c6-a3e8-0040ce0adc2c","metadata":{},"source":["Let’s take a look at an example using a simple sine wave.\nFirst import the necessary modules.\n\n"]},{"cell_type":"code","execution_count":1,"id":"d0e371cc-53f8-4e60-af5f-00d7d15a8436","metadata":{},"outputs":[],"source":["import numpy as np\nimport matplotlib.pyplot as plt\nimport scipy.stats as st\nimport scipy.signal as sig"]},{"cell_type":"markdown","id":"a7c74e57-661a-4c50-8f1b-67814d7b8f3d","metadata":{},"source":["Let’s define a sine function on a time domain, such that\nthe sine function completes $N$, integer cycles, i.e.,\nno cycles are cut-off within the domain.\n\n"]},{"cell_type":"code","execution_count":1,"id":"8f9332cf-4a87-4092-9f5d-ded6fc63c47e","metadata":{},"outputs":[],"source":["import numpy as np\n\nT = 8 * np.pi # length of time domain\nt = np.arange(0, T + 0.05 * np.pi, 0.05 * np.pi)\nfreq = np.arange(0, int(len(t) / 2.0) + 1) / len(t)\ny_sin = np.sin(t) # define the sin function"]},{"cell_type":"markdown","id":"722179f4-c67c-4f4e-a8be-3e4b1637b0d8","metadata":{},"source":["Now, we can define and plot our sine function.\n\n"]},{"cell_type":"code","execution_count":1,"id":"8cd15673-c5df-40d3-a42b-7d2828c4e7f0","metadata":{},"outputs":[],"source":["plt.plot(t,y_sin)\nplt.xlabel(\"Data Points\")\nplt.ylabel(\"Amplitude\")\nplt.title(\"Sine Wave\")\nplt.show()"]},{"cell_type":"markdown","id":"30c8ad06-152d-4f97-9715-ba6f23308bab","metadata":{},"source":["Here, we have 4 complete cycles of our sine wave.\nNow, let’s compute the discrete power spectrum of this sine wave.\n\n"]},{"cell_type":"code","execution_count":1,"id":"a7561cab-6d6d-4a75-aeb0-323dddaad111","metadata":{},"outputs":[],"source":["# Do simple fft of the signal\nyfft1_raw = np.fft.fft(y_sin)\nyfft1 = yfft1_raw/len(y_sin)\n\n# compute variance as a function of frequency (spectral power)\nPSD = 2*np.abs(yfft1[0:int(len(t)/2.0+1)])**2"]},{"cell_type":"markdown","id":"826ea80c-df29-4356-aa39-84816f477d42","metadata":{},"source":["And time for plotting out FFT results\n\n"]},{"cell_type":"code","execution_count":1,"id":"91a68382-99b1-4361-bd11-35332c411c73","metadata":{},"outputs":[],"source":["plt.bar(freq, PSD, width=0.0025)\n\nplt.xlabel('Frequency (cycles per time step)')\nplt.ylabel('Normalized Power')\nplt.title(\"D-PSD for Un-windowed Sine Wave\")\nplt.xlim(0,0.1)\n\nplt.show()"]},{"cell_type":"markdown","id":"0a803b6f-9bf1-4e00-91f4-a32af10b24a1","metadata":{},"source":["We get a single spectral peak corresponding to the frequency of our\nsine wave.\n\nNow, let’s see what happens if we apply a window to our sine wave\nthat cuts off the sine wave such that the sine function does not\ncomplete an integer number of cycles within the time domain.\n\n"]},{"cell_type":"code","execution_count":1,"id":"f387abb0-7f6d-4691-a197-deae7aa07739","metadata":{},"outputs":[],"source":["# Now let's window our data, such that we are not cleanly sampling our sine function\ny2 = []\nbxcr = []\nfor i in t:\n if (i < 1.5*np.pi) or (i > 6.5*np.pi):\n y2.append(0)\n bxcr.append(0)\n else:\n y2.append(np.sin(i))\n bxcr.append(1)\ny2 = np.asarray(y2)\nbxcr = np.asarray(bxcr)"]},{"cell_type":"markdown","id":"13627d17-21e8-4360-bf24-31400d7bbb3b","metadata":{},"source":["Results calculated, lets do some plotting.\n\n"]},{"cell_type":"code","execution_count":1,"id":"414c6f3d-8cd2-4d1e-814a-d560114e8d28","metadata":{},"outputs":[],"source":["# Plot windowed sine wave, window\nplt.subplot(2,1,1)\nplt.plot(t,y2, label=\"windowed sine wave\")\nplt.plot(t,bxcr, label=\"box wave\")\nplt.title('Windowed Sine Wave')\nplt.legend(loc=\"lower right\")\n\nplt.subplot(2,1,2)\nplt.plot(t,y2*bxcr)\nplt.title('Also a Windowed Sine Wave')\n\nplt.show()"]},{"cell_type":"markdown","id":"364e2787-f301-495c-9741-27172e45dc89","metadata":{},"source":["To demonstrate what spectral leakage is, we will now compute\nthe discrete power spectrum of the windowed sine wave to see what happens.\n\n"]},{"cell_type":"code","execution_count":1,"id":"63921acc-b477-4e55-b747-711f4592d70b","metadata":{},"outputs":[],"source":["# compute FFT\nyfft2_raw = np.fft.fft(y2)\nyfft2 = yfft2_raw/len(y2)\n\n# compute variance as a function of frequency (spectral power)\nck2y2 = 2*np.abs(yfft2[0:int(len(t)/2.0+1)])**2"]},{"cell_type":"code","execution_count":1,"id":"b9df5d3f-f598-43ec-b693-15ceeee3761a","metadata":{},"outputs":[],"source":["# Plot Power Spectrum of windowed data\nplt.bar(freq,ck2y2,width=0.0025)\nplt.xlabel('Frequency [Hz]')\nplt.ylabel('PSD [W]')\nplt.title(\"Discrete Power Spectrum for Windowed Sine Wave\")\nplt.xlim(0,0.1)\n\nplt.show()"]}],"metadata":{"org":null,"kernelspec":{"display_name":"Python 3","language":"python","name":"python3"},"language_info":{"codemirror_mode":{"name":"ipython","version":3},"file_extension":".py","mimetype":"text/x-python","name":"python","nbconvert_exporter":"python","pygments_lexer":"ipython3","version":"3.5.2"}},"nbformat":4,"nbformat_minor":5} |
Oops, something went wrong.