This is the trajectory of a pedestrian moving in jam
As you can see, his/her head perform an oscillation-like movement. So not a perfect sinus curve but neither a line.
Is it possible to define for this irregular curve an "amplitude" and a "frequency"?
UPDATE :
So far I tried two different approaches:
The results are as follows:
The problem that I see with the RDP is the free parameter dist
. low values (means more details) imply oscillations in the resulting trajectories. So I'm forced to be careful with this parameter. Besides, the splin
ed curve is much more smoother.
What do you think?
There is no absolute correct way to do this. Below is just one way.
Let's start with the assumption/claim that people generally intend to walk in straight lines. So you could use the Ramer-Douglas-Peucker algorithm to estimate the intended path of the person with a small set of line segments. (There is a Python implementation of the algorithm here .)
Then generate the distances of the true data points from the line segments .
timeseries = []
for point in points:
timeseries.append(
min((distance between point and segment)
for segment in segments))
This array of distances is a timeseries. You could then take the root-mean-squared of the timeseries as a measure of amplitude, and take a Fourier transform to find its dominant frequency (or frequencies).
Here is an update to RDP module you were linked to that should work with Python 3.x using Vectors:
import functools
def autocast(function):
@functools.wraps(function)
def wrapper(self, other):
if isinstance(other, self.__class__):
if len(other) != len(self):
raise ValueError('Object dimensions are not equivalent!')
return function(self, other)
return function(self, self.__class__(size=len(self), init=other))
return wrapper
class Vector:
__slots__ = '__data'
def __init__(self, *args, size=0, init=0):
self.__data = list(map(float, args if args else [init] * size))
def __repr__(self):
return self.__class__.__name__ + repr(tuple(self))
@autocast
def __cmp__(self, other):
return (self.__data > other.__data) - (self.__data < other.__data)
def __lt__(self, other):
return self.__cmp__(other) < 0
def __le__(self, other):
return self.__cmp__(other) <= 0
def __eq__(self, other):
return self.__cmp__(other) == 0
def __ne__(self, other):
return self.__cmp__(other) != 0
def __gt__(self, other):
return self.__cmp__(other) > 0
def __ge__(self, other):
return self.__cmp__(other) >= 0
def __bool__(self):
return any(self)
def __len__(self):
return len(self.__data)
def __getitem__(self, key):
return self.__data[key]
def __setitem__(self, key, value):
self.__data[key] = float(value)
def __delitem__(self, key):
self[key] = 0
def __iter__(self):
return iter(self.__data)
def __reversed__(self):
return reversed(self.__data)
def __contains__(self, item):
return item in self.__data
@autocast
def __add__(self, other):
return Vector(*(a + b for a, b in zip(self, other)))
@autocast
def __sub__(self, other):
return Vector(*(a - b for a, b in zip(self, other)))
@autocast
def __mul__(self, other):
return Vector(*(a * b for a, b in zip(self, other)))
@autocast
def __truediv__(self, other):
return Vector(*(a / b for a, b in zip(self, other)))
@autocast
def __floordiv__(self, other):
return Vector(*(a // b for a, b in zip(self, other)))
@autocast
def __mod__(self, other):
return Vector(*(a % b for a, b in zip(self, other)))
@autocast
def __divmod__(self, other):
result = tuple(divmod(a, b) for a, b in zip(self, other))
return Vector(*(a for a, b in result)), Vector(*(b for a, b in result))
@autocast
def __pow__(self, other):
return Vector(*(a ** b for a, b in zip(self, other)))
@autocast
def __radd__(self, other):
return Vector(*(a + b for a, b in zip(other, self)))
@autocast
def __rsub__(self, other):
return Vector(*(a - b for a, b in zip(other, self)))
@autocast
def __rmul__(self, other):
return Vector(*(a * b for a, b in zip(other, self)))
@autocast
def __rtruediv__(self, other):
return Vector(*(a / b for a, b in zip(other, self)))
@autocast
def __rfloordiv__(self, other):
return Vector(*(a // b for a, b in zip(other, self)))
@autocast
def __rmod__(self, other):
return Vector(*(a % b for a, b in zip(other, self)))
@autocast
def __rdivmod__(self, other):
result = tuple(divmod(a, b) for a, b in zip(other, self))
return Vector(*(a for a, b in result)), Vector(*(b for a, b in result))
@autocast
def __rpow__(self, other):
return Vector(*(a ** b for a, b in zip(other, self)))
@autocast
def __iadd__(self, other):
for key in range(len(self)):
self[key] += other[key]
return self
@autocast
def __isub__(self, other):
for key in range(len(self)):
self[key] -= other[key]
return self
@autocast
def __imul__(self, other):
for key in range(len(self)):
self[key] *= other[key]
return self
@autocast
def __itruediv__(self, other):
for key in range(len(self)):
self[key] /= other[key]
return self
@autocast
def __ifloordiv__(self, other):
for key in range(len(self)):
self[key] //= other[key]
return self
@autocast
def __imod__(self, other):
for key in range(len(self)):
self[key] %= other[key]
return self
@autocast
def __ipow__(self, other):
for key in range(len(self)):
self[key] **= other[key]
return self
def __neg__(self):
return Vector(*(-value for value in self))
def __pos__(self):
return Vector(*(+value for value in self))
def __abs__(self):
return Vector(*(abs(value) for value in self))
def __get_magnitude(self):
return sum(value ** 2 for value in self) ** 0.5
def __set_magnitude(self, value):
self *= value / self.magnitude
magnitude = property(__get_magnitude, __set_magnitude)
###############################################################################
def point_line_distance(point, start, end):
if start == end:
return (point - start).magnitude
es, sp = end - start, start - point
return abs(es[0] * sp[1] - es[1] * sp[0]) / es.magnitude
def rdp(points, epsilon):
dmax = index = 0
start, *middle, end = points
for i in range(1, len(points) - 1):
d = point_line_distance(points[i], start, end)
if d > dmax:
index, dmax = i, d
if dmax >= epsilon:
return rdp(points[:index+1], epsilon)[:-1] + \
rdp(points[index:], epsilon)
return start, end
Similar to the demonstration given by the original module, the following is an example usage scenario:
>>> from pprint import pprint
>>> line = [Vector(0.0, 0.0),
Vector(1.0, 0.0),
Vector(2.0, 0.0),
Vector(2.0, 1.0),
Vector(2.0, 2.0),
Vector(1.0, 2.0),
Vector(0.0, 2.0),
Vector(0.0, 1.0),
Vector(0.0, 0.0)]
>>> pprint(rdp(line, 1.0))
(Vector(0.0, 0.0),
Vector(2.0, 0.0),
Vector(2.0, 2.0),
Vector(0.0, 2.0),
Vector(0.0, 0.0))
>>>
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.