Mercurial Hosting > traffic-intelligence
changeset 1250:77fbd0e2ba7d
dltrack works with moving average filtering
author | Nicolas Saunier <nicolas.saunier@polymtl.ca> |
---|---|
date | Thu, 15 Feb 2024 22:04:35 -0500 |
parents | 2aa56b101041 |
children | 2b1c8fe8f7e4 |
files | scripts/dltrack.py trafficintelligence/moving.py trafficintelligence/storage.py trafficintelligence/tests/utils.txt trafficintelligence/utils.py |
diffstat | 5 files changed, 42 insertions(+), 12 deletions(-) [+] |
line wrap: on
line diff
--- 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?
--- 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()
--- 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')
--- 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])
--- 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