first commit
This commit is contained in:
392
nodes/track/sort/Hungarian.cpp
Normal file
392
nodes/track/sort/Hungarian.cpp
Normal file
@@ -0,0 +1,392 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Hungarian.cpp: Implementation file for Class HungarianAlgorithm.
|
||||
//
|
||||
// This is a C++ wrapper with slight modification of a hungarian algorithm implementation by Markus Buehren.
|
||||
// The original implementation is a few mex-functions for use in MATLAB, found here:
|
||||
// http://www.mathworks.com/matlabcentral/fileexchange/6543-functions-for-the-rectangular-assignment-problem
|
||||
//
|
||||
// Both this code and the orignal code are published under the BSD license.
|
||||
// by Cong Ma, 2016
|
||||
//
|
||||
|
||||
#include "Hungarian.h"
|
||||
#include <cmath>
|
||||
#include <cfloat>
|
||||
HungarianAlgorithm::HungarianAlgorithm(){}
|
||||
HungarianAlgorithm::~HungarianAlgorithm(){}
|
||||
|
||||
|
||||
//********************************************************//
|
||||
// A single function wrapper for solving assignment problem.
|
||||
//********************************************************//
|
||||
double HungarianAlgorithm::Solve(vector<vector<double>>& DistMatrix, vector<int>& Assignment)
|
||||
{
|
||||
unsigned int nRows = DistMatrix.size();
|
||||
unsigned int nCols = DistMatrix[0].size();
|
||||
|
||||
double *distMatrixIn = new double[nRows * nCols];
|
||||
int *assignment = new int[nRows];
|
||||
double cost = 0.0;
|
||||
|
||||
// Fill in the distMatrixIn. Mind the index is "i + nRows * j".
|
||||
// Here the cost matrix of size MxN is defined as a double precision array of N*M elements.
|
||||
// In the solving functions matrices are seen to be saved MATLAB-internally in row-order.
|
||||
// (i.e. the matrix [1 2; 3 4] will be stored as a vector [1 3 2 4], NOT [1 2 3 4]).
|
||||
for (unsigned int i = 0; i < nRows; i++)
|
||||
for (unsigned int j = 0; j < nCols; j++)
|
||||
distMatrixIn[i + nRows * j] = DistMatrix[i][j];
|
||||
|
||||
// call solving function
|
||||
assignmentoptimal(assignment, &cost, distMatrixIn, nRows, nCols);
|
||||
|
||||
Assignment.clear();
|
||||
for (unsigned int r = 0; r < nRows; r++)
|
||||
Assignment.push_back(assignment[r]);
|
||||
|
||||
delete[] distMatrixIn;
|
||||
delete[] assignment;
|
||||
return cost;
|
||||
}
|
||||
|
||||
|
||||
//********************************************************//
|
||||
// Solve optimal solution for assignment problem using Munkres algorithm, also known as Hungarian Algorithm.
|
||||
//********************************************************//
|
||||
void HungarianAlgorithm::assignmentoptimal(int *assignment, double *cost, double *distMatrixIn, int nOfRows, int nOfColumns)
|
||||
{
|
||||
double *distMatrix, *distMatrixTemp, *distMatrixEnd, *columnEnd, value, minValue;
|
||||
bool *coveredColumns, *coveredRows, *starMatrix, *newStarMatrix, *primeMatrix;
|
||||
int nOfElements, minDim, row, col;
|
||||
|
||||
/* initialization */
|
||||
*cost = 0;
|
||||
for (row = 0; row<nOfRows; row++)
|
||||
assignment[row] = -1;
|
||||
|
||||
/* generate working copy of distance Matrix */
|
||||
/* check if all matrix elements are positive */
|
||||
nOfElements = nOfRows * nOfColumns;
|
||||
distMatrix = (double *)malloc(nOfElements * sizeof(double));
|
||||
distMatrixEnd = distMatrix + nOfElements;
|
||||
|
||||
for (row = 0; row<nOfElements; row++)
|
||||
{
|
||||
value = distMatrixIn[row];
|
||||
if (value < 0)
|
||||
cerr << "All matrix elements have to be non-negative." << endl;
|
||||
distMatrix[row] = value;
|
||||
}
|
||||
|
||||
|
||||
/* memory allocation */
|
||||
coveredColumns = (bool *)calloc(nOfColumns, sizeof(bool));
|
||||
coveredRows = (bool *)calloc(nOfRows, sizeof(bool));
|
||||
starMatrix = (bool *)calloc(nOfElements, sizeof(bool));
|
||||
primeMatrix = (bool *)calloc(nOfElements, sizeof(bool));
|
||||
newStarMatrix = (bool *)calloc(nOfElements, sizeof(bool)); /* used in step4 */
|
||||
|
||||
/* preliminary steps */
|
||||
if (nOfRows <= nOfColumns)
|
||||
{
|
||||
minDim = nOfRows;
|
||||
|
||||
for (row = 0; row<nOfRows; row++)
|
||||
{
|
||||
/* find the smallest element in the row */
|
||||
distMatrixTemp = distMatrix + row;
|
||||
minValue = *distMatrixTemp;
|
||||
distMatrixTemp += nOfRows;
|
||||
while (distMatrixTemp < distMatrixEnd)
|
||||
{
|
||||
value = *distMatrixTemp;
|
||||
if (value < minValue)
|
||||
minValue = value;
|
||||
distMatrixTemp += nOfRows;
|
||||
}
|
||||
|
||||
/* subtract the smallest element from each element of the row */
|
||||
distMatrixTemp = distMatrix + row;
|
||||
while (distMatrixTemp < distMatrixEnd)
|
||||
{
|
||||
*distMatrixTemp -= minValue;
|
||||
distMatrixTemp += nOfRows;
|
||||
}
|
||||
}
|
||||
|
||||
/* Steps 1 and 2a */
|
||||
for (row = 0; row<nOfRows; row++)
|
||||
for (col = 0; col<nOfColumns; col++)
|
||||
if (fabs(distMatrix[row + nOfRows*col]) < DBL_EPSILON)
|
||||
if (!coveredColumns[col])
|
||||
{
|
||||
starMatrix[row + nOfRows*col] = true;
|
||||
coveredColumns[col] = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else /* if(nOfRows > nOfColumns) */
|
||||
{
|
||||
minDim = nOfColumns;
|
||||
|
||||
for (col = 0; col<nOfColumns; col++)
|
||||
{
|
||||
/* find the smallest element in the column */
|
||||
distMatrixTemp = distMatrix + nOfRows*col;
|
||||
columnEnd = distMatrixTemp + nOfRows;
|
||||
|
||||
minValue = *distMatrixTemp++;
|
||||
while (distMatrixTemp < columnEnd)
|
||||
{
|
||||
value = *distMatrixTemp++;
|
||||
if (value < minValue)
|
||||
minValue = value;
|
||||
}
|
||||
|
||||
/* subtract the smallest element from each element of the column */
|
||||
distMatrixTemp = distMatrix + nOfRows*col;
|
||||
while (distMatrixTemp < columnEnd)
|
||||
*distMatrixTemp++ -= minValue;
|
||||
}
|
||||
|
||||
/* Steps 1 and 2a */
|
||||
for (col = 0; col<nOfColumns; col++)
|
||||
for (row = 0; row<nOfRows; row++)
|
||||
if (fabs(distMatrix[row + nOfRows*col]) < DBL_EPSILON)
|
||||
if (!coveredRows[row])
|
||||
{
|
||||
starMatrix[row + nOfRows*col] = true;
|
||||
coveredColumns[col] = true;
|
||||
coveredRows[row] = true;
|
||||
break;
|
||||
}
|
||||
for (row = 0; row<nOfRows; row++)
|
||||
coveredRows[row] = false;
|
||||
|
||||
}
|
||||
|
||||
/* move to step 2b */
|
||||
step2b(assignment, distMatrix, starMatrix, newStarMatrix, primeMatrix, coveredColumns, coveredRows, nOfRows, nOfColumns, minDim);
|
||||
|
||||
/* compute cost and remove invalid assignments */
|
||||
computeassignmentcost(assignment, cost, distMatrixIn, nOfRows);
|
||||
|
||||
/* free allocated memory */
|
||||
free(distMatrix);
|
||||
free(coveredColumns);
|
||||
free(coveredRows);
|
||||
free(starMatrix);
|
||||
free(primeMatrix);
|
||||
free(newStarMatrix);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/********************************************************/
|
||||
void HungarianAlgorithm::buildassignmentvector(int *assignment, bool *starMatrix, int nOfRows, int nOfColumns)
|
||||
{
|
||||
int row, col;
|
||||
|
||||
for (row = 0; row<nOfRows; row++)
|
||||
for (col = 0; col<nOfColumns; col++)
|
||||
if (starMatrix[row + nOfRows*col])
|
||||
{
|
||||
#ifdef ONE_INDEXING
|
||||
assignment[row] = col + 1; /* MATLAB-Indexing */
|
||||
#else
|
||||
assignment[row] = col;
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/********************************************************/
|
||||
void HungarianAlgorithm::computeassignmentcost(int *assignment, double *cost, double *distMatrix, int nOfRows)
|
||||
{
|
||||
int row, col;
|
||||
|
||||
for (row = 0; row<nOfRows; row++)
|
||||
{
|
||||
col = assignment[row];
|
||||
if (col >= 0)
|
||||
*cost += distMatrix[row + nOfRows*col];
|
||||
}
|
||||
}
|
||||
|
||||
/********************************************************/
|
||||
void HungarianAlgorithm::step2a(int *assignment, double *distMatrix, bool *starMatrix, bool *newStarMatrix, bool *primeMatrix, bool *coveredColumns, bool *coveredRows, int nOfRows, int nOfColumns, int minDim)
|
||||
{
|
||||
bool *starMatrixTemp, *columnEnd;
|
||||
int col;
|
||||
|
||||
/* cover every column containing a starred zero */
|
||||
for (col = 0; col<nOfColumns; col++)
|
||||
{
|
||||
starMatrixTemp = starMatrix + nOfRows*col;
|
||||
columnEnd = starMatrixTemp + nOfRows;
|
||||
while (starMatrixTemp < columnEnd){
|
||||
if (*starMatrixTemp++)
|
||||
{
|
||||
coveredColumns[col] = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* move to step 3 */
|
||||
step2b(assignment, distMatrix, starMatrix, newStarMatrix, primeMatrix, coveredColumns, coveredRows, nOfRows, nOfColumns, minDim);
|
||||
}
|
||||
|
||||
/********************************************************/
|
||||
void HungarianAlgorithm::step2b(int *assignment, double *distMatrix, bool *starMatrix, bool *newStarMatrix, bool *primeMatrix, bool *coveredColumns, bool *coveredRows, int nOfRows, int nOfColumns, int minDim)
|
||||
{
|
||||
int col, nOfCoveredColumns;
|
||||
|
||||
/* count covered columns */
|
||||
nOfCoveredColumns = 0;
|
||||
for (col = 0; col<nOfColumns; col++)
|
||||
if (coveredColumns[col])
|
||||
nOfCoveredColumns++;
|
||||
|
||||
if (nOfCoveredColumns == minDim)
|
||||
{
|
||||
/* algorithm finished */
|
||||
buildassignmentvector(assignment, starMatrix, nOfRows, nOfColumns);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* move to step 3 */
|
||||
step3(assignment, distMatrix, starMatrix, newStarMatrix, primeMatrix, coveredColumns, coveredRows, nOfRows, nOfColumns, minDim);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/********************************************************/
|
||||
void HungarianAlgorithm::step3(int *assignment, double *distMatrix, bool *starMatrix, bool *newStarMatrix, bool *primeMatrix, bool *coveredColumns, bool *coveredRows, int nOfRows, int nOfColumns, int minDim)
|
||||
{
|
||||
bool zerosFound;
|
||||
int row, col, starCol;
|
||||
|
||||
zerosFound = true;
|
||||
while (zerosFound)
|
||||
{
|
||||
zerosFound = false;
|
||||
for (col = 0; col<nOfColumns; col++)
|
||||
if (!coveredColumns[col])
|
||||
for (row = 0; row<nOfRows; row++)
|
||||
if ((!coveredRows[row]) && (fabs(distMatrix[row + nOfRows*col]) < DBL_EPSILON))
|
||||
{
|
||||
/* prime zero */
|
||||
primeMatrix[row + nOfRows*col] = true;
|
||||
|
||||
/* find starred zero in current row */
|
||||
for (starCol = 0; starCol<nOfColumns; starCol++)
|
||||
if (starMatrix[row + nOfRows*starCol])
|
||||
break;
|
||||
|
||||
if (starCol == nOfColumns) /* no starred zero found */
|
||||
{
|
||||
/* move to step 4 */
|
||||
step4(assignment, distMatrix, starMatrix, newStarMatrix, primeMatrix, coveredColumns, coveredRows, nOfRows, nOfColumns, minDim, row, col);
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
coveredRows[row] = true;
|
||||
coveredColumns[starCol] = false;
|
||||
zerosFound = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* move to step 5 */
|
||||
step5(assignment, distMatrix, starMatrix, newStarMatrix, primeMatrix, coveredColumns, coveredRows, nOfRows, nOfColumns, minDim);
|
||||
}
|
||||
|
||||
/********************************************************/
|
||||
void HungarianAlgorithm::step4(int *assignment, double *distMatrix, bool *starMatrix, bool *newStarMatrix, bool *primeMatrix, bool *coveredColumns, bool *coveredRows, int nOfRows, int nOfColumns, int minDim, int row, int col)
|
||||
{
|
||||
int n, starRow, starCol, primeRow, primeCol;
|
||||
int nOfElements = nOfRows*nOfColumns;
|
||||
|
||||
/* generate temporary copy of starMatrix */
|
||||
for (n = 0; n<nOfElements; n++)
|
||||
newStarMatrix[n] = starMatrix[n];
|
||||
|
||||
/* star current zero */
|
||||
newStarMatrix[row + nOfRows*col] = true;
|
||||
|
||||
/* find starred zero in current column */
|
||||
starCol = col;
|
||||
for (starRow = 0; starRow<nOfRows; starRow++)
|
||||
if (starMatrix[starRow + nOfRows*starCol])
|
||||
break;
|
||||
|
||||
while (starRow<nOfRows)
|
||||
{
|
||||
/* unstar the starred zero */
|
||||
newStarMatrix[starRow + nOfRows*starCol] = false;
|
||||
|
||||
/* find primed zero in current row */
|
||||
primeRow = starRow;
|
||||
for (primeCol = 0; primeCol<nOfColumns; primeCol++)
|
||||
if (primeMatrix[primeRow + nOfRows*primeCol])
|
||||
break;
|
||||
|
||||
/* star the primed zero */
|
||||
newStarMatrix[primeRow + nOfRows*primeCol] = true;
|
||||
|
||||
/* find starred zero in current column */
|
||||
starCol = primeCol;
|
||||
for (starRow = 0; starRow<nOfRows; starRow++)
|
||||
if (starMatrix[starRow + nOfRows*starCol])
|
||||
break;
|
||||
}
|
||||
|
||||
/* use temporary copy as new starMatrix */
|
||||
/* delete all primes, uncover all rows */
|
||||
for (n = 0; n<nOfElements; n++)
|
||||
{
|
||||
primeMatrix[n] = false;
|
||||
starMatrix[n] = newStarMatrix[n];
|
||||
}
|
||||
for (n = 0; n<nOfRows; n++)
|
||||
coveredRows[n] = false;
|
||||
|
||||
/* move to step 2a */
|
||||
step2a(assignment, distMatrix, starMatrix, newStarMatrix, primeMatrix, coveredColumns, coveredRows, nOfRows, nOfColumns, minDim);
|
||||
}
|
||||
|
||||
/********************************************************/
|
||||
void HungarianAlgorithm::step5(int *assignment, double *distMatrix, bool *starMatrix, bool *newStarMatrix, bool *primeMatrix, bool *coveredColumns, bool *coveredRows, int nOfRows, int nOfColumns, int minDim)
|
||||
{
|
||||
double h, value;
|
||||
int row, col;
|
||||
|
||||
/* find smallest uncovered element h */
|
||||
h = DBL_MAX;
|
||||
for (row = 0; row<nOfRows; row++)
|
||||
if (!coveredRows[row])
|
||||
for (col = 0; col<nOfColumns; col++)
|
||||
if (!coveredColumns[col])
|
||||
{
|
||||
value = distMatrix[row + nOfRows*col];
|
||||
if (value < h)
|
||||
h = value;
|
||||
}
|
||||
|
||||
/* add h to each covered row */
|
||||
for (row = 0; row<nOfRows; row++)
|
||||
if (coveredRows[row])
|
||||
for (col = 0; col<nOfColumns; col++)
|
||||
distMatrix[row + nOfRows*col] += h;
|
||||
|
||||
/* subtract h from each uncovered column */
|
||||
for (col = 0; col<nOfColumns; col++)
|
||||
if (!coveredColumns[col])
|
||||
for (row = 0; row<nOfRows; row++)
|
||||
distMatrix[row + nOfRows*col] -= h;
|
||||
|
||||
/* move to step 3 */
|
||||
step3(assignment, distMatrix, starMatrix, newStarMatrix, primeMatrix, coveredColumns, coveredRows, nOfRows, nOfColumns, minDim);
|
||||
}
|
||||
34
nodes/track/sort/Hungarian.h
Normal file
34
nodes/track/sort/Hungarian.h
Normal file
@@ -0,0 +1,34 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Hungarian.h: Header file for Class HungarianAlgorithm.
|
||||
//
|
||||
// This is a C++ wrapper with slight modification of a hungarian algorithm implementation by Markus Buehren.
|
||||
// The original implementation is a few mex-functions for use in MATLAB, found here:
|
||||
// http://www.mathworks.com/matlabcentral/fileexchange/6543-functions-for-the-rectangular-assignment-problem
|
||||
//
|
||||
// Both this code and the orignal code are published under the BSD license.
|
||||
// by Cong Ma, 2016
|
||||
//
|
||||
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
|
||||
using namespace std;
|
||||
|
||||
|
||||
class HungarianAlgorithm
|
||||
{
|
||||
public:
|
||||
HungarianAlgorithm();
|
||||
~HungarianAlgorithm();
|
||||
double Solve(vector<vector<double>>& DistMatrix, vector<int>& Assignment);
|
||||
|
||||
private:
|
||||
void assignmentoptimal(int *assignment, double *cost, double *distMatrix, int nOfRows, int nOfColumns);
|
||||
void buildassignmentvector(int *assignment, bool *starMatrix, int nOfRows, int nOfColumns);
|
||||
void computeassignmentcost(int *assignment, double *cost, double *distMatrix, int nOfRows);
|
||||
void step2a(int *assignment, double *distMatrix, bool *starMatrix, bool *newStarMatrix, bool *primeMatrix, bool *coveredColumns, bool *coveredRows, int nOfRows, int nOfColumns, int minDim);
|
||||
void step2b(int *assignment, double *distMatrix, bool *starMatrix, bool *newStarMatrix, bool *primeMatrix, bool *coveredColumns, bool *coveredRows, int nOfRows, int nOfColumns, int minDim);
|
||||
void step3(int *assignment, double *distMatrix, bool *starMatrix, bool *newStarMatrix, bool *primeMatrix, bool *coveredColumns, bool *coveredRows, int nOfRows, int nOfColumns, int minDim);
|
||||
void step4(int *assignment, double *distMatrix, bool *starMatrix, bool *newStarMatrix, bool *primeMatrix, bool *coveredColumns, bool *coveredRows, int nOfRows, int nOfColumns, int minDim, int row, int col);
|
||||
void step5(int *assignment, double *distMatrix, bool *starMatrix, bool *newStarMatrix, bool *primeMatrix, bool *coveredColumns, bool *coveredRows, int nOfRows, int nOfColumns, int minDim);
|
||||
};
|
||||
176
nodes/track/sort/KalmanTracker.cpp
Normal file
176
nodes/track/sort/KalmanTracker.cpp
Normal file
@@ -0,0 +1,176 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// KalmanTracker.cpp: KalmanTracker Class Implementation Declaration
|
||||
|
||||
#include "KalmanTracker.h"
|
||||
|
||||
|
||||
int KalmanTracker::kf_count = 0;
|
||||
|
||||
|
||||
// initialize Kalman filter
|
||||
void KalmanTracker::init_kf(StateType stateMat)
|
||||
{
|
||||
int stateNum = 7;
|
||||
int measureNum = 4;
|
||||
kf = KalmanFilter(stateNum, measureNum, 0);
|
||||
|
||||
measurement = cv::Mat::zeros(measureNum, 1, CV_32F);
|
||||
|
||||
kf.transitionMatrix = (cv::Mat_<float>(stateNum, stateNum) << 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1);
|
||||
|
||||
setIdentity(kf.measurementMatrix);
|
||||
setIdentity(kf.processNoiseCov, Scalar::all(1e-2));
|
||||
setIdentity(kf.measurementNoiseCov, Scalar::all(1e-1));
|
||||
setIdentity(kf.errorCovPost, Scalar::all(1));
|
||||
|
||||
// initialize state vector with bounding box in [cx,cy,s,r] style
|
||||
kf.statePost.at<float>(0, 0) = stateMat.x + stateMat.width / 2;
|
||||
kf.statePost.at<float>(1, 0) = stateMat.y + stateMat.height / 2;
|
||||
kf.statePost.at<float>(2, 0) = stateMat.area();
|
||||
kf.statePost.at<float>(3, 0) = stateMat.width / stateMat.height;
|
||||
}
|
||||
|
||||
|
||||
// Predict the estimated bounding box.
|
||||
StateType KalmanTracker::predict()
|
||||
{
|
||||
// predict
|
||||
Mat p = kf.predict();
|
||||
m_age += 1;
|
||||
|
||||
if (m_time_since_update > 0)
|
||||
m_hit_streak = 0;
|
||||
m_time_since_update += 1;
|
||||
|
||||
StateType predictBox = get_rect_xysr(p.at<float>(0, 0), p.at<float>(1, 0), p.at<float>(2, 0), p.at<float>(3, 0));
|
||||
|
||||
m_history.push_back(predictBox);
|
||||
return m_history.back();
|
||||
}
|
||||
|
||||
|
||||
// Update the state vector with observed bounding box.
|
||||
void KalmanTracker::update(StateType stateMat)
|
||||
{
|
||||
m_time_since_update = 0;
|
||||
m_history.clear();
|
||||
m_hits += 1;
|
||||
m_hit_streak += 1;
|
||||
|
||||
// measurement
|
||||
measurement.at<float>(0, 0) = stateMat.x + stateMat.width / 2;
|
||||
measurement.at<float>(1, 0) = stateMat.y + stateMat.height / 2;
|
||||
measurement.at<float>(2, 0) = stateMat.area();
|
||||
measurement.at<float>(3, 0) = stateMat.width / stateMat.height;
|
||||
|
||||
// update
|
||||
kf.correct(measurement);
|
||||
}
|
||||
|
||||
|
||||
// Return the current state vector
|
||||
StateType KalmanTracker::get_state()
|
||||
{
|
||||
Mat s = kf.statePost;
|
||||
return get_rect_xysr(s.at<float>(0, 0), s.at<float>(1, 0), s.at<float>(2, 0), s.at<float>(3, 0));
|
||||
}
|
||||
|
||||
|
||||
// Convert bounding box from [cx,cy,s,r] to [x,y,w,h] style.
|
||||
StateType KalmanTracker::get_rect_xysr(float cx, float cy, float s, float r)
|
||||
{
|
||||
float w = sqrt(s * r);
|
||||
float h = s / w;
|
||||
float x = (cx - w / 2);
|
||||
float y = (cy - h / 2);
|
||||
|
||||
if (x < 0 && cx > 0)
|
||||
x = 0;
|
||||
if (y < 0 && cy > 0)
|
||||
y = 0;
|
||||
|
||||
return StateType(x, y, w, h);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
// --------------------------------------------------------------------
|
||||
// Kalman Filter Demonstrating, a 2-d ball demo
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
const int winHeight = 600;
|
||||
const int winWidth = 800;
|
||||
|
||||
Point mousePosition = Point(winWidth >> 1, winHeight >> 1);
|
||||
|
||||
// mouse event callback
|
||||
void mouseEvent(int event, int x, int y, int flags, void *param)
|
||||
{
|
||||
if (event == CV_EVENT_MOUSEMOVE) {
|
||||
mousePosition = Point(x, y);
|
||||
}
|
||||
}
|
||||
|
||||
void TestKF();
|
||||
|
||||
void main()
|
||||
{
|
||||
TestKF();
|
||||
}
|
||||
|
||||
|
||||
void TestKF()
|
||||
{
|
||||
int stateNum = 4;
|
||||
int measureNum = 2;
|
||||
KalmanFilter kf = KalmanFilter(stateNum, measureNum, 0);
|
||||
|
||||
// initialization
|
||||
Mat processNoise(stateNum, 1, CV_32F);
|
||||
Mat measurement = Mat::zeros(measureNum, 1, CV_32F);
|
||||
|
||||
kf.transitionMatrix = *(Mat_<float>(stateNum, stateNum) <<
|
||||
1, 0, 1, 0,
|
||||
0, 1, 0, 1,
|
||||
0, 0, 1, 0,
|
||||
0, 0, 0, 1);
|
||||
|
||||
setIdentity(kf.measurementMatrix);
|
||||
setIdentity(kf.processNoiseCov, Scalar::all(1e-2));
|
||||
setIdentity(kf.measurementNoiseCov, Scalar::all(1e-1));
|
||||
setIdentity(kf.errorCovPost, Scalar::all(1));
|
||||
|
||||
randn(kf.statePost, Scalar::all(0), Scalar::all(winHeight));
|
||||
|
||||
namedWindow("Kalman");
|
||||
setMouseCallback("Kalman", mouseEvent);
|
||||
Mat img(winHeight, winWidth, CV_8UC3);
|
||||
|
||||
while (1)
|
||||
{
|
||||
// predict
|
||||
Mat prediction = kf.predict();
|
||||
Point predictPt = Point(prediction.at<float>(0, 0), prediction.at<float>(1, 0));
|
||||
|
||||
// generate measurement
|
||||
Point statePt = mousePosition;
|
||||
measurement.at<float>(0, 0) = statePt.x;
|
||||
measurement.at<float>(1, 0) = statePt.y;
|
||||
|
||||
// update
|
||||
kf.correct(measurement);
|
||||
|
||||
// visualization
|
||||
img.setTo(Scalar(255, 255, 255));
|
||||
circle(img, predictPt, 8, CV_RGB(0, 255, 0), -1); // predicted point as green
|
||||
circle(img, statePt, 8, CV_RGB(255, 0, 0), -1); // current position as red
|
||||
|
||||
imshow("Kalman", img);
|
||||
char code = (char)waitKey(100);
|
||||
if (code == 27 || code == 'q' || code == 'Q')
|
||||
break;
|
||||
}
|
||||
destroyWindow("Kalman");
|
||||
}
|
||||
*/
|
||||
72
nodes/track/sort/KalmanTracker.h
Normal file
72
nodes/track/sort/KalmanTracker.h
Normal file
@@ -0,0 +1,72 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// KalmanTracker.h: KalmanTracker Class Declaration
|
||||
|
||||
#ifndef KALMAN_H
|
||||
#define KALMAN_H 2
|
||||
|
||||
#include "opencv2/video/tracking.hpp"
|
||||
#include "opencv2/highgui/highgui.hpp"
|
||||
|
||||
using namespace std;
|
||||
using namespace cv;
|
||||
|
||||
#define StateType Rect_<float>
|
||||
|
||||
|
||||
// This class represents the internel state of individual tracked objects observed as bounding box.
|
||||
class KalmanTracker
|
||||
{
|
||||
public:
|
||||
KalmanTracker()
|
||||
{
|
||||
init_kf(StateType());
|
||||
m_time_since_update = 0;
|
||||
m_hits = 0;
|
||||
m_hit_streak = 0;
|
||||
m_age = 0;
|
||||
m_id = kf_count;
|
||||
//kf_count++;
|
||||
}
|
||||
KalmanTracker(StateType initRect)
|
||||
{
|
||||
init_kf(initRect);
|
||||
m_time_since_update = 0;
|
||||
m_hits = 0;
|
||||
m_hit_streak = 0;
|
||||
m_age = 0;
|
||||
m_id = kf_count;
|
||||
kf_count++;
|
||||
}
|
||||
|
||||
~KalmanTracker()
|
||||
{
|
||||
m_history.clear();
|
||||
}
|
||||
|
||||
StateType predict();
|
||||
void update(StateType stateMat);
|
||||
|
||||
StateType get_state();
|
||||
StateType get_rect_xysr(float cx, float cy, float s, float r);
|
||||
|
||||
static int kf_count;
|
||||
|
||||
int m_time_since_update;
|
||||
int m_hits;
|
||||
int m_hit_streak;
|
||||
int m_age;
|
||||
int m_id;
|
||||
|
||||
private:
|
||||
void init_kf(StateType stateMat);
|
||||
|
||||
cv::KalmanFilter kf;
|
||||
cv::Mat measurement;
|
||||
|
||||
std::vector<StateType> m_history;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
6
nodes/track/sort/README.md
Normal file
6
nodes/track/sort/README.md
Normal file
@@ -0,0 +1,6 @@
|
||||
|
||||
|
||||
summary
|
||||
-----------
|
||||
|
||||
sort algorithm for tracking
|
||||
Reference in New Issue
Block a user