├── .gitignore ├── README.md ├── ROS ├── spyke_coding │ ├── CMakeLists.txt │ ├── launch │ │ ├── encode_bsa.launch │ │ ├── encode_gaussian_fields.launch │ │ ├── encode_hough.launch │ │ ├── encode_moving_window.launch │ │ ├── encode_step_forward.launch │ │ ├── encode_temporal_contrast.launch │ │ └── encode_threshold_hough.launch │ ├── package.xml │ └── src │ │ └── generate_spikes.py ├── spyke_coding_schemes │ ├── CMakeLists.txt │ ├── package.xml │ ├── setup.py │ └── src │ │ └── spyke_coding_schemes │ │ ├── DecodingSchemes.py │ │ ├── EncodingSchemes.py │ │ ├── __init__.py │ │ └── __pycache__ │ │ ├── DecodingSchemes.cpython-38.pyc │ │ └── EncodingSchemes.cpython-38.pyc └── spyke_msgs │ ├── CMakeLists.txt │ ├── msg │ ├── spyke.msg │ └── spyke_array.msg │ └── package.xml ├── SpikeCodingMatlab ├── BenSpikeDecoding.m ├── BenSpikeEncoding.m ├── Benchmark.m ├── BohteDecoding.m ├── BohteEncoding.m ├── GaussianReceptFieldsDecoding.m ├── GaussianReceptFieldsEncoding.m ├── HoughSpikeEncoding.m ├── HoughSpikeModifiedEncoding.m ├── ImageCoding.m ├── MovingWindowDecoding.m ├── MovingWindowEncoding.m ├── RMSE.m ├── SpikeCoding.m ├── StepForwardDecoding.m ├── StepForwardEncoding.m ├── TemporalContrastDecode.m ├── TemporalContrastEncode.m ├── benchmark_rmse_case_0.png ├── benchmark_rmse_case_1.png ├── benchmark_rmse_case_2.png ├── benchmark_rmse_case_3.png ├── benchmark_rmse_case_4.png ├── benchmark_spike_efficiency_case_0.png ├── benchmark_spike_efficiency_case_1.png ├── benchmark_spike_efficiency_case_2.png ├── benchmark_spike_efficiency_case_3.png ├── benchmark_spike_efficiency_case_4.png ├── benchmark_tests_plot_GRF_case0.png ├── benchmark_tests_plot_GRF_case1.png ├── benchmark_tests_plot_GRF_case2.png ├── benchmark_tests_plot_GRF_case3.png ├── benchmark_tests_plot_GRF_case4.png ├── benchmark_tests_plot_case0.png ├── benchmark_tests_plot_case1.png ├── benchmark_tests_plot_case2.png ├── benchmark_tests_plot_case3.png ├── benchmark_tests_plot_case4.png ├── image_sf_threshold_1.png ├── image_sf_threshold_10.png ├── image_sf_threshold_20.png ├── image_sf_threshold_5.png ├── spikePlot.m ├── test-1.png ├── test-2.png └── test-3.png └── SpikeCodingPython ├── Bags ├── gaussian_fields.bag ├── moving_window.bag ├── step_forward.bag └── temporal_contrast.bag ├── DecodingSchemes.py ├── EncodingSchemes.py ├── FunctionGenerator.py ├── __pycache__ ├── DecodingSchemes.cpython-38.pyc ├── EncodingSchemes.cpython-38.pyc └── FunctionGenerator.cpython-38.pyc ├── bag_gaussian_fields.png ├── bag_moving_window.png ├── bag_step_forward.png ├── bag_temporal_contrast.png ├── main.py ├── process_rosbags.py ├── test-1.png ├── test-2.png └── test-3.png /.gitignore: -------------------------------------------------------------------------------- 1 | SpikeCodingPython/test.py 2 | SpikeCodingPython/grf_comparison.py 3 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # SpikeCoding 2 | 3 | This package features MATLAB, Python and ROS implementations of spike encoding and decoding algorithms. So far, the following algorithms are available: 4 | - Population coding: 5 | - [Matlab][Python][ROS] Gaussian Receptor Fields 6 | - [Matlab][Python] Bohté et al. (2002) GRF 7 | - Temporal coding: 8 | - [Matlab][Python][ROS] Temporal contrast 9 | - [Matlab][Python][ROS] Step-forward 10 | - [Matlab][Python][ROS] Moving window 11 | - Rate coding: 12 | - [Matlab][Python] Hough spike 13 | - [Matlab][Python] Threshold Hough 14 | - [Matlab][Python] Ben's spike 15 | 16 | Supporting paper: https://arxiv.org/abs/2103.02751 17 | 18 | TODOs: 19 | - Finish integration of rate coding to ROS node 20 | - Add Population schemes to ROS node 21 | - Implement the following schemes: non-linear GRF, ROC, Poisson, LPC. 22 | - Upload review table & add references on README 23 | - Generate tests for MNIST dataset 24 | - Generate tests for IMU data from the Obstacle Detection & Avoidance Dataset 25 | - Setup framework for parameters optimisation (DEAP, PyEvolve, PyBrain) 26 | - Include to PySNN (?) 27 | 28 | --- 29 | 30 | *This work is part of the Comp4Drones project and has received funding from the ECSEL Joint Undertaking (JU) under grant agreement No. 826610. The JU receives support from the European Union's Horizon 2020 research and innovation program and Spain, Austria, Belgium, Czech Republic, France, Italy, Latvia, Netherlands.* 31 | 32 | --- 33 | 34 | ## 1. MATLAB Implementation 35 | 36 | The MATLAB codes are available in *SpikeCodingMatlab*. Within this folder, simply execute the `SpikeCoding.m` file to have an overview of the results (encoding/decoding) of the implemented schemes tested on 3 different functions. 37 | 38 | ## 2. Python Impmementation 39 | 40 | The Python scripts are available in *SpikeCodingPython*. Within this folder, simply execute the `main.py` file to have an overview of the results (encoding/decoding) of the implemented schemes tested on 3 different functions. 41 | 42 | Here you can find the results: 43 | 44 | ![](SpikeCodingPython/test-1.png) 45 | 46 | ![](SpikeCodingPython/test-2.png) 47 | 48 | ![](SpikeCodingPython/test-3.png) 49 | 50 | ## 3. ROS Package 51 | 52 | The ROS folder contains the following packages: 53 | - *spyke_coding*: creates a ROS node to generate spikes based on input data and the selected coding scheme. 54 | - *spyke_coding_schemes*: includes all the encoding and decoding functions used in the *spyke_coding* package. 55 | - *spyke_msgs*: defines the custom spiking messages to be published. 56 | 57 | ### Installing 58 | 59 | Install ROS Noetic (for Ubuntu Focal 20.04 LTS) using the following tutorial:
http://wiki.ros.org/noetic/Installation/Ubuntu 60 | 61 | Install *catkin* python tools: 62 | 63 | sudo apt-get install python3-catkin-tools 64 | 65 | Install additionnal dependencies: 66 | 67 | sudo apt install python3-catkin-lint python3-pip 68 | pip3 install osrf-pycommon==0.1.9 69 | pip3 install empy 70 | 71 | Then create your workspace: 72 | 73 | cd~ 74 | mkdir -p catkin_ws/src 75 | 76 | Clone this repository, and copy the ROS packages to your `~/catkin_ws/src/` folder. Then compile your project: 77 | 78 | cd /catkin_ws/ 79 | catkin_make 80 | source ~/catkin_ws/devel/setup.bash 81 | 82 | ### Testing 83 | 84 | The *spyke_coding* package includes a set of launch files for each type of encoding. In its present form, the package defines a fake signal with a given sampling period `dt` and a signal duration `T_max` (in seconds). Both temporal and rate coding schemes use a buffer of size `1/dt`. 85 | 86 | Once the ROS node is launched, it automatically stops after `T_max` seconds, or if the user press `ctrl+c`. The output data is stored here: `~/.ros/encoding.bag` 87 | 88 | Example on the temporal-contrast encoding: 89 | 90 | cd /catkin_ws/ 91 | source ~/catkin_ws/devel/setup.bash 92 | roslaunch spyke_coding encode_temporal_contrast.launch 93 | 94 | After completion, you can plot the results using the dedicated Python script: 95 | 96 | cd /SpikeCodingPython/ 97 | python process_rosbags.py ~/.ros/encoding.bag 98 | 99 | Here is an example result: 100 | 101 | ![](SpikeCodingPython/bag_temporal_contrast.png) 102 | 103 | List of the available launch files: 104 | - `encode_temporal_contrast.launch` 105 | - `encode_step_forward.launch` 106 | - `encode_moving_window.launch` 107 | - `encode_hough.launch` 108 | - `encode_threshold_hough.launch` 109 | - `encode_bsa.launch` 110 | - `encode_gaussian_fields.launch` 111 | 112 | ## Application to images encoding 113 | 114 | TODO: 115 | - add other methods 116 | - generate videos 117 | - plot error between original and reconstruction 118 | - include in ROS 119 | - test on MNIST 120 | 121 | Based on video available in the ODA Dataset: https://github.com/JuSquare/ODA_Dataset/tree/master/dataset 122 | 123 | Step Forward (SF) Temporal Coding with Threshold = 1
124 | ![](SpikeCodingMatlab/image_sf_threshold_1.png) 125 | 126 | 127 | Step Forward (SF) Temporal Coding with Threshold = 5
128 | ![](SpikeCodingMatlab/image_sf_threshold_5.png) 129 | 130 | Step Forward (SF) Temporal Coding with Threshold = 10
131 | ![](SpikeCodingMatlab/image_sf_threshold_10.png) 132 | 133 | Step Forward (SF) Temporal Coding with Threshold = 20
134 | ![](SpikeCodingMatlab/image_sf_threshold_20.png) 135 | -------------------------------------------------------------------------------- /ROS/spyke_coding/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.0.2) 2 | project(spyke_coding) 3 | 4 | find_package(catkin REQUIRED COMPONENTS rospy std_msgs) 5 | 6 | catkin_package( 7 | LIBRARIES spyke_coding spyke_coding_schemes 8 | CATKIN_DEPENDS rospy std_msgs 9 | ) 10 | 11 | catkin_install_python(PROGRAMS src/generate_spikes.py 12 | DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}) 13 | 14 | -------------------------------------------------------------------------------- /ROS/spyke_coding/launch/encode_bsa.launch: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /ROS/spyke_coding/launch/encode_gaussian_fields.launch: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /ROS/spyke_coding/launch/encode_hough.launch: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /ROS/spyke_coding/launch/encode_moving_window.launch: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /ROS/spyke_coding/launch/encode_step_forward.launch: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /ROS/spyke_coding/launch/encode_temporal_contrast.launch: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /ROS/spyke_coding/launch/encode_threshold_hough.launch: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /ROS/spyke_coding/package.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | spyke_coding 4 | 0.0.0 5 | The spyke_coding package 6 | Julien Dupeyroux 7 | MIT 8 | 9 | catkin 10 | rospy 11 | spyke_msgs 12 | std_msgs 13 | rospy 14 | spyke_msgs 15 | std_msgs 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /ROS/spyke_coding/src/generate_spikes.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python 2 | 3 | # This file is part of the SpikeCoding repository - MAVLab TU Delft 4 | # 5 | # MIT License 6 | # 7 | # Copyright (c) 2021 Julien Dupeyroux 8 | # 9 | # Permission is hereby granted, free of charge, to any person obtaining a copy 10 | # of this software and associated documentation files (the "Software"), to deal 11 | # in the Software without restriction, including without limitation the rights 12 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 | # copies of the Software, and to permit persons to whom the Software is 14 | # furnished to do so, subject to the following conditions: 15 | # 16 | # The above copyright notice and this permission notice shall be included in all 17 | # copies or substantial portions of the Software. 18 | # 19 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 25 | # SOFTWARE. 26 | # 27 | # @author Julien Dupeyroux 28 | 29 | import rospy 30 | import rosbag 31 | import numpy as np 32 | import math 33 | 34 | from std_msgs.msg import Int32, Float32, String 35 | from spyke_msgs.msg import spyke, spyke_array 36 | import spyke_coding_schemes.EncodingSchemes as encode 37 | import spyke_coding_schemes.DecodingSchemes as decode 38 | 39 | def signal_generator(dt, T_max): 40 | mySin = np.vectorize(math.sin) 41 | time = np.arange(0,T_max,dt) 42 | fake_signal_1D = np.zeros(len(time)) 43 | a = [2, -0.5, 0.75] 44 | f = [1.0, 3.0, 5.0] 45 | phi = [0.0, 0.0, 0.0] 46 | sigma = 0.2 47 | for i in range(len(a)): 48 | fake_signal_1D += a[i]*mySin(2*math.pi*f[i]*time + phi[i]*np.ones(len(time))) + np.random.rand(len(time))*sigma 49 | return fake_signal_1D 50 | 51 | def spikes_publisher(dt, signal): 52 | # Create ROS bag 53 | myBag = rosbag.Bag("encoding.bag", "w") 54 | minSig = min(signal) 55 | maxSig = max(signal) 56 | encoding_scheme = "temporal_contrast" 57 | 58 | # Variables for encoding (buffer, threshold, scaling constants, etc.) 59 | buffer_size = int(1/dt) 60 | buffer = np.zeros(buffer_size) 61 | factor = rospy.get_param('factor') 62 | threshold = rospy.get_param('threshold') 63 | window = rospy.get_param('window') 64 | neurons = rospy.get_param('neurons') 65 | encoding_scheme = rospy.get_param('encoding_scheme') 66 | 67 | # Setup publisher 68 | if encoding_scheme == "gaussian_fields": 69 | pub = rospy.Publisher('event', spyke_array, queue_size=1) 70 | else: 71 | pub = rospy.Publisher('event', spyke, queue_size=1) 72 | 73 | # Init ros node 74 | rospy.init_node('spikes_publisher', anonymous=True) 75 | rate = rospy.Rate(int(1/dt)) 76 | 77 | # Execute node 78 | t = 0 79 | while not rospy.is_shutdown(): 80 | 81 | if encoding_scheme == "gaussian_fields": 82 | # Encode the signal 83 | mySpikes = encode.grf_spike(signal[t], neurons, minSig, maxSig) 84 | # Store data 85 | spyke_event = spyke_array() 86 | spyke_event.spike = np.int8(mySpikes.tolist()) 87 | spyke_event.start = signal[buffer_size-1] 88 | spyke_event.min_input = minSig 89 | spyke_event.max_input = maxSig 90 | spyke_event.threshold = threshold 91 | spyke_event.input = signal[t] 92 | spyke_event.scheme = encoding_scheme 93 | spyke_event.timestamp = rospy.get_rostime() 94 | myBag.write('event', spyke_event) 95 | # Publish event 96 | pub.publish(spyke_event) 97 | 98 | else: 99 | if t < buffer_size: 100 | buffer[t] = signal[t] 101 | else: 102 | # Update the buffer 103 | buffer = np.roll(buffer, -1) 104 | buffer[-1] = signal[t] 105 | # Encode the signal 106 | if encoding_scheme == "temporal_contrast": 107 | mySpikes, threshold = encode.temporal_contrast(buffer, factor) 108 | elif encoding_scheme == "step_forward": 109 | mySpikes, _ = encode.step_forward(buffer, threshold) 110 | elif encoding_scheme == "moving_window": 111 | mySpikes, _ = encode.moving_window(buffer, threshold, window) 112 | else: 113 | rospy.signal_shutdown("No encoding scheme found!") 114 | # Store data 115 | spyke_event = spyke() 116 | spyke_event.spike = np.int8(mySpikes[-1]) 117 | spyke_event.start = signal[buffer_size-1] 118 | spyke_event.min_input = minSig 119 | spyke_event.max_input = maxSig 120 | spyke_event.threshold = threshold 121 | spyke_event.input = signal[t] 122 | spyke_event.scheme = encoding_scheme 123 | spyke_event.timestamp = rospy.get_rostime() 124 | myBag.write('event', spyke_event) 125 | # Publish event 126 | pub.publish(spyke_event) 127 | 128 | rate.sleep() 129 | t += 1 130 | 131 | # Check signal validity 132 | if t == len(signal): 133 | rospy.signal_shutdown("End of signal") 134 | 135 | # Close ROS bag after execution 136 | myBag.close() 137 | 138 | 139 | if __name__ == '__main__': 140 | # Setup fake signal for testing (to be replaced with subscriber to sensor node) 141 | dt = rospy.get_param('dt') 142 | T_max = rospy.get_param('T_max') 143 | signal = signal_generator(dt, T_max) 144 | 145 | # Launch node 146 | try: 147 | spikes_publisher(dt, signal) 148 | except rospy.ROSInterruptException: 149 | pass 150 | -------------------------------------------------------------------------------- /ROS/spyke_coding_schemes/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.0.2) 2 | project(spyke_coding_schemes) 3 | 4 | find_package(catkin REQUIRED COMPONENTS rospy) 5 | 6 | catkin_python_setup() 7 | 8 | catkin_package() -------------------------------------------------------------------------------- /ROS/spyke_coding_schemes/package.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | spyke_coding_schemes 4 | 0.0.0 5 | The spyke_coding_schemes package 6 | Julien Dupeyroux 7 | MIT 8 | 9 | catkin 10 | rospy 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /ROS/spyke_coding_schemes/setup.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python 2 | 3 | # This file is part of the SpikeCoding repository - MAVLab TU Delft 4 | # 5 | # MIT License 6 | # 7 | # Copyright (c) 2021 Julien Dupeyroux 8 | # 9 | # Permission is hereby granted, free of charge, to any person obtaining a copy 10 | # of this software and associated documentation files (the "Software"), to deal 11 | # in the Software without restriction, including without limitation the rights 12 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 | # copies of the Software, and to permit persons to whom the Software is 14 | # furnished to do so, subject to the following conditions: 15 | # 16 | # The above copyright notice and this permission notice shall be included in all 17 | # copies or substantial portions of the Software. 18 | # 19 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 25 | # SOFTWARE. 26 | # 27 | # @author Julien Dupeyroux 28 | 29 | from distutils.core import setup 30 | from catkin_pkg.python_setup import generate_distutils_setup 31 | 32 | setup_args = generate_distutils_setup( 33 | packages=['spyke_coding_schemes'], 34 | package_dir={'': 'src'} 35 | ) 36 | 37 | setup(**setup_args) -------------------------------------------------------------------------------- /ROS/spyke_coding_schemes/src/spyke_coding_schemes/DecodingSchemes.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python 2 | 3 | # This file is part of the SpikeCoding repository - MAVLab TU Delft 4 | # 5 | # MIT License 6 | # 7 | # Copyright (c) 2021 Julien Dupeyroux 8 | # 9 | # Permission is hereby granted, free of charge, to any person obtaining a copy 10 | # of this software and associated documentation files (the "Software"), to deal 11 | # in the Software without restriction, including without limitation the rights 12 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 | # copies of the Software, and to permit persons to whom the Software is 14 | # furnished to do so, subject to the following conditions: 15 | # 16 | # The above copyright notice and this permission notice shall be included in all 17 | # copies or substantial portions of the Software. 18 | # 19 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 25 | # SOFTWARE. 26 | # 27 | # @author Julien Dupeyroux 28 | 29 | import numpy as np 30 | 31 | 32 | def temporal_contrast(spikes, threshold): 33 | # Based on algorithm provided in: 34 | # Sengupta et al. (2017) 35 | # Petro et al. (2020) 36 | signal = np.zeros(len(spikes)) 37 | for i in range(1, len(spikes)): 38 | if spikes[i] > 0: 39 | signal[i] = signal[i-1] + threshold 40 | elif spikes[i] < 0: 41 | signal[i] = signal[i-1] - threshold 42 | else: 43 | signal[i] = signal[i-1] 44 | return signal 45 | 46 | def step_forward(spikes, threshold, startpoint): 47 | # Based on algorithm provided in: 48 | # Petro et al. (2020) 49 | signal = np.zeros(len(spikes)) 50 | signal[0] = startpoint 51 | for i in range(1,len(spikes)): 52 | if spikes[i] > 0: 53 | signal[i] = signal[i-1] + threshold 54 | elif spikes[i] < 0: 55 | signal[i] = signal[i-1] -threshold 56 | else: 57 | signal[i] = signal[i-1] 58 | return signal 59 | 60 | def moving_window(spikes, threshold, startpoint): 61 | # Based on algorithm provided in: 62 | # Petro et al. (2020) 63 | signal = np.zeros(len(spikes)) 64 | signal[0] = startpoint 65 | for i in range(1,len(spikes)): 66 | if spikes[i] > 0: 67 | signal[i] = signal[i-1] + threshold 68 | elif spikes[i] < 0: 69 | signal[i] = signal[i-1] - threshold 70 | else: 71 | signal[i] = signal[i-1] 72 | return signal 73 | 74 | def ben_spike(spikes, fir, shift): 75 | # Based on algorithm provided in: 76 | # Petro et al. (2020) 77 | # Sengupta et al. (2017) 78 | # Schrauwen et al. (2003) 79 | signal = np.convolve(spikes, fir) 80 | signal = signal + shift*np.ones(len(signal)) 81 | signal = signal[0:(len(signal)-len(fir)+1)] 82 | return signal 83 | 84 | def grf_spike(spikes, min_input, max_input): 85 | shape = spikes.shape 86 | signal = np.zeros(shape[0]) 87 | for i in range(shape[0]): 88 | signal[i] = min_input + (2*np.argmax(spikes[i,:])-3)/2*(max_input - min_input)/(shape[1]-2) 89 | return signal -------------------------------------------------------------------------------- /ROS/spyke_coding_schemes/src/spyke_coding_schemes/EncodingSchemes.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python 2 | 3 | # This file is part of the SpikeCoding repository - MAVLab TU Delft 4 | # 5 | # MIT License 6 | # 7 | # Copyright (c) 2021 Julien Dupeyroux 8 | # 9 | # Permission is hereby granted, free of charge, to any person obtaining a copy 10 | # of this software and associated documentation files (the "Software"), to deal 11 | # in the Software without restriction, including without limitation the rights 12 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 | # copies of the Software, and to permit persons to whom the Software is 14 | # furnished to do so, subject to the following conditions: 15 | # 16 | # The above copyright notice and this permission notice shall be included in all 17 | # copies or substantial portions of the Software. 18 | # 19 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 25 | # SOFTWARE. 26 | # 27 | # @author Julien Dupeyroux 28 | 29 | import numpy as np 30 | from scipy.stats import norm 31 | 32 | 33 | def temporal_contrast(data, factor): 34 | # Based on algorithm provided in: 35 | # Sengupta et al. (2017) 36 | # Petro et al. (2020) 37 | diff = np.zeros(len(data)-1) 38 | spikes = np.zeros(len(data)) 39 | for i in range(len(data)-1): 40 | diff[i] = data[i+1] - data[i] 41 | threshold = np.mean(diff) + factor * np.std(diff) 42 | diff = np.insert(diff, 0, diff[1]) 43 | for i in range(len(data)): 44 | if diff[i] > threshold: 45 | spikes[i] = 1 46 | elif diff[i] < -threshold: 47 | spikes[i] = -1 48 | return spikes, threshold 49 | 50 | 51 | def step_forward(data, threshold): 52 | # Based on algorithm provided in: 53 | # Petro et al. (2020) 54 | startpoint = data[0] 55 | spikes = np.zeros(len(data)) 56 | base = startpoint 57 | for i in range(1,len(data)): 58 | if data[i] > base + threshold: 59 | spikes[i] = 1 60 | base = base + threshold 61 | elif data[i] < base - threshold: 62 | spikes[i] = -1 63 | base = base - threshold 64 | return spikes, startpoint 65 | 66 | 67 | def moving_window(data, threshold, window): 68 | # Based on algorithm provided in: 69 | # Petro et al. (2020) 70 | startpoint = data[0] 71 | spikes = np.zeros(len(data)) 72 | base = np.mean(data[0:window+1]) 73 | for i in range(window+1): 74 | if data[i] > base + threshold: 75 | spikes[i] = 1 76 | elif data[i] < base - threshold: 77 | spikes[i] = -1 78 | for i in range(window+2, len(data)): 79 | base = np.mean(data[(i-window-1):(i-1)]) 80 | if data[i] > base + threshold: 81 | spikes[i] = 1 82 | elif data[i] < base - threshold: 83 | spikes[i] = -1 84 | return spikes, startpoint 85 | 86 | 87 | def hough_spike(data, fir): 88 | # Based on algorithm provided in: 89 | # Schrauwen et al. (2003) 90 | spikes = np.zeros(len(data)) 91 | shift = min(data) 92 | data = data - shift*np.ones(len(data)) 93 | for i in range(len(data)): 94 | count = 0 95 | for j in range(len(fir)): 96 | if i+j < len(data): 97 | if data[i+j] >= fir[j]: 98 | count = count + 1 99 | if count == len(fir): 100 | spikes[i] = 1 101 | for j in range(len(fir)): 102 | if i+j < len(data): 103 | data[i+j] = data[i+j] - fir[j] 104 | return spikes, shift 105 | 106 | 107 | def modified_hough_spike(data, fir, threshold): 108 | # Based on algorithm provided in: 109 | # Schrauwen et al. (2003) 110 | spikes = np.zeros(len(data)) 111 | shift = min(data) 112 | data = data - shift*np.ones(len(data)) 113 | for i in range(len(data)): 114 | error = 0 115 | for j in range(len(fir)): 116 | if i+j < len(data): 117 | if data[i+j] < fir[j]: 118 | error = error + fir[j] - data[i+j] 119 | if error <= threshold: 120 | spikes[i] = 1 121 | for j in range(len(fir)): 122 | if i+j < len(data): 123 | data[i+j] = data[i+j] - fir[j] 124 | return spikes, shift 125 | 126 | 127 | def ben_spike(data, fir, threshold): 128 | # Based on algorithm provided in: 129 | # Petro et al. (2020) 130 | # Sengupta et al. (2017) 131 | # Schrauwen et al. (2003) 132 | spikes = np.zeros(len(data)) 133 | shift = min(data) 134 | data = data - shift*np.ones(len(data)) 135 | for i in range(len(data)-len(fir)+1): 136 | err1 = 0 137 | err2 = 0 138 | for j in range(len(fir)): 139 | err1 = err1 + abs(data[i+j] - fir[j]) 140 | err2 = err2 + abs(data[i+j-1]) 141 | if err1 <= err2*threshold: 142 | spikes[i] = 1 143 | for j in range(len(fir)): 144 | if i+j+1 < len(data): 145 | data[i+j+1] = data[i+j+1] - fir[j] 146 | return spikes, shift 147 | 148 | 149 | def grf_spike(data, m, min_input, max_input): 150 | # Adapted from algorithm provided in: 151 | # Bohté et al. (2002) 152 | # Modifications: definition of sigma, removal of beta constant, 153 | # and modified WTA process 154 | if np.isscalar(data): 155 | spikes = np.zeros(m) 156 | neuron_outputs = np.zeros(m) 157 | for i in range(m): 158 | mu = min_input + (2*i-3)/2*(max_input - min_input)/(m-2) 159 | sigma = (max_input - min_input)/(m-2) 160 | neuron_outputs[i] = norm.pdf(data, mu, sigma) 161 | spikes[np.argmax(neuron_outputs)] = 1 162 | else: 163 | spikes = np.zeros((len(data),m)) 164 | neuron_outputs = np.zeros(m) 165 | for j in range(len(data)): 166 | for i in range(m): 167 | mu = min_input + (2*i-3)/2*(max_input - min_input)/(m-2) 168 | sigma = (max_input - min_input)/(m-2) 169 | neuron_outputs[i] = norm.pdf(data[j], mu, sigma) 170 | spikes[j,np.argmax(neuron_outputs)] = 1 171 | return spikes 172 | -------------------------------------------------------------------------------- /ROS/spyke_coding_schemes/src/spyke_coding_schemes/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JuSquare/SpikeCoding/48e84b80035e1dfd1eebd32c347a23cc5d52338e/ROS/spyke_coding_schemes/src/spyke_coding_schemes/__init__.py -------------------------------------------------------------------------------- /ROS/spyke_coding_schemes/src/spyke_coding_schemes/__pycache__/DecodingSchemes.cpython-38.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JuSquare/SpikeCoding/48e84b80035e1dfd1eebd32c347a23cc5d52338e/ROS/spyke_coding_schemes/src/spyke_coding_schemes/__pycache__/DecodingSchemes.cpython-38.pyc -------------------------------------------------------------------------------- /ROS/spyke_coding_schemes/src/spyke_coding_schemes/__pycache__/EncodingSchemes.cpython-38.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JuSquare/SpikeCoding/48e84b80035e1dfd1eebd32c347a23cc5d52338e/ROS/spyke_coding_schemes/src/spyke_coding_schemes/__pycache__/EncodingSchemes.cpython-38.pyc -------------------------------------------------------------------------------- /ROS/spyke_msgs/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.0.2) 2 | project(spyke_msgs) 3 | 4 | find_package(catkin REQUIRED COMPONENTS 5 | message_generation 6 | std_msgs) 7 | 8 | FILE(GLOB messages_to_build RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}/msg" 9 | "${CMAKE_CURRENT_SOURCE_DIR}/msg/*.msg") 10 | 11 | add_message_files( 12 | FILES 13 | ${messages_to_build} 14 | ) 15 | 16 | generate_messages( 17 | DEPENDENCIES 18 | std_msgs 19 | ) 20 | 21 | catkin_package( 22 | CATKIN_DEPENDS message_runtime std_msgs 23 | ) 24 | 25 | include_directories( 26 | ${catkin_INCLUDE_DIRS} 27 | ) 28 | -------------------------------------------------------------------------------- /ROS/spyke_msgs/msg/spyke.msg: -------------------------------------------------------------------------------- 1 | # A spyke event 2 | int8 spike 3 | float32 start 4 | float32 min_input 5 | float32 max_input 6 | float32 threshold 7 | float32 input 8 | string scheme 9 | time timestamp -------------------------------------------------------------------------------- /ROS/spyke_msgs/msg/spyke_array.msg: -------------------------------------------------------------------------------- 1 | # A spyke event 2 | int8[] spike 3 | float32 start 4 | float32 min_input 5 | float32 max_input 6 | float32 threshold 7 | float32 input 8 | string scheme 9 | time timestamp -------------------------------------------------------------------------------- /ROS/spyke_msgs/package.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | spyke_msgs 4 | 0.0.0 5 | The spyke_msgs package 6 | Julien Dupeyroux 7 | MIT 8 | 9 | catkin 10 | std_msgs 11 | message_generation 12 | message_runtime 13 | std_msgs 14 | message_generation 15 | 16 | 17 | -------------------------------------------------------------------------------- /SpikeCodingMatlab/BenSpikeDecoding.m: -------------------------------------------------------------------------------- 1 | % This file is part of the SpikeCoding repository - MAVLab TU Delft 2 | % 3 | % MIT License 4 | % 5 | % Copyright (c) 2021 Julien Dupeyroux 6 | % 7 | % Permission is hereby granted, free of charge, to any person obtaining a copy 8 | % of this software and associated documentation files (the "Software"), to deal 9 | % in the Software without restriction, including without limitation the rights 10 | % to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | % copies of the Software, and to permit persons to whom the Software is 12 | % furnished to do so, subject to the following conditions: 13 | % 14 | % The above copyright notice and this permission notice shall be included in all 15 | % copies or substantial portions of the Software. 16 | % 17 | % THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | % IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | % FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | % AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | % LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | % OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | % SOFTWARE. 24 | % 25 | % @author Julien Dupeyroux 26 | 27 | function signal = BenSpikeDecoding(spikes, fir, shift) 28 | 29 | % Based on algorithm provided in: 30 | % Petro et al. (2020) 31 | % Sengupta et al. (2017) 32 | % Schrauwen et al. (2003) 33 | 34 | signal = conv(spikes,fir) + shift; 35 | signal = signal(1:end-length(fir)+1); 36 | 37 | end -------------------------------------------------------------------------------- /SpikeCodingMatlab/BenSpikeEncoding.m: -------------------------------------------------------------------------------- 1 | % This file is part of the SpikeCoding repository - MAVLab TU Delft 2 | % 3 | % MIT License 4 | % 5 | % Copyright (c) 2021 Julien Dupeyroux 6 | % 7 | % Permission is hereby granted, free of charge, to any person obtaining a copy 8 | % of this software and associated documentation files (the "Software"), to deal 9 | % in the Software without restriction, including without limitation the rights 10 | % to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | % copies of the Software, and to permit persons to whom the Software is 12 | % furnished to do so, subject to the following conditions: 13 | % 14 | % The above copyright notice and this permission notice shall be included in all 15 | % copies or substantial portions of the Software. 16 | % 17 | % THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | % IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | % FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | % AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | % LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | % OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | % SOFTWARE. 24 | % 25 | % @author Julien Dupeyroux 26 | 27 | function [spikes, shift] = BenSpikeEncoding(input, fir, threshold) 28 | 29 | % Based on algorithm provided in: 30 | % Petro et al. (2020) 31 | % Sengupta et al. (2017) 32 | % Schrauwen et al. (2003) 33 | 34 | L = length(input); 35 | F = length(fir); 36 | spikes = zeros(1,L); 37 | shift = min(input); 38 | input = input - shift; 39 | 40 | for i = 1:(L-F) 41 | err1 = 0; 42 | err2 = 0; 43 | for j = 1:F 44 | err1 = err1 + abs(input(i+j) - fir(j)); 45 | err2 = err2 + abs(input(i+j-1)); 46 | end 47 | if err1 <= err2*threshold 48 | spikes(i) = 1; 49 | for j = 1:F 50 | if i+j+1 <= L 51 | input(i+j+1) = input(i+j+1) - fir(j); 52 | end 53 | end 54 | end 55 | end 56 | 57 | end -------------------------------------------------------------------------------- /SpikeCodingMatlab/Benchmark.m: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JuSquare/SpikeCoding/48e84b80035e1dfd1eebd32c347a23cc5d52338e/SpikeCodingMatlab/Benchmark.m -------------------------------------------------------------------------------- /SpikeCodingMatlab/BohteDecoding.m: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JuSquare/SpikeCoding/48e84b80035e1dfd1eebd32c347a23cc5d52338e/SpikeCodingMatlab/BohteDecoding.m -------------------------------------------------------------------------------- /SpikeCodingMatlab/BohteEncoding.m: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JuSquare/SpikeCoding/48e84b80035e1dfd1eebd32c347a23cc5d52338e/SpikeCodingMatlab/BohteEncoding.m -------------------------------------------------------------------------------- /SpikeCodingMatlab/GaussianReceptFieldsDecoding.m: -------------------------------------------------------------------------------- 1 | % This file is part of the SpikeCoding repository - MAVLab TU Delft 2 | % 3 | % MIT License 4 | % 5 | % Copyright (c) 2021 Julien Dupeyroux 6 | % 7 | % Permission is hereby granted, free of charge, to any person obtaining a copy 8 | % of this software and associated documentation files (the "Software"), to deal 9 | % in the Software without restriction, including without limitation the rights 10 | % to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | % copies of the Software, and to permit persons to whom the Software is 12 | % furnished to do so, subject to the following conditions: 13 | % 14 | % The above copyright notice and this permission notice shall be included in all 15 | % copies or substantial portions of the Software. 16 | % 17 | % THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | % IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | % FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | % AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | % LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | % OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | % SOFTWARE. 24 | % 25 | % @author Julien Dupeyroux 26 | 27 | function signal = GaussianReceptFieldsDecoding(spikes,min_input,max_input) 28 | 29 | L = size(spikes,1); 30 | m = size(spikes,2); 31 | signal = zeros(1,L); 32 | for i = 1:L 33 | [~,index_neuron] = max(spikes(i,:)); 34 | signal(1,i) = min_input + (2*index_neuron-3)/2*(max_input - min_input)/(m-2); 35 | end 36 | 37 | 38 | end -------------------------------------------------------------------------------- /SpikeCodingMatlab/GaussianReceptFieldsEncoding.m: -------------------------------------------------------------------------------- 1 | % This file is part of the SpikeCoding repository - MAVLab TU Delft 2 | % 3 | % MIT License 4 | % 5 | % Copyright (c) 2021 Julien Dupeyroux 6 | % 7 | % Permission is hereby granted, free of charge, to any person obtaining a copy 8 | % of this software and associated documentation files (the "Software"), to deal 9 | % in the Software without restriction, including without limitation the rights 10 | % to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | % copies of the Software, and to permit persons to whom the Software is 12 | % furnished to do so, subject to the following conditions: 13 | % 14 | % The above copyright notice and this permission notice shall be included in all 15 | % copies or substantial portions of the Software. 16 | % 17 | % THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | % IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | % FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | % AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | % LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | % OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | % SOFTWARE. 24 | % 25 | % @author Julien Dupeyroux 26 | 27 | function [spikes,min_input,max_input] = GaussianReceptFieldsEncoding(input,m) 28 | 29 | L = length(input); 30 | 31 | spikes = zeros(L,m); 32 | neuron_outputs = zeros(1,m); 33 | 34 | min_input = min(input); 35 | max_input = max(input); 36 | 37 | for j = 1:L 38 | for i = 1:m 39 | mu = min_input + (2*i-3)/2*(max_input - min_input)/(m-2); 40 | sigma = (max_input - min_input)/(m-2); 41 | neuron_outputs(i) = normpdf(input(j), mu, sigma)/normpdf(mu, mu, sigma); 42 | end 43 | [~,spikingNeuron] = max(neuron_outputs); 44 | spikes(j,spikingNeuron) = 1; 45 | end 46 | 47 | 48 | end -------------------------------------------------------------------------------- /SpikeCodingMatlab/HoughSpikeEncoding.m: -------------------------------------------------------------------------------- 1 | % This file is part of the SpikeCoding repository - MAVLab TU Delft 2 | % 3 | % MIT License 4 | % 5 | % Copyright (c) 2021 Julien Dupeyroux 6 | % 7 | % Permission is hereby granted, free of charge, to any person obtaining a copy 8 | % of this software and associated documentation files (the "Software"), to deal 9 | % in the Software without restriction, including without limitation the rights 10 | % to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | % copies of the Software, and to permit persons to whom the Software is 12 | % furnished to do so, subject to the following conditions: 13 | % 14 | % The above copyright notice and this permission notice shall be included in all 15 | % copies or substantial portions of the Software. 16 | % 17 | % THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | % IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | % FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | % AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | % LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | % OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | % SOFTWARE. 24 | % 25 | % @author Julien Dupeyroux 26 | 27 | function [spikes, shift] = HoughSpikeEncoding(input, fir) 28 | 29 | % Based on algorithm provided in: 30 | % Schrauwen et al. (2003) 31 | 32 | L = length(input); 33 | F = length(fir); 34 | spikes = zeros(1,L); 35 | shift = min(input); 36 | input = input - shift; 37 | for i = 1:L 38 | count = 0; 39 | for j = 1:F 40 | if i+j-1 < L 41 | if input(i+j-1) >= fir(j) 42 | count = count + 1; 43 | end 44 | end 45 | end 46 | if count == F 47 | spikes(i) = 1; 48 | for j = 1:F 49 | if i+j-1 < L 50 | input(i+j-1) = input(i+j-1) - fir(j); 51 | end 52 | end 53 | end 54 | end 55 | 56 | end -------------------------------------------------------------------------------- /SpikeCodingMatlab/HoughSpikeModifiedEncoding.m: -------------------------------------------------------------------------------- 1 | % This file is part of the SpikeCoding repository - MAVLab TU Delft 2 | % 3 | % MIT License 4 | % 5 | % Copyright (c) 2021 Julien Dupeyroux 6 | % 7 | % Permission is hereby granted, free of charge, to any person obtaining a copy 8 | % of this software and associated documentation files (the "Software"), to deal 9 | % in the Software without restriction, including without limitation the rights 10 | % to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | % copies of the Software, and to permit persons to whom the Software is 12 | % furnished to do so, subject to the following conditions: 13 | % 14 | % The above copyright notice and this permission notice shall be included in all 15 | % copies or substantial portions of the Software. 16 | % 17 | % THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | % IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | % FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | % AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | % LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | % OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | % SOFTWARE. 24 | % 25 | % @author Julien Dupeyroux 26 | 27 | function [spikes, shift] = HoughSpikeModifiedEncoding(input, fir, threshold) 28 | 29 | % Based on algorithm provided in: 30 | % Schrauwen et al. (2003) 31 | 32 | L = length(input); 33 | F = length(fir); 34 | spikes = zeros(1,L); 35 | shift = min(input); 36 | input = input - shift; 37 | for i = 1:L 38 | error = 0; 39 | for j = 1:F 40 | if i+j-1 < L 41 | if input(i+j-1) < fir(j) 42 | error = error + fir(j) - input(i+j-1); 43 | end 44 | end 45 | end 46 | if error <= threshold 47 | spikes(i) = 1; 48 | for j = 1:F 49 | if i+j-1 < L 50 | input(i+j-1) = input(i+j-1) - fir(j); 51 | end 52 | end 53 | end 54 | end 55 | 56 | end -------------------------------------------------------------------------------- /SpikeCodingMatlab/ImageCoding.m: -------------------------------------------------------------------------------- 1 | % This file is part of the SpikeCoding repository - MAVLab TU Delft 2 | % 3 | % MIT License 4 | % 5 | % Copyright (c) 2021 Julien Dupeyroux 6 | % 7 | % Permission is hereby granted, free of charge, to any person obtaining a copy 8 | % of this software and associated documentation files (the "Software"), to deal 9 | % in the Software without restriction, including without limitation the rights 10 | % to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | % copies of the Software, and to permit persons to whom the Software is 12 | % furnished to do so, subject to the following conditions: 13 | % 14 | % The above copyright notice and this permission notice shall be included in all 15 | % copies or substantial portions of the Software. 16 | % 17 | % THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | % IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | % FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | % AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | % LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | % OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | % SOFTWARE. 24 | % 25 | % @author Julien Dupeyroux 26 | 27 | %% Load data 28 | 29 | filename = 'visual_data/3/video.avi'; 30 | myVid = VideoReader(filename); 31 | T = 5; 32 | inputData = zeros(myVid.Height, myVid.Width, T); 33 | 34 | for i=1:T 35 | frame = rgb2gray(readFrame(myVid)); 36 | inputData(:,:,i) = frame; 37 | end 38 | 39 | Time = 0:(1/myVid.FrameRate):(T-1)/myVid.FrameRate; 40 | 41 | %% Plots 42 | 43 | Pixel = [990, 190]; 44 | deltaPix = 25; 45 | 46 | Signal = squeeze(inputData(Pixel(1),Pixel(2),:)); 47 | 48 | % Plot one image for example 49 | figure() 50 | subplot(5,1,1:4) 51 | hold on; 52 | imagesc(inputData(:,:,T)); 53 | rectangle('Position',[Pixel(1)-deltaPix Pixel(2)-deltaPix deltaPix*2 deltaPix*2], 'linewidth', 1.5); 54 | plot(Pixel(1), Pixel(2), 'red+', 'linewidth', 1.5); 55 | hold off; 56 | box on; 57 | axis([0 myVid.Width 0 myVid.Height]) 58 | colorbar 59 | 60 | % Plot variations of a pixel 61 | subplot(5,1,5) 62 | plot(Time, Signal); 63 | box on; 64 | axis([0 Time(end) min(Signal) max(Signal)]) 65 | xlabel('Time [s]'); 66 | ylabel('Gray level'); 67 | 68 | %% Test Step-Forward Temporal Contrast algorighm on one pixel 69 | 70 | % Get the signal 71 | Pixel = [990, 190]; 72 | Signal = squeeze(inputData(Pixel(1),Pixel(2),:)); 73 | 74 | % Step forward params 75 | threshold_SF = 3; 76 | 77 | % Step forward coding 78 | [spikes_SF, startpoint] = StepForwardEncoding(Signal, threshold_SF); 79 | signal_SF = StepForwardDecoding(spikes_SF, threshold_SF, startpoint); 80 | 81 | figure() 82 | subplot(4,1,1:3) 83 | hold on; 84 | plot(Time, signal_SF, 'red') 85 | plot(Time, Signal, 'blue') 86 | hold off; 87 | title('Step Forward Algorithm SF'); 88 | box on; 89 | subplot(4,1,4) 90 | stem(Time,spikes_SF) 91 | box on; 92 | 93 | %% Applying SF algorithm to the whole image 94 | 95 | spikes = zeros(myVid.Height, myVid.Width, T); 96 | reconstruct_images = zeros(myVid.Height, myVid.Width, T); 97 | threshold_SF = 20; 98 | 99 | for i = 1:myVid.Height 100 | for j = 1:myVid.Width 101 | [spikes(i,j,:), startpoint] = StepForwardEncoding(squeeze(inputData(i,j,:)), threshold_SF); 102 | reconstruct_images(i,j,:) = StepForwardDecoding(spikes(i,j,:), threshold_SF, startpoint); 103 | end 104 | end 105 | 106 | %% Plots 107 | 108 | figure('Position', [10 10 2400 600]) 109 | subplot(1,3,1) 110 | imshow(inputData(:,:,T),[]); 111 | title('Input'); 112 | axis equal; 113 | axis([0 myVid.Width 0 myVid.Height]) 114 | subplot(1,3,2) 115 | imshow(spikePlot(spikes(:,:,T))); 116 | title('Spikes'); 117 | subplot(1,3,3) 118 | imshow(reconstruct_images(:,:,T),[]); 119 | title('Reconstruction'); 120 | axis equal; 121 | axis([0 myVid.Width 0 myVid.Height]) 122 | 123 | -------------------------------------------------------------------------------- /SpikeCodingMatlab/MovingWindowDecoding.m: -------------------------------------------------------------------------------- 1 | % This file is part of the SpikeCoding repository - MAVLab TU Delft 2 | % 3 | % MIT License 4 | % 5 | % Copyright (c) 2021 Julien Dupeyroux 6 | % 7 | % Permission is hereby granted, free of charge, to any person obtaining a copy 8 | % of this software and associated documentation files (the "Software"), to deal 9 | % in the Software without restriction, including without limitation the rights 10 | % to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | % copies of the Software, and to permit persons to whom the Software is 12 | % furnished to do so, subject to the following conditions: 13 | % 14 | % The above copyright notice and this permission notice shall be included in all 15 | % copies or substantial portions of the Software. 16 | % 17 | % THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | % IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | % FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | % AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | % LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | % OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | % SOFTWARE. 24 | % 25 | % @author Julien Dupeyroux 26 | 27 | function signal = MovingWindowDecoding(spikes, threshold, startpoint) 28 | 29 | % Based on algorithm provided in: 30 | % Petro et al. (2020) 31 | 32 | L = length(spikes); 33 | signal = zeros(1,L); 34 | signal(1) = startpoint; 35 | 36 | for i = 2:L 37 | if spikes(i) > 0 38 | signal(i) = signal(i-1) + threshold; 39 | elseif spikes(i) < 0 40 | signal(i) = signal(i-1) - threshold; 41 | else 42 | signal(i) = signal(i-1); 43 | end 44 | end 45 | 46 | end -------------------------------------------------------------------------------- /SpikeCodingMatlab/MovingWindowEncoding.m: -------------------------------------------------------------------------------- 1 | % This file is part of the SpikeCoding repository - MAVLab TU Delft 2 | % 3 | % MIT License 4 | % 5 | % Copyright (c) 2021 Julien Dupeyroux 6 | % 7 | % Permission is hereby granted, free of charge, to any person obtaining a copy 8 | % of this software and associated documentation files (the "Software"), to deal 9 | % in the Software without restriction, including without limitation the rights 10 | % to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | % copies of the Software, and to permit persons to whom the Software is 12 | % furnished to do so, subject to the following conditions: 13 | % 14 | % The above copyright notice and this permission notice shall be included in all 15 | % copies or substantial portions of the Software. 16 | % 17 | % THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | % IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | % FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | % AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | % LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | % OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | % SOFTWARE. 24 | % 25 | % @author Julien Dupeyroux 26 | 27 | function [spikes, startpoint] = MovingWindowEncoding(input, threshold, window) 28 | 29 | % Based on algorithm provided in: 30 | % Petro et al. (2020) 31 | 32 | startpoint = input(1); 33 | L = length(input); 34 | spikes = zeros(1,L); 35 | base = mean(input(1:(window+1))); 36 | 37 | for i = 1:(window+1) 38 | if input(i) > base + threshold 39 | spikes(i) = 1; 40 | elseif input(i) < base - threshold 41 | spikes(i) = -1; 42 | end 43 | end 44 | 45 | for i = (window+2):L 46 | base = mean(input((i-window-1):(i-1))); 47 | if input(i) > base + threshold 48 | spikes(i) = 1; 49 | elseif input(i) < base - threshold 50 | spikes(i) = -1; 51 | end 52 | end 53 | 54 | end -------------------------------------------------------------------------------- /SpikeCodingMatlab/RMSE.m: -------------------------------------------------------------------------------- 1 | % This file is part of the SpikeCoding repository - MAVLab TU Delft 2 | % 3 | % MIT License 4 | % 5 | % Copyright (c) 2021 Julien Dupeyroux 6 | % 7 | % Permission is hereby granted, free of charge, to any person obtaining a copy 8 | % of this software and associated documentation files (the "Software"), to deal 9 | % in the Software without restriction, including without limitation the rights 10 | % to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | % copies of the Software, and to permit persons to whom the Software is 12 | % furnished to do so, subject to the following conditions: 13 | % 14 | % The above copyright notice and this permission notice shall be included in all 15 | % copies or substantial portions of the Software. 16 | % 17 | % THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | % IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | % FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | % AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | % LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | % OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | % SOFTWARE. 24 | % 25 | % @author Julien Dupeyroux 26 | 27 | function rmse = RMSE(data, estimate) 28 | 29 | rmse = sqrt( sum( (data(:)-estimate(:)).^2) / numel(data) ); 30 | 31 | end -------------------------------------------------------------------------------- /SpikeCodingMatlab/SpikeCoding.m: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JuSquare/SpikeCoding/48e84b80035e1dfd1eebd32c347a23cc5d52338e/SpikeCodingMatlab/SpikeCoding.m -------------------------------------------------------------------------------- /SpikeCodingMatlab/StepForwardDecoding.m: -------------------------------------------------------------------------------- 1 | % This file is part of the SpikeCoding repository - MAVLab TU Delft 2 | % 3 | % MIT License 4 | % 5 | % Copyright (c) 2021 Julien Dupeyroux 6 | % 7 | % Permission is hereby granted, free of charge, to any person obtaining a copy 8 | % of this software and associated documentation files (the "Software"), to deal 9 | % in the Software without restriction, including without limitation the rights 10 | % to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | % copies of the Software, and to permit persons to whom the Software is 12 | % furnished to do so, subject to the following conditions: 13 | % 14 | % The above copyright notice and this permission notice shall be included in all 15 | % copies or substantial portions of the Software. 16 | % 17 | % THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | % IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | % FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | % AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | % LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | % OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | % SOFTWARE. 24 | % 25 | % @author Julien Dupeyroux 26 | 27 | function signal = StepForwardDecoding(spikes, threshold, startpoint) 28 | 29 | % Based on algorithm provided in: 30 | % Petro et al. (2020) 31 | 32 | L = length(spikes); 33 | signal = zeros(1,L); 34 | signal(1) = startpoint; 35 | 36 | for i = 2:L 37 | if spikes(i) > 0 38 | signal(i) = signal(i-1) + threshold; 39 | elseif spikes(i) < 0 40 | signal(i) = signal(i-1) - threshold; 41 | else 42 | signal(i) = signal(i-1); 43 | end 44 | end 45 | 46 | end -------------------------------------------------------------------------------- /SpikeCodingMatlab/StepForwardEncoding.m: -------------------------------------------------------------------------------- 1 | % This file is part of the SpikeCoding repository - MAVLab TU Delft 2 | % 3 | % MIT License 4 | % 5 | % Copyright (c) 2021 Julien Dupeyroux 6 | % 7 | % Permission is hereby granted, free of charge, to any person obtaining a copy 8 | % of this software and associated documentation files (the "Software"), to deal 9 | % in the Software without restriction, including without limitation the rights 10 | % to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | % copies of the Software, and to permit persons to whom the Software is 12 | % furnished to do so, subject to the following conditions: 13 | % 14 | % The above copyright notice and this permission notice shall be included in all 15 | % copies or substantial portions of the Software. 16 | % 17 | % THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | % IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | % FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | % AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | % LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | % OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | % SOFTWARE. 24 | % 25 | % @author Julien Dupeyroux 26 | 27 | function [spikes, startpoint] = StepForwardEncoding(input, threshold) 28 | 29 | % Based on algorithm provided in: 30 | % Petro et al. (2020) 31 | 32 | startpoint = input(1); 33 | L = length(input); 34 | spikes = zeros(1,L); 35 | base = startpoint; 36 | 37 | for i = 2:L 38 | if input(i) > base + threshold 39 | spikes(i) = 1; 40 | base = base + threshold; 41 | elseif input(i) < base - threshold 42 | spikes(i) = -1; 43 | base = base - threshold; 44 | end 45 | end 46 | 47 | end -------------------------------------------------------------------------------- /SpikeCodingMatlab/TemporalContrastDecode.m: -------------------------------------------------------------------------------- 1 | % This file is part of the SpikeCoding repository - MAVLab TU Delft 2 | % 3 | % MIT License 4 | % 5 | % Copyright (c) 2021 Julien Dupeyroux 6 | % 7 | % Permission is hereby granted, free of charge, to any person obtaining a copy 8 | % of this software and associated documentation files (the "Software"), to deal 9 | % in the Software without restriction, including without limitation the rights 10 | % to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | % copies of the Software, and to permit persons to whom the Software is 12 | % furnished to do so, subject to the following conditions: 13 | % 14 | % The above copyright notice and this permission notice shall be included in all 15 | % copies or substantial portions of the Software. 16 | % 17 | % THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | % IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | % FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | % AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | % LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | % OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | % SOFTWARE. 24 | % 25 | % @author Julien Dupeyroux 26 | 27 | function signal = TemporalContrastDecode(spikes, threshold) 28 | 29 | % Based on algorithm provided in: 30 | % Sengupta et al. (2017) 31 | % Petro et al. (2020) 32 | 33 | L = length(spikes); 34 | signal = zeros(1,L); 35 | for i = 2:L 36 | if spikes(i) > 0 37 | signal(i) = signal(i-1) + threshold; 38 | elseif spikes(i) < 0 39 | signal(i) = signal(i-1) - threshold; 40 | else 41 | signal(i) = signal(i-1); 42 | end 43 | end 44 | 45 | end 46 | 47 | -------------------------------------------------------------------------------- /SpikeCodingMatlab/TemporalContrastEncode.m: -------------------------------------------------------------------------------- 1 | % This file is part of the SpikeCoding repository - MAVLab TU Delft 2 | % 3 | % MIT License 4 | % 5 | % Copyright (c) 2021 Julien Dupeyroux 6 | % 7 | % Permission is hereby granted, free of charge, to any person obtaining a copy 8 | % of this software and associated documentation files (the "Software"), to deal 9 | % in the Software without restriction, including without limitation the rights 10 | % to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | % copies of the Software, and to permit persons to whom the Software is 12 | % furnished to do so, subject to the following conditions: 13 | % 14 | % The above copyright notice and this permission notice shall be included in all 15 | % copies or substantial portions of the Software. 16 | % 17 | % THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | % IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | % FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | % AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | % LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | % OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | % SOFTWARE. 24 | % 25 | % @author Julien Dupeyroux 26 | 27 | function [spikes, threshold] = TemporalContrastEncode(input, factor) 28 | 29 | % Based on algorithm provided in: 30 | % Sengupta et al. (2017) 31 | % Petro et al. (2020) 32 | 33 | L = length(input); 34 | diff = zeros(1,L-1); 35 | for i = 1:L-1 36 | diff(i) = input(i+1) - input(i); 37 | end 38 | 39 | threshold = mean(diff) + factor*std(diff); 40 | diff = [diff(1), diff]; 41 | 42 | spikes = zeros(1, L); 43 | for i = 1:L 44 | if diff(i) > threshold 45 | spikes(i) = 1; 46 | elseif diff(i) < -threshold 47 | spikes(i) = -1; 48 | end 49 | end 50 | 51 | end 52 | 53 | -------------------------------------------------------------------------------- /SpikeCodingMatlab/benchmark_rmse_case_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JuSquare/SpikeCoding/48e84b80035e1dfd1eebd32c347a23cc5d52338e/SpikeCodingMatlab/benchmark_rmse_case_0.png -------------------------------------------------------------------------------- /SpikeCodingMatlab/benchmark_rmse_case_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JuSquare/SpikeCoding/48e84b80035e1dfd1eebd32c347a23cc5d52338e/SpikeCodingMatlab/benchmark_rmse_case_1.png -------------------------------------------------------------------------------- /SpikeCodingMatlab/benchmark_rmse_case_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JuSquare/SpikeCoding/48e84b80035e1dfd1eebd32c347a23cc5d52338e/SpikeCodingMatlab/benchmark_rmse_case_2.png -------------------------------------------------------------------------------- /SpikeCodingMatlab/benchmark_rmse_case_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JuSquare/SpikeCoding/48e84b80035e1dfd1eebd32c347a23cc5d52338e/SpikeCodingMatlab/benchmark_rmse_case_3.png -------------------------------------------------------------------------------- /SpikeCodingMatlab/benchmark_rmse_case_4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JuSquare/SpikeCoding/48e84b80035e1dfd1eebd32c347a23cc5d52338e/SpikeCodingMatlab/benchmark_rmse_case_4.png -------------------------------------------------------------------------------- /SpikeCodingMatlab/benchmark_spike_efficiency_case_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JuSquare/SpikeCoding/48e84b80035e1dfd1eebd32c347a23cc5d52338e/SpikeCodingMatlab/benchmark_spike_efficiency_case_0.png -------------------------------------------------------------------------------- /SpikeCodingMatlab/benchmark_spike_efficiency_case_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JuSquare/SpikeCoding/48e84b80035e1dfd1eebd32c347a23cc5d52338e/SpikeCodingMatlab/benchmark_spike_efficiency_case_1.png -------------------------------------------------------------------------------- /SpikeCodingMatlab/benchmark_spike_efficiency_case_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JuSquare/SpikeCoding/48e84b80035e1dfd1eebd32c347a23cc5d52338e/SpikeCodingMatlab/benchmark_spike_efficiency_case_2.png -------------------------------------------------------------------------------- /SpikeCodingMatlab/benchmark_spike_efficiency_case_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JuSquare/SpikeCoding/48e84b80035e1dfd1eebd32c347a23cc5d52338e/SpikeCodingMatlab/benchmark_spike_efficiency_case_3.png -------------------------------------------------------------------------------- /SpikeCodingMatlab/benchmark_spike_efficiency_case_4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JuSquare/SpikeCoding/48e84b80035e1dfd1eebd32c347a23cc5d52338e/SpikeCodingMatlab/benchmark_spike_efficiency_case_4.png -------------------------------------------------------------------------------- /SpikeCodingMatlab/benchmark_tests_plot_GRF_case0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JuSquare/SpikeCoding/48e84b80035e1dfd1eebd32c347a23cc5d52338e/SpikeCodingMatlab/benchmark_tests_plot_GRF_case0.png -------------------------------------------------------------------------------- /SpikeCodingMatlab/benchmark_tests_plot_GRF_case1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JuSquare/SpikeCoding/48e84b80035e1dfd1eebd32c347a23cc5d52338e/SpikeCodingMatlab/benchmark_tests_plot_GRF_case1.png -------------------------------------------------------------------------------- /SpikeCodingMatlab/benchmark_tests_plot_GRF_case2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JuSquare/SpikeCoding/48e84b80035e1dfd1eebd32c347a23cc5d52338e/SpikeCodingMatlab/benchmark_tests_plot_GRF_case2.png -------------------------------------------------------------------------------- /SpikeCodingMatlab/benchmark_tests_plot_GRF_case3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JuSquare/SpikeCoding/48e84b80035e1dfd1eebd32c347a23cc5d52338e/SpikeCodingMatlab/benchmark_tests_plot_GRF_case3.png -------------------------------------------------------------------------------- /SpikeCodingMatlab/benchmark_tests_plot_GRF_case4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JuSquare/SpikeCoding/48e84b80035e1dfd1eebd32c347a23cc5d52338e/SpikeCodingMatlab/benchmark_tests_plot_GRF_case4.png -------------------------------------------------------------------------------- /SpikeCodingMatlab/benchmark_tests_plot_case0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JuSquare/SpikeCoding/48e84b80035e1dfd1eebd32c347a23cc5d52338e/SpikeCodingMatlab/benchmark_tests_plot_case0.png -------------------------------------------------------------------------------- /SpikeCodingMatlab/benchmark_tests_plot_case1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JuSquare/SpikeCoding/48e84b80035e1dfd1eebd32c347a23cc5d52338e/SpikeCodingMatlab/benchmark_tests_plot_case1.png -------------------------------------------------------------------------------- /SpikeCodingMatlab/benchmark_tests_plot_case2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JuSquare/SpikeCoding/48e84b80035e1dfd1eebd32c347a23cc5d52338e/SpikeCodingMatlab/benchmark_tests_plot_case2.png -------------------------------------------------------------------------------- /SpikeCodingMatlab/benchmark_tests_plot_case3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JuSquare/SpikeCoding/48e84b80035e1dfd1eebd32c347a23cc5d52338e/SpikeCodingMatlab/benchmark_tests_plot_case3.png -------------------------------------------------------------------------------- /SpikeCodingMatlab/benchmark_tests_plot_case4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JuSquare/SpikeCoding/48e84b80035e1dfd1eebd32c347a23cc5d52338e/SpikeCodingMatlab/benchmark_tests_plot_case4.png -------------------------------------------------------------------------------- /SpikeCodingMatlab/image_sf_threshold_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JuSquare/SpikeCoding/48e84b80035e1dfd1eebd32c347a23cc5d52338e/SpikeCodingMatlab/image_sf_threshold_1.png -------------------------------------------------------------------------------- /SpikeCodingMatlab/image_sf_threshold_10.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JuSquare/SpikeCoding/48e84b80035e1dfd1eebd32c347a23cc5d52338e/SpikeCodingMatlab/image_sf_threshold_10.png -------------------------------------------------------------------------------- /SpikeCodingMatlab/image_sf_threshold_20.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JuSquare/SpikeCoding/48e84b80035e1dfd1eebd32c347a23cc5d52338e/SpikeCodingMatlab/image_sf_threshold_20.png -------------------------------------------------------------------------------- /SpikeCodingMatlab/image_sf_threshold_5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JuSquare/SpikeCoding/48e84b80035e1dfd1eebd32c347a23cc5d52338e/SpikeCodingMatlab/image_sf_threshold_5.png -------------------------------------------------------------------------------- /SpikeCodingMatlab/spikePlot.m: -------------------------------------------------------------------------------- 1 | function spikes_im = spikePlot(spikes) 2 | 3 | A = size(spikes); 4 | spikes_im = zeros(A(1), A(2), 3); 5 | for i = 1:A(1) 6 | for j = 1:A(2) 7 | if spikes(i,j,1) > 0 8 | spikes_im(i,j,3) = 255; 9 | elseif spikes(i,j,1) < 0 10 | spikes_im(i,j,1) = 255; 11 | end 12 | end 13 | end 14 | 15 | end -------------------------------------------------------------------------------- /SpikeCodingMatlab/test-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JuSquare/SpikeCoding/48e84b80035e1dfd1eebd32c347a23cc5d52338e/SpikeCodingMatlab/test-1.png -------------------------------------------------------------------------------- /SpikeCodingMatlab/test-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JuSquare/SpikeCoding/48e84b80035e1dfd1eebd32c347a23cc5d52338e/SpikeCodingMatlab/test-2.png -------------------------------------------------------------------------------- /SpikeCodingMatlab/test-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JuSquare/SpikeCoding/48e84b80035e1dfd1eebd32c347a23cc5d52338e/SpikeCodingMatlab/test-3.png -------------------------------------------------------------------------------- /SpikeCodingPython/Bags/gaussian_fields.bag: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JuSquare/SpikeCoding/48e84b80035e1dfd1eebd32c347a23cc5d52338e/SpikeCodingPython/Bags/gaussian_fields.bag -------------------------------------------------------------------------------- /SpikeCodingPython/Bags/moving_window.bag: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JuSquare/SpikeCoding/48e84b80035e1dfd1eebd32c347a23cc5d52338e/SpikeCodingPython/Bags/moving_window.bag -------------------------------------------------------------------------------- /SpikeCodingPython/Bags/step_forward.bag: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JuSquare/SpikeCoding/48e84b80035e1dfd1eebd32c347a23cc5d52338e/SpikeCodingPython/Bags/step_forward.bag -------------------------------------------------------------------------------- /SpikeCodingPython/Bags/temporal_contrast.bag: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JuSquare/SpikeCoding/48e84b80035e1dfd1eebd32c347a23cc5d52338e/SpikeCodingPython/Bags/temporal_contrast.bag -------------------------------------------------------------------------------- /SpikeCodingPython/DecodingSchemes.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python 2 | 3 | # This file is part of the SpikeCoding repository - MAVLab TU Delft 4 | # 5 | # MIT License 6 | # 7 | # Copyright (c) 2021 Julien Dupeyroux 8 | # 9 | # Permission is hereby granted, free of charge, to any person obtaining a copy 10 | # of this software and associated documentation files (the "Software"), to deal 11 | # in the Software without restriction, including without limitation the rights 12 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 | # copies of the Software, and to permit persons to whom the Software is 14 | # furnished to do so, subject to the following conditions: 15 | # 16 | # The above copyright notice and this permission notice shall be included in all 17 | # copies or substantial portions of the Software. 18 | # 19 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 25 | # SOFTWARE. 26 | # 27 | # @author Julien Dupeyroux, Stein Stroobants 28 | 29 | import numpy as np 30 | 31 | 32 | def temporal_contrast(spikes, threshold): 33 | # Based on algorithm provided in: 34 | # Sengupta et al. (2017) 35 | # Petro et al. (2020) 36 | signal = np.zeros(len(spikes)) 37 | for i in range(1, len(spikes)): 38 | if spikes[i] > 0: 39 | signal[i] = signal[i-1] + threshold 40 | elif spikes[i] < 0: 41 | signal[i] = signal[i-1] - threshold 42 | else: 43 | signal[i] = signal[i-1] 44 | return signal 45 | 46 | def step_forward(spikes, threshold, startpoint): 47 | # Based on algorithm provided in: 48 | # Petro et al. (2020) 49 | signal = np.zeros(len(spikes)) 50 | signal[0] = startpoint 51 | for i in range(1,len(spikes)): 52 | if spikes[i] > 0: 53 | signal[i] = signal[i-1] + threshold 54 | elif spikes[i] < 0: 55 | signal[i] = signal[i-1] -threshold 56 | else: 57 | signal[i] = signal[i-1] 58 | return signal 59 | 60 | def moving_window(spikes, threshold, startpoint): 61 | # Based on algorithm provided in: 62 | # Petro et al. (2020) 63 | signal = np.zeros(len(spikes)) 64 | signal[0] = startpoint 65 | for i in range(1,len(spikes)): 66 | if spikes[i] > 0: 67 | signal[i] = signal[i-1] + threshold 68 | elif spikes[i] < 0: 69 | signal[i] = signal[i-1] - threshold 70 | else: 71 | signal[i] = signal[i-1] 72 | return signal 73 | 74 | def ben_spike(spikes, fir, shift): 75 | # Based on algorithm provided in: 76 | # Petro et al. (2020) 77 | # Sengupta et al. (2017) 78 | # Schrauwen et al. (2003) 79 | signal = np.convolve(spikes, fir) 80 | signal = signal + shift*np.ones(len(signal)) 81 | signal = signal[0:(len(signal)-len(fir)+1)] 82 | return signal 83 | 84 | def grf_spike(spikes, min_input, max_input): 85 | shape = spikes.shape 86 | signal = np.zeros(shape[0]) 87 | for i in range(shape[0]): 88 | signal[i] = min_input + (2*(np.argmax(spikes[i,:]) + 1)-3)/2*(max_input - min_input)/(shape[1]-2) 89 | return signal 90 | 91 | def one_hot_place_spike(spikes, min_input, max_input): 92 | shape = spikes.shape 93 | signal = np.zeros(shape[0]) 94 | for i in range(shape[0]): 95 | signal[i] = min_input + (2*(np.argmax(spikes[i,:]) + 1)-3)/2*(max_input - min_input)/(shape[1]-2) 96 | return signal 97 | 98 | def grf_spike_with_internal_timesteps(spikes, n_timesteps, min_input, max_input): 99 | shape = spikes.shape 100 | spikes = spikes.reshape((int(shape[0]/n_timesteps), n_timesteps, shape[1])) 101 | signal = np.zeros(len(spikes)) 102 | mu = np.zeros(shape[1]) 103 | 104 | for i in range(shape[1]): 105 | mu[i] = min_input + (2*(i + 1)-3)/2*(max_input - min_input)/(shape[1]-2) 106 | 107 | for i in range(len(spikes)): 108 | spike_times = np.zeros(shape[1]) 109 | for j in range(n_timesteps): 110 | for spike_idx in spikes[i, j, :].nonzero(): 111 | spike_times[spike_idx] = n_timesteps - j 112 | 113 | weight_center = np.sum(mu*spike_times)/np.sum(spike_times) 114 | signal[i] = weight_center 115 | 116 | return signal -------------------------------------------------------------------------------- /SpikeCodingPython/EncodingSchemes.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python 2 | 3 | # This file is part of the SpikeCoding repository - MAVLab TU Delft 4 | # 5 | # MIT License 6 | # 7 | # Copyright (c) 2021 Julien Dupeyroux 8 | # 9 | # Permission is hereby granted, free of charge, to any person obtaining a copy 10 | # of this software and associated documentation files (the "Software"), to deal 11 | # in the Software without restriction, including without limitation the rights 12 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 | # copies of the Software, and to permit persons to whom the Software is 14 | # furnished to do so, subject to the following conditions: 15 | # 16 | # The above copyright notice and this permission notice shall be included in all 17 | # copies or substantial portions of the Software. 18 | # 19 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 25 | # SOFTWARE. 26 | # 27 | # @author Julien Dupeyroux, Stein Stroobants 28 | 29 | import numpy as np 30 | from scipy.stats import norm 31 | 32 | 33 | def temporal_contrast(data, factor): 34 | # Based on algorithm provided in: 35 | # Sengupta et al. (2017) 36 | # Petro et al. (2020) 37 | diff = np.zeros(len(data)-1) 38 | spikes = np.zeros(len(data)) 39 | for i in range(len(data)-1): 40 | diff[i] = data[i+1] - data[i] 41 | threshold = np.mean(diff) + factor * np.std(diff) 42 | diff = np.insert(diff, 0, diff[1]) 43 | for i in range(len(data)): 44 | if diff[i] > threshold: 45 | spikes[i] = 1 46 | elif diff[i] < -threshold: 47 | spikes[i] = -1 48 | return spikes, threshold 49 | 50 | 51 | def step_forward(data, threshold): 52 | # Based on algorithm provided in: 53 | # Petro et al. (2020) 54 | startpoint = data[0] 55 | spikes = np.zeros(len(data)) 56 | base = startpoint 57 | for i in range(1,len(data)): 58 | if data[i] > base + threshold: 59 | spikes[i] = 1 60 | base = base + threshold 61 | elif data[i] < base - threshold: 62 | spikes[i] = -1 63 | base = base - threshold 64 | return spikes, startpoint 65 | 66 | 67 | def moving_window(data, threshold, window): 68 | # Based on algorithm provided in: 69 | # Petro et al. (2020) 70 | startpoint = data[0] 71 | spikes = np.zeros(len(data)) 72 | base = np.mean(data[0:window+1]) 73 | for i in range(window+1): 74 | if data[i] > base + threshold: 75 | spikes[i] = 1 76 | elif data[i] < base - threshold: 77 | spikes[i] = -1 78 | for i in range(window+2, len(data)): 79 | base = np.mean(data[(i-window-1):(i-1)]) 80 | if data[i] > base + threshold: 81 | spikes[i] = 1 82 | elif data[i] < base - threshold: 83 | spikes[i] = -1 84 | return spikes, startpoint 85 | 86 | 87 | def hough_spike(data, fir): 88 | # Based on algorithm provided in: 89 | # Schrauwen et al. (2003) 90 | spikes = np.zeros(len(data)) 91 | shift = min(data) 92 | data = data - shift*np.ones(len(data)) 93 | for i in range(len(data)): 94 | count = 0 95 | for j in range(len(fir)): 96 | if i+j < len(data): 97 | if data[i+j] >= fir[j]: 98 | count = count + 1 99 | if count == len(fir): 100 | spikes[i] = 1 101 | for j in range(len(fir)): 102 | if i+j < len(data): 103 | data[i+j] = data[i+j] - fir[j] 104 | return spikes, shift 105 | 106 | 107 | def modified_hough_spike(data, fir, threshold): 108 | # Based on algorithm provided in: 109 | # Schrauwen et al. (2003) 110 | spikes = np.zeros(len(data)) 111 | shift = min(data) 112 | data = data - shift*np.ones(len(data)) 113 | for i in range(len(data)): 114 | error = 0 115 | for j in range(len(fir)): 116 | if i+j < len(data): 117 | if data[i+j] < fir[j]: 118 | error = error + fir[j] - data[i+j] 119 | if error <= threshold: 120 | spikes[i] = 1 121 | for j in range(len(fir)): 122 | if i+j < len(data): 123 | data[i+j] = data[i+j] - fir[j] 124 | return spikes, shift 125 | 126 | 127 | def ben_spike(data, fir, threshold): 128 | # Based on algorithm provided in: 129 | # Petro et al. (2020) 130 | # Sengupta et al. (2017) 131 | # Schrauwen et al. (2003) 132 | spikes = np.zeros(len(data)) 133 | shift = min(data) 134 | data = data - shift*np.ones(len(data)) 135 | for i in range(len(data)-len(fir)+1): 136 | err1 = 0 137 | err2 = 0 138 | for j in range(len(fir)): 139 | err1 = err1 + abs(data[i+j] - fir[j]) 140 | err2 = err2 + abs(data[i+j-1]) 141 | if err1 <= err2*threshold: 142 | spikes[i] = 1 143 | for j in range(len(fir)): 144 | if i+j+1 < len(data): 145 | data[i+j+1] = data[i+j+1] - fir[j] 146 | return spikes, shift 147 | 148 | 149 | def grf_spike(data, m, min_input, max_input): 150 | # Adapted from algorithm provided in: 151 | # Bohté et al. (2002) 152 | # Modifications: definition of sigma, removal of beta constant, 153 | # and modified WTA process 154 | 155 | if np.isscalar(data): 156 | data = [data] 157 | 158 | spikes = np.zeros((len(data),m)) 159 | neuron_outputs = np.zeros(m) 160 | 161 | for j in range(len(data)): 162 | for i in range(m): 163 | mu = min_input + (2*(i + 1)-3)/2*(max_input - min_input)/(m-2) 164 | sigma = (max_input - min_input)/(m-2) 165 | neuron_outputs[i] = norm.pdf(data[j], mu, sigma) 166 | 167 | spikes[j,np.argmax(neuron_outputs)] = 1 168 | return spikes 169 | 170 | def one_hot_place_spike(data, m, min_input, max_input): 171 | # Simple population coding algorithm adapted from Stagsted et al. (2020) that represents inputs by a location. 172 | # An input is assigned to the neuron that is closest to its value. 173 | # Only one neuron fires at every timestep 174 | 175 | if np.isscalar(data): 176 | data = [data] 177 | 178 | spikes = np.zeros((len(data),m)) 179 | 180 | for j in range(len(data)): 181 | size_change = 1/2*(max_input - min_input)/(m-2) # to make sure it has the same lower/upper bounds as the Bohte paper 182 | idx = int(np.round(((data[j] - (min_input - size_change)) / ((max_input + size_change) - (min_input - size_change))) * (m - 1))) 183 | spikes[j, idx] = 1 184 | 185 | return spikes 186 | 187 | 188 | def grf_spike_with_internal_timesteps(data, min_input, max_input, neurons=10, timesteps=10, beta=1.5): 189 | """Create a series of spikes based on Gaussian Receptive Fields 190 | Adapted from algorithm provided in: 191 | Bohté et al. (2002) 192 | 193 | Keyword arguments: 194 | data -- 195 | neurons -- numbers of neurons (default 10) 196 | timesteps -- number of timesteps (default 10) 197 | min_input -- minimal value 198 | max_input -- maximum value 199 | beta -- tuning parameter that determines the width of the receptive fields 200 | """ 201 | 202 | if np.isscalar(data): 203 | data = [data] 204 | 205 | spikes = np.zeros((len(data), timesteps, neurons)) 206 | responses = np.zeros(neurons) 207 | 208 | # Calculation of mu and sigma of the Gaussian receptive fields 209 | mu = min_input + (2*(np.arange(neurons)+1)-3)/2*(max_input - min_input)/(neurons-2) 210 | sigma = 1/beta*(max_input - min_input)/(neurons-2) 211 | max_prob = norm.pdf(mu[0], mu[0], sigma) 212 | 213 | for j in range(len(data)): 214 | for i in range(neurons): 215 | responses[i] = norm.pdf(data[j], mu[i], sigma) 216 | size_change = max_prob / (2 * timesteps) 217 | new = int(np.round(((responses[i] + size_change) / (max_prob + 2 * size_change) * (timesteps + 1)) + 0.0001)) # 0.0001 for roundoff errors... 218 | spiking_time = timesteps - new 219 | if spiking_time < timesteps - 1: 220 | spikes[j, spiking_time, i] = 1 221 | spikes = spikes.reshape([len(data) * timesteps, neurons]) 222 | return spikes -------------------------------------------------------------------------------- /SpikeCodingPython/FunctionGenerator.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python 2 | 3 | # This file is part of the SpikeCoding repository - MAVLab TU Delft 4 | # 5 | # MIT License 6 | # 7 | # Copyright (c) 2021 Julien Dupeyroux 8 | # 9 | # Permission is hereby granted, free of charge, to any person obtaining a copy 10 | # of this software and associated documentation files (the "Software"), to deal 11 | # in the Software without restriction, including without limitation the rights 12 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 | # copies of the Software, and to permit persons to whom the Software is 14 | # furnished to do so, subject to the following conditions: 15 | # 16 | # The above copyright notice and this permission notice shall be included in all 17 | # copies or substantial portions of the Software. 18 | # 19 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 25 | # SOFTWARE. 26 | # 27 | # @author Julien Dupeyroux 28 | 29 | import numpy as np 30 | import math 31 | from scipy.stats import norm 32 | 33 | 34 | def noisy_sine_wave(a, f, phi, sigma, time): 35 | mySin = np.vectorize(math.sin) 36 | return a*mySin(2*math.pi*f*time + phi*np.ones(len(time))) + np.random.rand(len(time))*sigma 37 | 38 | 39 | def sum_of_sine_waves(a, f, phi, sigma, time): 40 | signal = np.zeros(len(time)) 41 | for j in range(len(a)): 42 | signal = signal + noisy_sine_wave(a[j], f[j], phi[j], sigma, time) 43 | return signal 44 | 45 | 46 | def noisy_gaussian_wave(a, m, s, sigma, time): 47 | return a*norm.pdf(time, m, s) + sigma*np.random.rand(len(time)) 48 | 49 | 50 | def sum_of_gaussian_wave(a, m, s, sigma, time): 51 | signal = np.zeros(len(time)) 52 | for j in range(len(a)): 53 | signal = signal + noisy_gaussian_wave(a[j], m[j], s[j], 0, time) + np.random.rand(len(time))*sigma 54 | return signal 55 | -------------------------------------------------------------------------------- /SpikeCodingPython/__pycache__/DecodingSchemes.cpython-38.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JuSquare/SpikeCoding/48e84b80035e1dfd1eebd32c347a23cc5d52338e/SpikeCodingPython/__pycache__/DecodingSchemes.cpython-38.pyc -------------------------------------------------------------------------------- /SpikeCodingPython/__pycache__/EncodingSchemes.cpython-38.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JuSquare/SpikeCoding/48e84b80035e1dfd1eebd32c347a23cc5d52338e/SpikeCodingPython/__pycache__/EncodingSchemes.cpython-38.pyc -------------------------------------------------------------------------------- /SpikeCodingPython/__pycache__/FunctionGenerator.cpython-38.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JuSquare/SpikeCoding/48e84b80035e1dfd1eebd32c347a23cc5d52338e/SpikeCodingPython/__pycache__/FunctionGenerator.cpython-38.pyc -------------------------------------------------------------------------------- /SpikeCodingPython/bag_gaussian_fields.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JuSquare/SpikeCoding/48e84b80035e1dfd1eebd32c347a23cc5d52338e/SpikeCodingPython/bag_gaussian_fields.png -------------------------------------------------------------------------------- /SpikeCodingPython/bag_moving_window.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JuSquare/SpikeCoding/48e84b80035e1dfd1eebd32c347a23cc5d52338e/SpikeCodingPython/bag_moving_window.png -------------------------------------------------------------------------------- /SpikeCodingPython/bag_step_forward.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JuSquare/SpikeCoding/48e84b80035e1dfd1eebd32c347a23cc5d52338e/SpikeCodingPython/bag_step_forward.png -------------------------------------------------------------------------------- /SpikeCodingPython/bag_temporal_contrast.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JuSquare/SpikeCoding/48e84b80035e1dfd1eebd32c347a23cc5d52338e/SpikeCodingPython/bag_temporal_contrast.png -------------------------------------------------------------------------------- /SpikeCodingPython/main.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python 2 | 3 | # This file is part of the SpikeCoding repository - MAVLab TU Delft 4 | # 5 | # MIT License 6 | # 7 | # Copyright (c) 2021 Julien Dupeyroux 8 | # 9 | # Permission is hereby granted, free of charge, to any person obtaining a copy 10 | # of this software and associated documentation files (the "Software"), to deal 11 | # in the Software without restriction, including without limitation the rights 12 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 | # copies of the Software, and to permit persons to whom the Software is 14 | # furnished to do so, subject to the following conditions: 15 | # 16 | # The above copyright notice and this permission notice shall be included in all 17 | # copies or substantial portions of the Software. 18 | # 19 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 25 | # SOFTWARE. 26 | # 27 | # @author Julien Dupeyroux 28 | 29 | import csv 30 | import numpy as np 31 | import matplotlib.pyplot as plt 32 | from scipy import signal 33 | from scipy.stats import norm 34 | import EncodingSchemes as ES 35 | import DecodingSchemes as DS 36 | import FunctionGenerator as FG 37 | 38 | 39 | if __name__ == '__main__': 40 | dt = 0.01 41 | T_max = 4 42 | time = np.arange(0, T_max, dt) 43 | 44 | S = list() 45 | S.append(FG.sum_of_sine_waves([2, -0.5, 0.75], [1.0, 3.0, 5.0], [0.0, 0.0, 0.0], 0.0, time)) 46 | S.append(FG.sum_of_sine_waves([-0.25], [1.0], [0.0], 0.05, time)) 47 | S.append(FG.sum_of_gaussian_wave([1, 0.5], [0.2, 0.75], [0.1, 0.1], 0.1, time)) 48 | 49 | # tbr_factors = [1.005, 1.005, 1.005] 50 | 51 | # sf_thresholds = [0.35, 0.05, 0.35] 52 | 53 | # mw_thresholds = [0.325, 0.015, 0.225] 54 | # mw_window = [3, 3, 3] 55 | 56 | # for i in range(len(S)): 57 | 58 | # spikes_TBR, threshold = ES.temporal_contrast(S[i], tbr_factors[i]) 59 | # signal_TBR = 2*DS.temporal_contrast(spikes_TBR, threshold) 60 | 61 | # spikes_SF, startpoint = ES.step_forward(S[i], sf_thresholds[i]) 62 | # signal_SF = DS.step_forward(spikes_SF, sf_thresholds[i], startpoint) 63 | 64 | # spikes_MW, startpoint = ES.moving_window(S[i], mw_thresholds[i], mw_window[i]) 65 | # signal_MW = DS.moving_window(spikes_MW, mw_thresholds[i], startpoint) 66 | 67 | # plt.subplot(3*len(S),3,(1+i*3*len(S),4+i*3*len(S))) 68 | # plt.plot(time, S[i]) 69 | # plt.plot(time, signal_TBR) 70 | # plt.gca().axes.get_xaxis().set_visible(False) 71 | # plt.gca().axes.get_yaxis().set_visible(False) 72 | # if i == 0: 73 | # plt.title("Temporal Contrast Algorithm TBR") 74 | 75 | # plt.subplot(3*len(S),3,7+i*3*len(S)) 76 | # plt.stem(time, spikes_TBR) 77 | # plt.gca().axes.get_xaxis().set_visible(False) 78 | # plt.gca().axes.get_yaxis().set_visible(False) 79 | 80 | # plt.subplot(3*len(S),3,(2+i*3*len(S),5+i*3*len(S))) 81 | # plt.plot(time, S[i]) 82 | # plt.plot(time, signal_SF) 83 | # plt.gca().axes.get_xaxis().set_visible(False) 84 | # plt.gca().axes.get_yaxis().set_visible(False) 85 | # if i == 0: 86 | # plt.title("Step Forward Algorithm SF") 87 | 88 | # plt.subplot(3*len(S),3,8+i*3*len(S)) 89 | # plt.stem(time, spikes_SF) 90 | # plt.gca().axes.get_xaxis().set_visible(False) 91 | # plt.gca().axes.get_yaxis().set_visible(False) 92 | 93 | # plt.subplot(3*len(S),3,(3+i*3*len(S),6+i*3*len(S))) 94 | # plt.plot(time, S[i]) 95 | # plt.plot(time, signal_MW) 96 | # plt.gca().axes.get_xaxis().set_visible(False) 97 | # plt.gca().axes.get_yaxis().set_visible(False) 98 | # if i == 0: 99 | # plt.title("Moving Window Algorithm MW") 100 | 101 | # plt.subplot(3*len(S),3,9+i*3*len(S)) 102 | # plt.stem(time, spikes_MW) 103 | # plt.gca().axes.get_xaxis().set_visible(False) 104 | # plt.gca().axes.get_yaxis().set_visible(False) 105 | 106 | # plt.show() 107 | 108 | # hsa_window = [12, 15, 12] 109 | # hsa_fir = list() 110 | # hsa_fir.append(signal.triang(hsa_window[0])) 111 | # hsa_fir.append(norm.pdf(np.linspace(1, hsa_window[1], hsa_window[1]), 0, 5)) 112 | # hsa_fir.append(signal.triang(hsa_window[2])) 113 | 114 | # hsa_m_thresholds = [0.85, 0.05, 0.5] 115 | 116 | # bsa_window = [9, 10, 8] 117 | # bsa_fir = list() 118 | # bsa_fir.append(signal.triang(bsa_window[0])) 119 | # bsa_fir.append(norm.pdf(np.linspace(1, bsa_window[1], bsa_window[1]), 1.5, 3.5)) 120 | # bsa_fir.append(signal.triang(bsa_window[2])) 121 | 122 | # bsa_thresholds = [1.175, 1.05, 1.2] 123 | 124 | # for i in range(len(S)): 125 | 126 | # spikes_HSA, shift = ES.hough_spike(S[i], hsa_fir[i]) 127 | # signal_HSA = DS.ben_spike(spikes_HSA, hsa_fir[i], shift) 128 | 129 | # spikes_HSAm, shift = ES.modified_hough_spike(S[i], hsa_fir[i], hsa_m_thresholds[i]) 130 | # signal_HSAm = DS.ben_spike(spikes_HSAm, hsa_fir[i], shift) 131 | 132 | # spikes_BSA, shift = ES.ben_spike(S[i], bsa_fir[i], bsa_thresholds[i]) 133 | # signal_BSA = DS.ben_spike(spikes_BSA, bsa_fir[i], shift) 134 | 135 | # plt.subplot(3*len(S),3,(1+i*3*len(S),4+i*3*len(S))) 136 | # plt.plot(time, S[i]) 137 | # plt.plot(time, signal_HSA) 138 | # plt.gca().axes.get_xaxis().set_visible(False) 139 | # plt.gca().axes.get_yaxis().set_visible(False) 140 | # if i == 0: 141 | # plt.title("Hough Spike Algorithm HSA") 142 | 143 | # plt.subplot(3*len(S),3,7+i*3*len(S)) 144 | # plt.stem(time, spikes_HSA) 145 | # plt.gca().axes.get_xaxis().set_visible(False) 146 | # plt.gca().axes.get_yaxis().set_visible(False) 147 | 148 | # plt.subplot(3*len(S),3,(2+i*3*len(S),5+i*3*len(S))) 149 | # plt.plot(time, S[i]) 150 | # plt.plot(time, signal_HSAm) 151 | # plt.gca().axes.get_xaxis().set_visible(False) 152 | # plt.gca().axes.get_yaxis().set_visible(False) 153 | # if i == 0: 154 | # plt.title("Threshold Hough Spike Algorithm T-HSA") 155 | 156 | # plt.subplot(3*len(S),3,8+i*3*len(S)) 157 | # plt.stem(time, spikes_HSAm) 158 | # plt.gca().axes.get_xaxis().set_visible(False) 159 | # plt.gca().axes.get_yaxis().set_visible(False) 160 | 161 | # plt.subplot(3*len(S),3,(3+i*3*len(S),6+i*3*len(S))) 162 | # plt.plot(time, S[i]) 163 | # plt.plot(time, signal_BSA) 164 | # plt.gca().axes.get_xaxis().set_visible(False) 165 | # plt.gca().axes.get_yaxis().set_visible(False) 166 | # if i == 0: 167 | # plt.title("Ben Spike Algorithm BSA") 168 | 169 | # plt.subplot(3*len(S),3,9+i*3*len(S)) 170 | # plt.stem(time, spikes_BSA) 171 | # plt.gca().axes.get_xaxis().set_visible(False) 172 | # plt.gca().axes.get_yaxis().set_visible(False) 173 | 174 | # plt.show() 175 | 176 | number_of_neurons_grf = 15 177 | 178 | nb_neurons_BOHTE = 15 179 | nb_timesteps_BOHTE = 10 180 | beta_BOHTE = 1.5 181 | 182 | for i in range(len(S)): 183 | 184 | 185 | [min_input, max_input] = [min(S[i]), max(S[i])] 186 | spikes_GRF = ES.grf_spike(S[i], number_of_neurons_grf, min_input, max_input) 187 | signal_GRF = DS.grf_spike(spikes_GRF, min_input, max_input) 188 | 189 | spikes_BOHTE = ES.grf_spike_with_internal_timesteps(S[i], min_input, max_input, nb_neurons_BOHTE, nb_timesteps_BOHTE, beta_BOHTE) 190 | signal_BOHTE = DS.grf_spike_with_internal_timesteps(spikes_BOHTE, nb_timesteps_BOHTE, min_input, max_input) 191 | # shape = spikes_BOHTE.shape 192 | # new_spikes_BOHTE = spikes_BOHTE.reshape((int(shape[0]/nb_timesteps_BOHTE), nb_timesteps_BOHTE, shape[1])) 193 | 194 | plt.subplot(3*len(S),3,(1+i*3*len(S),4+i*3*len(S))) 195 | plt.plot(time, S[i]) 196 | plt.plot(time, signal_GRF) 197 | plt.gca().axes.get_xaxis().set_visible(False) 198 | plt.gca().axes.get_yaxis().set_visible(False) 199 | if i == 0: 200 | plt.title("Gaussian Receptive Fields GRF") 201 | 202 | plt.subplot(3*len(S),3,7+i*3*len(S)) 203 | for k in range(len(S[i])): 204 | plt.plot([time[k], time[k]], [np.argmax(spikes_GRF[k,:])-0.35, np.argmax(spikes_GRF[k,:])+0.35]) 205 | plt.gca().axes.get_xaxis().set_visible(False) 206 | plt.gca().axes.get_yaxis().set_visible(False) 207 | 208 | plt.subplot(3*len(S),3,(3+i*3*len(S),6+i*3*len(S))) 209 | plt.plot(time, S[i]) 210 | plt.plot(time, signal_BOHTE) 211 | plt.gca().axes.get_xaxis().set_visible(False) 212 | plt.gca().axes.get_yaxis().set_visible(False) 213 | if i == 0: 214 | plt.title("Bohté et al. (2002) GRF") 215 | 216 | plt.subplot(3*len(S),3,9+i*3*len(S)) 217 | # TODO: add plot 218 | plt.gca().axes.get_xaxis().set_visible(False) 219 | plt.gca().axes.get_yaxis().set_visible(False) 220 | 221 | plt.show() -------------------------------------------------------------------------------- /SpikeCodingPython/process_rosbags.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python 2 | 3 | # This file is part of the SpikeCoding repository - MAVLab TU Delft 4 | # 5 | # MIT License 6 | # 7 | # Copyright (c) 2021 Julien Dupeyroux 8 | # 9 | # Permission is hereby granted, free of charge, to any person obtaining a copy 10 | # of this software and associated documentation files (the "Software"), to deal 11 | # in the Software without restriction, including without limitation the rights 12 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 | # copies of the Software, and to permit persons to whom the Software is 14 | # furnished to do so, subject to the following conditions: 15 | # 16 | # The above copyright notice and this permission notice shall be included in all 17 | # copies or substantial portions of the Software. 18 | # 19 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 25 | # SOFTWARE. 26 | # 27 | # @author Julien Dupeyroux 28 | 29 | import rosbag 30 | import sys 31 | import numpy as np 32 | import math 33 | import matplotlib.pyplot as plt 34 | import DecodingSchemes as DS 35 | 36 | if __name__ == '__main__': 37 | 38 | if len(sys.argv) != 2: 39 | sys.exit("Usage: python process_rosbags.py ") 40 | 41 | bag = rosbag.Bag(sys.argv[1]) 42 | 43 | events = list() 44 | signal = list() 45 | time = list() 46 | threshold = list() 47 | 48 | min_input = None 49 | max_input = None 50 | startpoint = None 51 | coding = None 52 | 53 | print(bag) 54 | 55 | for topic, msg, t in bag.read_messages(topics=['event']): 56 | events.append(msg.spike) 57 | time.append((msg.timestamp.to_nsec() / (1e-9))) 58 | signal.append(float(msg.input)) 59 | threshold.append(float(msg.threshold)) 60 | if coding == None: 61 | coding = msg.scheme 62 | if startpoint == None: 63 | startpoint = float(msg.start) 64 | if min_input == None: 65 | min_input = float(msg.min_input) 66 | if max_input == None: 67 | max_input = float(msg.max_input) 68 | 69 | bag.close() 70 | events = np.array(events) 71 | 72 | if coding == "temporal_contrast": 73 | reconstructed_signal = 2*DS.temporal_contrast(events, np.mean(threshold)) 74 | elif coding == "step_forward": 75 | reconstructed_signal = DS.step_forward(events, np.mean(threshold), startpoint) 76 | elif coding == "moving_window": 77 | reconstructed_signal = DS.moving_window(events, np.mean(threshold), startpoint) 78 | # elif coding == "bsa" or coding == "hsa" or coding == "threshold_hsa": 79 | # # TODO: include fir, shift 80 | # reconstructed_signal = DS.ben_spike(events, fir, shift) 81 | elif coding == "gaussian_fields": 82 | reconstructed_signal = DS.grf_spike(events, min_input, max_input) 83 | else: 84 | sys.exit("Encoding scheme not recognized!") 85 | 86 | 87 | 88 | plt.subplot(3,1,(1,2)) 89 | plt.plot(signal) 90 | plt.plot(reconstructed_signal) 91 | plt.title(coding) 92 | plt.legend(["Original signal", "Reconstructed signal"]) 93 | plt.subplot(3,1,3) 94 | if coding == "gaussian_fields": 95 | for i in range(len(events)): 96 | plt.plot([i, i], [np.argmax(events[i,:])-0.35, np.argmax(events[i,:])+0.35]) 97 | else: 98 | plt.stem(events) 99 | plt.xlabel("Timestamps") 100 | 101 | plt.show() -------------------------------------------------------------------------------- /SpikeCodingPython/test-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JuSquare/SpikeCoding/48e84b80035e1dfd1eebd32c347a23cc5d52338e/SpikeCodingPython/test-1.png -------------------------------------------------------------------------------- /SpikeCodingPython/test-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JuSquare/SpikeCoding/48e84b80035e1dfd1eebd32c347a23cc5d52338e/SpikeCodingPython/test-2.png -------------------------------------------------------------------------------- /SpikeCodingPython/test-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JuSquare/SpikeCoding/48e84b80035e1dfd1eebd32c347a23cc5d52338e/SpikeCodingPython/test-3.png --------------------------------------------------------------------------------