# HG changeset patch # User Nicolas Saunier # Date 1708052675 18000 # Node ID 77fbd0e2ba7d54908ee5cee26cf4321664b861df # Parent 2aa56b101041a72a613c9cb23b0babeffab5803e dltrack works with moving average filtering diff -r 2aa56b101041 -r 77fbd0e2ba7d scripts/dltrack.py --- a/scripts/dltrack.py Thu Feb 15 14:09:52 2024 -0500 +++ b/scripts/dltrack.py Thu Feb 15 22:04:35 2024 -0500 @@ -59,10 +59,14 @@ lastFrameNum = args.lastFrameNum if args.maskFilename is not None: mask = cv2.imread(args.maskFilename, cv2.IMREAD_GRAYSCALE) -elif params.maskFilename is not None: +elif params is not None and params.maskFilename is not None: mask = cv2.imread(params.maskFilename, cv2.IMREAD_GRAYSCALE) else: mask = None +if params is not None: + smoothingHalfWidth = params.smoothingHalfWidth +else: + smoothingHalfWidth = None # TODO use mask, remove short objects, smooth @@ -135,9 +139,14 @@ cv2.destroyAllWindows() # classification +shortObjectNumbers = [] for num, obj in objects.items(): - obj.setUserType(utils.mostCommon(obj.userTypes)) # improve? mix with speed? - + if obj.length() < 3: + shortObjectNumbers.append(num) + else: + obj.setUserType(utils.mostCommon(obj.userTypes)) # improve? mix with speed? +for num in shortObjectNumbers: + del objects[num] # TODO add quality control: avoid U-turns # merge bikes and people @@ -242,8 +251,14 @@ featureNum = features[0].getNum() obj.features=[moving.MovingObject(featureNum, obj.getTimeInterval(), moving.Trajectory(projected.tolist()))] obj.featureNumbers = [featureNum] +if smoothingHalfWidth is not None: # smoothing + for num, obj in objects.items(): + for f in obj.getFeatures(): + f.positions = f.getPositions().filterMovingWindow(smoothingHalfWidth) storage.saveTrajectoriesToSqlite(args.databaseFilename, list(objects.values()), 'object') + + # todo save bbox and mask to study localization / representation # apply quality checks deviation and acceleration bounds? diff -r 2aa56b101041 -r 77fbd0e2ba7d trafficintelligence/moving.py --- a/trafficintelligence/moving.py Thu Feb 15 14:09:52 2024 -0500 +++ b/trafficintelligence/moving.py Thu Feb 15 22:04:35 2024 -0500 @@ -990,10 +990,10 @@ return Trajectory([[alpha*x for x in self.getXCoordinates()], [alpha*y for y in self.getYCoordinates()]]) - def filterMovingWindow(self, halfWidth, mode = 'valid'): + def filterMovingWindow(self, halfWidth): '''Returns a new Trajectory obtained after the smoothing of the input by a moving average''' - return Trajectory([utils.filterMovingWindow(self.positions[0], halfWidth, mode), - utils.filterMovingWindow(self.positions[1], halfWidth, mode)]) + return Trajectory([utils.filterMovingWindow(self.positions[0], halfWidth), + utils.filterMovingWindow(self.positions[1], halfWidth)]) def differentiate(self, doubleLastPosition = False): diff = Trajectory() diff -r 2aa56b101041 -r 77fbd0e2ba7d trafficintelligence/storage.py --- a/trafficintelligence/storage.py Thu Feb 15 14:09:52 2024 -0500 +++ b/trafficintelligence/storage.py Thu Feb 15 22:04:35 2024 -0500 @@ -1654,7 +1654,7 @@ self.minFeatureEigThreshold = config.getfloat(self.sectionHeader, 'min-feature-eig-threshold') self.minFeatureTime = config.getint(self.sectionHeader, 'min-feature-time') self.minFeatureDisplacement = config.getfloat(self.sectionHeader, 'min-feature-displacement') - self.smoothingHalfWidth = config.getfloat(self.sectionHeader, 'smoothing-halfwidth') + self.smoothingHalfWidth = config.getint(self.sectionHeader, 'smoothing-halfwidth') #self.updateTimer = config.getint(self.sectionHeader, 'tracker-reload-time') diff -r 2aa56b101041 -r 77fbd0e2ba7d trafficintelligence/tests/utils.txt --- a/trafficintelligence/tests/utils.txt Thu Feb 15 14:09:52 2024 -0500 +++ b/trafficintelligence/tests/utils.txt Thu Feb 15 22:04:35 2024 -0500 @@ -1,5 +1,6 @@ >>> from trafficintelligence.utils import * >>> from trafficintelligence.moving import Point +>>> from numpy import array, arange >>> upperCaseFirstLetter('mmmm... donuts') 'Mmmm... Donuts' @@ -46,6 +47,15 @@ >>> values[-1] 6.0 +>>> filterMovingWindow(arange(10), 3) +array([0., 1., 2., 3., 4., 5., 6., 7., 8., 9.]) +>>> filterMovingWindow(list(range(10)), 3) +array([0., 1., 2., 3., 4., 5., 6., 7., 8., 9.]) +>>> filterMovingWindow(arange(10.), 3) +array([0., 1., 2., 3., 4., 5., 6., 7., 8., 9.]) +>>> filterMovingWindow(arange(10.), 2) +array([0., 1., 2., 3., 4., 5., 6., 7., 8., 9.]) + >>> stepPlot([3, 5, 7, 8], 1, 10, 0) ([1, 3, 3, 5, 5, 7, 7, 8, 8, 10], [0, 0, 1, 1, 2, 2, 3, 3, 4, 4]) diff -r 2aa56b101041 -r 77fbd0e2ba7d trafficintelligence/utils.py --- a/trafficintelligence/utils.py Thu Feb 15 14:09:52 2024 -0500 +++ b/trafficintelligence/utils.py Thu Feb 15 22:04:35 2024 -0500 @@ -11,7 +11,7 @@ from scipy.stats import rv_continuous, kruskal, shapiro, lognorm, norm, t, chi2_contingency from scipy.spatial import distance from scipy.sparse import dok_matrix -from numpy import zeros, array, exp, sum as npsum, int64 as npint, arange, cumsum, mean, median, percentile, isnan, ones, convolve, dtype, isnan, NaN, ma, isinf, savez, load as npload, log, polyfit +from numpy import zeros, array, exp, sum as npsum, int64 as npint, arange, cumsum, mean, median, percentile, isnan, ones, convolve, dtype, isnan, NaN, ma, isinf, savez, load as npload, log, polyfit, float64 from numpy.random import random_sample, permutation as nppermutation from pandas import DataFrame, concat, crosstab import matplotlib.pyplot as plt @@ -431,13 +431,18 @@ smoothed[point] = max(set(window_values), key=window_values.count) return smoothed -def filterMovingWindow(inputSignal, halfWidth, mode = 'valid'): +def filterMovingWindow(inputSignal, halfWidth): '''Returns an array obtained after the smoothing of the 1-D input by a moving average The size of the output depends on the mode: 'full', 'same', 'valid' See https://numpy.org/doc/stable/reference/generated/numpy.convolve.html.''' - width = min(len(inputSignal), int(halfWidth*2+1)) - win = ones(width,'d') - return convolve(win/width, array(inputSignal), mode) + halfWidth = min(floor((len(inputSignal)-1)/2.), halfWidth) + win = ones(2*halfWidth+1)/(2*halfWidth+1) + filtered = array(inputSignal, dtype=float64) + filtered[halfWidth:-halfWidth] = convolve(inputSignal, win, 'valid') # .ravel() + for i in range(halfWidth-1): + filtered[i] = sum(inputSignal[:2*i+1])/(2*i+1) + filtered[-1-i] = sum(inputSignal[-1-2*i:])/(2*i+1) + return filtered def linearRegression(x, y, deg = 1, plotData = False): '''returns the least square estimation of the linear regression of y = ax+b