def buildFeature(obj, featureID, num=1): featureList = getFeatures(obj, featureID) tmp = {} delta = {} for i in featureList: for t in xrange(i[1], i[2] + 1): tmp[t] = [i[0], i[3]] newTraj = moving.Trajectory() for instant in obj.getTimeInterval(): newTraj.addPosition( tmp[instant][0].getPositionAtInstant(instant) + tmp[instant][1]) newFeature = moving.MovingObject( num, timeInterval=obj.getTimeInterval(), positions=newTraj) return newFeature
def smoothObject(obj, newNum, minLengthParam=0.7, smoothing=False, plotResults=True, halfWidth=3, _computeVelocities=True, optimize=True, create=False): '''Computes a smoother trajectory for the object and optionnally smoother velocities The object should have its features in obj.features TODO: check whether features are necessary''' if not obj.hasFeatures(): print( 'Object {} has an empty list of features: please load and add them using obj.setFeatures(features)' .format(obj.getNum())) from sys import exit exit() featureList = [ i for i, f in enumerate(obj.getFeatures()) if f.length() >= minLengthParam * obj.length() ] if featureList == []: featureList.append( utils.argmaxDict( {i: f.length() for i, f in enumerate(obj.getFeatures())})) create = True newObjects = [] for featureID in featureList: # featureID should be the index in the list of obj.features newObjects.append( smoothObjectTrajectory(obj, featureID, newNum, smoothing=smoothing, halfWidth=halfWidth, create=create)) newTranslated = moving.Trajectory() newInterval = [] for t in obj.getTimeInterval(): xCoord = [] yCoord = [] for i in newObjects: if i.existsAtInstant(t): p1 = i.getPositionAtInstant(t) xCoord.append(p1.x) yCoord.append(p1.y) if xCoord != []: tmp = moving.Point(median(xCoord), median(yCoord)) newInterval.append(t) newTranslated.addPosition(tmp) newObj = moving.MovingObject(newNum, timeInterval=moving.TimeInterval( min(newInterval), max(newInterval)), positions=newTranslated) if _computeVelocities: tmpTraj = moving.Trajectory() velocities = computeVelocities(newObj, True, 5) for i in sorted(velocities.keys()): tmpTraj.addPosition(velocities[i]) newObj.velocities = tmpTraj else: newObj.velocities = obj.velocities if optimize: csj1 = sumSquaredJerk(obj, fromPosition=True) csj2 = sumSquaredJerk(newObj, fromPosition=True) if csj1 < csj2: newObj = obj newObj.velocities = obj.velocities if _computeVelocities and csj1 >= csj2: csj3 = sumSquaredJerk(obj, fromPosition=False) csj4 = sumSquaredJerk(newObj, fromPosition=False) if csj4 <= csj3: newObj.velocities = obj.velocities newObj.featureNumbers = obj.featureNumbers newObj.features = obj.getFeatures() newObj.userType = obj.userType if plotResults: plt.figure() plt.title('objects_id = {}'.format(obj.num)) for i in featureList: obj.getFeature(i).plot('cx-') obj.plot('rx-') newObj.plot('gx-') return newObj
def smoothObjectTrajectory(obj, featureID, newNum, smoothing=False, halfWidth=3, create=False): results = [] bearing = {} if create: feature = buildFeature(obj, featureID, num=1) # why num=1 else: feature = obj.getFeature(featureID) for t in feature.getTimeInterval(): p1 = feature.getPositionAtInstant(t) p2 = obj.getPositionAtInstant(t) if t != feature.getLastInstant(): p3 = feature.getPositionAtInstant(t + 1) else: p1 = feature.getPositionAtInstant(t - 1) p3 = feature.getPositionAtInstant(t) bearing[t] = getBearing(p1, p2, p3)[1] results.append(getBearing(p1, p2, p3)) medianResults = median(results, 0) dist = medianResults[0] angle = medianResults[3] for i in sorted(bearing.keys()): bearing[i] = bearing[i] + angle if smoothing: bearingInput = [] for i in sorted(bearing.keys()): bearingInput.append(bearing[i]) import utils bearingOut = utils.filterMovingWindow(bearingInput, halfWidth) for t, i in enumerate(sorted(bearing.keys())): bearing[i] = bearingOut[t] #solve a smoothing problem in case of big drop in computing bearing (0,360) for t, i in enumerate(sorted(bearing.keys())): if i != max(bearing.keys()) and abs(bearingInput[t] - bearingInput[t + 1]) >= 340: for x in xrange(max(i - halfWidth, min(bearing.keys())), min(i + halfWidth, max(bearing.keys())) + 1): bearing[x] = bearingInput[t - i + x] translated = moving.Trajectory() for t in feature.getTimeInterval(): p1 = feature.getPositionAtInstant(t) p1.x = p1.x + dist * sin(bearing[t] * pi / 180) p1.y = p1.y + dist * cos(bearing[t] * pi / 180) translated.addPosition(p1) #modify first and last un-smoothed positions (half width) if smoothing: d1 = translated[halfWidth] - feature.positions[halfWidth] d2 = translated[-halfWidth - 1] - feature.positions[-halfWidth - 1] for i in xrange(halfWidth): p1 = feature.getPositionAt(i) + d1 p2 = feature.getPositionAt(-i - 1) + d2 translated.setPosition(i, p1) translated.setPosition(-i - 1, p2) newObj = moving.MovingObject(newNum, timeInterval=feature.getTimeInterval(), positions=translated) return newObj