diff scripts/test-compute-object-position-from-features.py @ 334:1d90e9080cb2

moved python scripts to the scripts directory
author Nicolas Saunier <nicolas.saunier@polymtl.ca>
date Fri, 14 Jun 2013 10:34:11 -0400
parents python/compute-object-from-features.py@04a874e1f19f
children 56cc8a1f7082
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/test-compute-object-position-from-features.py	Fri Jun 14 10:34:11 2013 -0400
@@ -0,0 +1,141 @@
+#!/usr/bin/env python
+
+import sys
+
+import matplotlib.mlab as pylab
+import matplotlib.pyplot as plt
+import numpy as np
+
+import cv
+import utils
+import cvutils
+import ubc_utils
+import moving
+
+# use something like getopt to manage arguments if necessary
+
+if len(sys.argv) < 3:
+    print('Usage: {0} <video-filename> <n-objects>'.format(sys.argv[0]))
+    sys.exit()
+
+if sys.argv[1].endswith('.avi'):
+    videoFilenamePrefix = utils.removeExtension(sys.argv[1],'.')
+else:
+    videoFilenamePrefix = sys.argv[1]
+
+objectNum = int(sys.argv[2])
+
+objects = ubc_utils.loadTrajectories(videoFilenamePrefix+'-objects.txt', objectNum+1)
+obj = objects[objectNum]
+features = ubc_utils.loadTrajectories(videoFilenamePrefix+'-features.txt', max(obj.featureNumbers)+1)
+h = np.loadtxt(videoFilenamePrefix+'-homography.txt')
+
+invh = cvutils.invertHomography(h)
+
+def computeGroundTrajectory(features, homography, timeInterval = None):
+    '''Computes a trajectory for the set of features as the closes point to the ground
+    using the homography in image space'''
+    if not timeInterval:
+        raise Exception('not implemented') # compute from the features
+    
+    yCoordinates = -np.ones((len(features),int(timeInterval.length())))
+    for i,f in enumerate(features):
+        traj = f.getPositions().asArray()
+        imgTraj = cvutils.projectArray(homography, traj)
+        yCoordinates[i,f.getFirstInstant()-timeInterval.first:f.getLastInstant()+1-timeInterval.first] = imgTraj[1,:]
+
+    indices = np.argmax(yCoordinates,0)
+    newTraj = moving.Trajectory()
+    for j,idx in enumerate(indices):
+        newTraj.addPosition(features[idx].getPositionAtInstant(j+timeInterval.first))
+        #newVelocities.addPosition(features[obj.featureNumbers[idx]].getVelocityAtInstant(j+obj.getFirstInstant()))
+
+    return newTraj
+
+def computeMedianTrajectory(features, timeInterval = None):
+    if not timeInterval:
+        raise Exception('not implemented') # compute from the features
+    
+    newTraj = moving.Trajectory()
+    for t in timeInterval:
+        points = []
+        for f in features:
+            if f.existsAtInstant(t):
+                points.append(f.getPositionAtInstant(t).aslist())
+        med = np.median(np.array(points), 0)
+        newTraj.addPositionXY(med[0], med[1])
+
+    return newTraj
+
+# TODO version median: conversion to large matrix will not work, have to do it frame by frame
+
+def kalmanFilter(positions, velocities, processNoiseCov, measurementNoiseCov):
+    kalman=cv.CreateKalman(6, 4)
+    kalman.transition_matrix[0,2]=1
+    kalman.transition_matrix[0,4]=1./2
+    kalman.transition_matrix[1,3]=1
+    kalman.transition_matrix[1,5]=1./2
+    kalman.transition_matrix[2,4]=1
+    kalman.transition_matrix[3,5]=1
+
+    cv.SetIdentity(kalman.measurement_matrix, 1.)
+    cv.SetIdentity(kalman.process_noise_cov, processNoiseCov)
+    cv.SetIdentity(kalman.measurement_noise_cov, measurementNoiseCov)
+    cv.SetIdentity(kalman.error_cov_post, 1.)
+
+    p = positions[0]
+    v = velocities[0]
+    v2 = velocities[2]
+    a = (v2-v).multiply(0.5)
+    kalman.state_post[0,0]=p.x
+    kalman.state_post[1,0]=p.y
+    kalman.state_post[2,0]=v.x
+    kalman.state_post[3,0]=v.y
+    kalman.state_post[4,0]=a.x
+    kalman.state_post[5,0]=a.y
+    
+    filteredPositions = moving.Trajectory()
+    filteredVelocities = moving.Trajectory()
+    measurement = cv.CreateMat(4,1,cv.CV_32FC1)
+    for i in xrange(positions.length()):
+        cv.KalmanPredict(kalman) # no control
+        p = positions[i]
+        v = velocities[i]
+        measurement[0,0] = p.x
+        measurement[1,0] = p.y
+        measurement[2,0] = v.x
+        measurement[3,0] = v.y
+        cv.KalmanCorrect(kalman, measurement)
+        filteredPositions.addPositionXY(kalman.state_post[0,0], kalman.state_post[1,0])
+        filteredVelocities.addPositionXY(kalman.state_post[2,0], kalman.state_post[3,0])
+
+    return (filteredPositions, filteredVelocities)
+
+groundTrajectory = computeGroundTrajectory([features[i] for i in obj.featureNumbers], invh, obj.getTimeInterval())
+(filteredPositions, filteredVelocities) = kalmanFilter(groundTrajectory, obj.getVelocities(), 0.1, 0.1)
+
+#medianTrajectory = computeMedianTrajectory([features[i] for i in obj.featureNumbers], obj.getTimeInterval())
+
+delta = []
+for t in obj.getTimeInterval():
+    p1 = obj.getPositionAtInstant(t)
+    p2 = groundTrajectory[t-obj.getFirstInstant()]
+    delta.append((p1-p2).aslist())
+
+delta = np.median(delta, 0)
+
+translated = moving.Trajectory()
+for t in obj.getTimeInterval():
+    p1 = obj.getPositionAtInstant(t)
+    p1.x -= delta[0]
+    p1.y -= delta[1]
+    translated.addPosition(p1)
+
+plt.clf()
+obj.draw('rx-')
+for fnum in obj.featureNumbers: features[fnum].draw()
+groundTrajectory.draw('bx-')
+filteredPositions.draw('gx-')
+translated.draw('kx-')
+#medianTrajectory.draw('kx-')
+plt.axis('equal')