comparison trafficintelligence/moving.py @ 1196:d5566af60a69

correcting bug with savgol filter, renaming the functions to proper names filterSG and getAccelerationsSG
author Nicolas Saunier <nicolas.saunier@polymtl.ca>
date Thu, 14 Jul 2022 11:29:13 +0200
parents 27a6a7f9b972
children 0475b4cd0cfb
comparison
equal deleted inserted replaced
1195:27a6a7f9b972 1196:d5566af60a69
846 diff.addPosition(self[i]-self[i-1]) 846 diff.addPosition(self[i]-self[i-1])
847 if doubleLastPosition: 847 if doubleLastPosition:
848 diff.addPosition(diff[-1]) 848 diff.addPosition(diff[-1])
849 return diff 849 return diff
850 850
851 def differentiateSG(self, window_length, polyorder, deriv=0, delta=1.0, axis=-1, mode='nearest', cval=0.0, nInstantsIgnoredAtEnds = 2): 851 def filterSG(self, window_length, polyorder, deriv=0, delta=1.0, axis=-1, mode='nearest', cval=0.0, nInstantsIgnoredAtEnds = 2):
852 '''Differentiates the trajectory using the Savitsky Golay filter 852 '''Filters the trajectory using the Savitsky Golay filter
853 if deriv = 1, the method differentiates
854 Warning: high order polynomials yield artefacts
853 855
854 window_length : The length of the filter window (i.e. the number of coefficients). window_length must be a positive odd integer. 856 window_length : The length of the filter window (i.e. the number of coefficients). window_length must be a positive odd integer.
855 polyorder : The order of the polynomial used to fit the samples. polyorder must be less than window_length. 857 polyorder : The order of the polynomial used to fit the samples. polyorder must be less than window_length.
856 deriv : The order of the derivative to compute. This must be a nonnegative integer. The default is 0, which means to filter the data without differentiating. 858 deriv : The order of the derivative to compute. This must be a nonnegative integer. The default is 0, which means to filter the data without differentiating.
857 delta : The spacing of the samples to which the filter will be applied. This is only used if deriv > 0. Default is 1.0. 859 delta : The spacing of the samples to which the filter will be applied. This is only used if deriv > 0. Default is 1.0.
859 mode : Must be mirror, constant, nearest, wrap or interp. This determines the type of extension to use for the padded signal to which the filter is applied. When mode is constant, the padding value is given by cval. See the Notes for more details on mirror, constant, wrap, and nearest. When the interp mode is selected (the default), no extension is used. Instead, a degree polyorder polynomial is fit to the last window_length values of the edges, and this polynomial is used to evaluate the last window_length // 2 output values. 861 mode : Must be mirror, constant, nearest, wrap or interp. This determines the type of extension to use for the padded signal to which the filter is applied. When mode is constant, the padding value is given by cval. See the Notes for more details on mirror, constant, wrap, and nearest. When the interp mode is selected (the default), no extension is used. Instead, a degree polyorder polynomial is fit to the last window_length values of the edges, and this polynomial is used to evaluate the last window_length // 2 output values.
860 cval : Value to fill past the edges of the input if mode is constant. Default is 0.0. 862 cval : Value to fill past the edges of the input if mode is constant. Default is 0.0.
861 863
862 https://docs.scipy.org/doc/scipy/reference/generated/scipy.signal.savgol_filter.html#scipy.signal.savgol_filter''' 864 https://docs.scipy.org/doc/scipy/reference/generated/scipy.signal.savgol_filter.html#scipy.signal.savgol_filter'''
863 filtered = savgol_filter(self.positions, window_length, polyorder, deriv, delta, axis, mode, cval) 865 filtered = savgol_filter(self.positions, window_length, polyorder, deriv, delta, axis, mode, cval)
866 length = self.length()
864 if nInstantsIgnoredAtEnds >=1: 867 if nInstantsIgnoredAtEnds >=1:
865 if nInstantsIgnoredAtEnds >= len(speeds)/2: 868 if nInstantsIgnoredAtEnds >= length/2:
866 n = int(round(len(speeds)/2))-1 869 n = int(round(length/2))-1
867 else: 870 else:
868 n = nInstantsIgnoredAtEnds 871 n = nInstantsIgnoredAtEnds
869 filtered = filtered[:,n:-n] 872 filtered = filtered[:,n:-n]
870 return Trajectory(filtered.tolist()) 873 return Trajectory(filtered.tolist())
871 874
1563 n = min(nInstantsIgnoredAtEnds, int(floor(self.length()/2.))) 1566 n = min(nInstantsIgnoredAtEnds, int(floor(self.length()/2.)))
1564 return speeds[n:-n] 1567 return speeds[n:-n]
1565 else: 1568 else:
1566 return speeds 1569 return speeds
1567 1570
1568 def getAccelerations(self, window_length, polyorder, delta=1.0, axis=-1, mode='nearest', cval=0.0, nInstantsIgnoredAtEnds = 0): 1571 def getAccelerationsSG(self, window_length, polyorder, delta=1.0, axis=-1, mode='nearest', cval=0.0, nInstantsIgnoredAtEnds = 0):
1569 '''Returns the 1-D acceleration from the 1-D speeds 1572 '''Returns the 1-D acceleration from the 1-D speeds
1570 Caution about previously filtered data''' 1573 Caution about previously filtered data'''
1571 speeds = self.getSpeeds() 1574 speeds = self.getSpeeds()
1572 wlength = min(window_length, len(speeds)) 1575 wlength = min(window_length, len(speeds))
1573 if wlength % 2 == 0: 1576 if wlength % 2 == 0: