Blame | Last modification | View Log | Download | RSS feed
#include "MovingPointTracker.h"MovingPointTracker::MovingPointTracker() {active_objects = 0;nextID = 0;}MovingPointTracker::~MovingPointTracker() {}float MovingPointTracker::pointDistance(cv::Point2f &pt1, cv::Point2f &pt2) {cv::Point2f diff = pt1 - pt2;return cv::sqrt(diff.x * diff.x + diff.y * diff.y);}std::vector<MOVING_OBJECT> MovingPointTracker::update(std::vector<cv::Point2f> points) {// Mark each existing object as invalidfor (int i = 0; i < objects.size(); i++) {objects[i].valid = false;}std::vector<MOVING_OBJECT> newObjects;// For each point, determine if it is an extension of an existing objectfor (int i = 0; i < points.size(); i++) {bool found = false;int index;for (index = 0; index < objects.size(); index++) {// Find the first object within the distance threshold// TODO: calculate all distances and use the closest one// TODO: handle case where multiple objects are merged into oneif (pointDistance(points[i], objects[index].last_known_pt) < OBJECT_DISTANCE_THRESHOLD) {found = true;break;}}if (found) {// If a match was found, update the objectobjects[index].valid = true;// Predict the next point using the Kalman filterobjects[index].filter->predict();objects[index].last_known_pt = points[i];objects[index].predicted_pt = objects[index].filter->correct(points[i].x, points[i].y);// Calculate the running averageobjects[index].history.push_front(objects[index].predicted_pt);if (objects[index].history.size() > HISTORY_DEPTH)objects[index].history.pop_back();float avgX = 0, avgY = 0;for (std::list<cv::Point2f>::iterator it = objects[index].history.begin(); it != objects[index].history.end(); it++) {avgX += (*it).x;avgY += (*it).y;}avgX /= objects[index].history.size();avgY /= objects[index].history.size();objects[index].historyAvg = cv::Point2f(avgX, avgY);// Calculate the updated velocity and angleobjects[index].velocity = pointDistance(objects[index].predicted_pt, objects[index].historyAvg);cv::Point2f diff = objects[index].predicted_pt - objects[index].historyAvg;objects[index].angle = atan2(diff.y, diff.x);} else {// If no matches were found, create a new objectMOVING_OBJECT newObject;newObject.ID = nextID;nextID++;newObject.last_known_pt = points[i];newObject.predicted_pt = points[i];newObject.velocity = 0;newObject.angle = 0;newObject.filter = new KalmanFilter(points[i].x, points[i].y);newObject.historyAvg = cv::Point2f(0, 0);newObjects.push_back(newObject);}}// If an object is invalid at this point, remove it//std::vector<MOVING_OBJECT> newObjects;for (int i = 0; i < objects.size(); i++) {if (objects[i].valid) {newObjects.push_back(objects[i]);}}objects = newObjects;return objects;}