├── .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 | 
45 |
46 | 
47 |
48 | 
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 | 
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 | 
125 |
126 |
127 | Step Forward (SF) Temporal Coding with Threshold = 5
128 | 
129 |
130 | Step Forward (SF) Temporal Coding with Threshold = 10
131 | 
132 |
133 | Step Forward (SF) Temporal Coding with Threshold = 20
134 | 
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
--------------------------------------------------------------------------------