I use this code to track object from findContour method.
public class Tracker extends JTracker {
int nextTractID = 0;
Vector<Integer> assignment = new Vector<>();
int count1;
int count2;
int count3;
int count4;
double posx;
double posy;
int matchId;
Point pt1;
Point pt2;
int trackId;
static ArrayList<Integer> trackIds = new ArrayList<>();
static Point p0 = new Point(0, 0);
static ArrayList<Point> pointArray0 = new ArrayList<>();
static Point p1;
static ArrayList<Point> pointArray1 = new ArrayList<>();
static Point p2;
static ArrayList<Point> pointArray2 = new ArrayList<>();
static Point p3;
static ArrayList<Point> pointArray3 = new ArrayList<>();
static Point p4;
static ArrayList<Point> pointArray4 = new ArrayList<>();
static Point p5;
static ArrayList<Point> pointArray5 = new ArrayList<>();
static Point p6;
static ArrayList<Point> pointArray6 = new ArrayList<>();
static Point p7;
static ArrayList<Point> pointArray7 = new ArrayList<>();
static Point p8;
static ArrayList<Point> pointArray8 = new ArrayList<>();
static Point p9;
static ArrayList<Point> pointArray9 = new ArrayList<>();
static Point p10;
static ArrayList<Point> pointArray10 = new ArrayList<>();
static Point p11;
static ArrayList<Point> pointArray11 = new ArrayList<>();
static Point p12;
static ArrayList<Point> pointArray12 = new ArrayList<>();
static Point p13;
static ArrayList<Point> pointArray13 = new ArrayList<>();
static Point p14;
static ArrayList<Point> pointArray14 = new ArrayList<>();
static Point p15;
static ArrayList<Point> pointArray15 = new ArrayList<>();
static Point p16;
static ArrayList<Point> pointArray16 = new ArrayList<>();
static Point p17;
static ArrayList<Point> pointArray17 = new ArrayList<>();
static Point p18;
static ArrayList<Point> pointArray18 = new ArrayList<>();
static Point p19;
static ArrayList<Point> pointArray19 = new ArrayList<>();
static Point p20;
static ArrayList<Point> pointArray20 = new ArrayList<>();
static Point p21;
static ArrayList<Point> pointArray21 = new ArrayList<>();
static Point p22;
static ArrayList<Point> pointArray22 = new ArrayList<>();
static Point p23;
static ArrayList<Point> pointArray23 = new ArrayList<>();
Vector<Rect> rectArray;
Mat imag;
public Point getPt1() {
return pt1;
}
public void setPt1(Point pt1) {
this.pt1 = pt1;
}
public Point getPt2() {
return pt2;
}
public void setPt2(Point pt2) {
this.pt2 = pt2;
}
public int getTrackId() {
return trackId;
}
public void setTrackId(int trackId) {
this.trackId = trackId;
}
public int getMatchId() {
return matchId;
}
public void setMatchId(int matchId) {
this.matchId = matchId;
}
public double getPosx() {
return posx;
}
public void setPosx(double posx) {
this.posx = posx;
}
public double getPosy() {
return posy;
}
public void setPosy(double posy) {
this.posy = posy;
}
public Tracker(float _dt, float _Accel_noise_mag, double _dist_thres,
int _maximum_allowed_skipped_frames, int _max_trace_length) {
tracks = new Vector<>();
dt = _dt;
Accel_noise_mag = _Accel_noise_mag;
dist_thres = _dist_thres;
maximum_allowed_skipped_frames = _maximum_allowed_skipped_frames;
max_trace_length = _max_trace_length;
track_removed = 0;
}
static Scalar Colors[] = {new Scalar(255, 0, 0), new Scalar(0, 255, 0),
new Scalar(0, 0, 255), new Scalar(255, 255, 0),
new Scalar(0, 255, 255), new Scalar(255, 0, 255),
new Scalar(255, 127, 255), new Scalar(127, 0, 255),
new Scalar(127, 0, 127)};
double euclideanDist(Point p, Point q) {
Point diff = new Point(p.x - q.x, p.y - q.y);
return Math.sqrt(diff.x * diff.x + diff.y * diff.y);
}
public void update(Vector<Rect> rectArray, Vector<Point> detections, Mat imag) {
this.rectArray = rectArray;
this.imag = imag;
if (tracks.size() == 0) {
// If no tracks yet
for (int i = 0; i < detections.size(); i++) {
Track tr = new Track(detections.get(i), dt,
Accel_noise_mag, nextTractID++);
tracks.add(tr);
}
}
// -----------------------------------
// Number of tracks and detections
// -----------------------------------
int N = tracks.size();
int M = detections.size();
// Cost matrix.
double[][] Cost = new double[N][M]; // size: N, M
// Vector<Integer> assignment = new Vector<>(); // assignment according to Hungarian algorithm
assignment.clear();
// -----------------------------------
// Caculate cost matrix (distances)
// -----------------------------------
for (int i = 0; i < tracks.size(); i++) {
for (int j = 0; j < detections.size(); j++) {
Cost[i][j] = euclideanDist(tracks.get(i).prediction, detections.get(j));
}
}
// -----------------------------------
// Solving assignment problem (tracks and predictions of Kalman filter)
// -----------------------------------
// HungarianAlg APS = new HungarianAlg();
// APS.Solve(Cost,assignment, HungarianAlg.TMethod.optimal);
// HungarianAlg2 APS = new HungarianAlg2();
// APS.Solve(Cost,assignment);
AssignmentOptimal APS = new AssignmentOptimal();
APS.Solve(Cost, assignment);
// -----------------------------------
// clean assignment from pairs with large distance
// -----------------------------------
// Not assigned tracks
Vector<Integer> not_assigned_tracks = new Vector<>();
for (int i = 0; i < assignment.size(); i++) {
if (assignment.get(i) != -1) {
if (Cost[i][assignment.get(i)] > dist_thres) {
assignment.set(i, -1);
// Mark unassigned tracks, and increment skipped frames
// counter,
// when skipped frames counter will be larger than
// threshold, track will be deleted.
not_assigned_tracks.add(i);
}
} else {
// If track have no assigned detect, then increment skipped
// frames counter.
tracks.get(i).skipped_frames++;
//not_assigned_tracks.add(i);
}
}
// -----------------------------------
// If track didn't get detects long time, remove it.
// -----------------------------------
/*for (int i = 0; i < tracks.size(); i++) {
if (tracks.get(i).skipped_frames > maximum_allowed_skipped_frames) {
tracks.remove(i);
assignment.remove(i);
track_removed++;
i--;
}
}*/
// -----------------------------------
// Search for unassigned detects
// -----------------------------------
Vector<Integer> not_assigned_detections = new Vector<>();
Vector<Integer> assigned_id = new Vector<>();
if (tracks.size() <= 23) {
for (int i = 0; i < detections.size(); i++) {
if (!assignment.contains(i)) { //New track
not_assigned_detections.add(i);
} else {
assigned_id.add(i);
}
}
}
//System.out.println("Assign ID:"+assigned_id);
//System.out.println("Not Assign:"+not_assigned_detections);
//System.out.println("Not Assign Track:"+not_assigned_tracks);
// -----------------------------------
// and start new tracks for them.
// -----------------------------------
if (not_assigned_detections.size() > 0) {
for (Integer not_assigned_detection : not_assigned_detections) {
Track tr = new Track(detections.get(not_assigned_detection), dt, Accel_noise_mag, nextTractID++);
tracks.add(tr);
trackIds.add(nextTractID);
}
}
// Update Kalman Filters state
updateKalman(imag, detections);
for (int j = 0; j < assignment.size(); j++) {
if (assignment.get(j) != -1) {
pt1 = new Point(
(int) ((rectArray.get(assignment.get(j)).tl().x + rectArray
.get(assignment.get(j)).br().x) / 2), rectArray
.get(assignment.get(j)).br().y);
pt2 = new Point(
(int) ((rectArray.get(assignment.get(j)).tl().x + rectArray
.get(assignment.get(j)).br().x) / 2), rectArray
.get(assignment.get(j)).tl().y);
//show ID
Imgproc.putText(imag, tracks.get(j).track_id + "", pt2,
2 * Core.FONT_HERSHEY_PLAIN, 1, new Scalar(255, 255,
255), 1);
//setTrackId(tracks.get(j).track_id);
//Show ID,(x,y)
/*Imgproc.putText(imag, tracks.get(j).track_id + "" + "(" + rectArray
.get(assignment.get(j)).br().x + "," + rectArray
.get(assignment.get(j)).br().y +")" , pt2,
2 * Core.FONT_HERSHEY_PLAIN, 1, new Scalar(255, 255,
255), 1);*/
if (tracks.get(j).history.size() < 100) {
tracks.get(j).history.add(pt1);
} else {
tracks.get(j).history.remove(0);
tracks.get(j).history.add(pt1);
}
double x = pt2.x;
double y = pt2.y;
setPosx(x);
setPosy(y);
//System.out.println("Track ID: "+tracks.get(j).track_id + pt2 + pt1 ); //Track ID , Point
//System.out.println("p0:"+p0 + ", pt2:"+pt2+" ,ID:" + tracks.get(j).track_id+ " " +(pt2.x - p0.x)+ " :: " + (pt2.y - p0.y));
//if (pt2.x > 20 & pt2.x < 940) {
if (tracks.get(j).track_id == 0) { //& ((pt2.x - p0.x)<=5 | (pt2.x - p0.x)>= -5) & ((pt2.y - p0.y)<=5 | (pt2.y - p0.y)>= -5)){
p0 = pt2;
double dist = euclideanDist(tracks.get(j).trace.get(tracks.get(j).trace.size() - 1), p0);
pointArray0.add(p0);
//System.out.println("Point1:"+p0);
//System.out.println(tracks.get(j).trace.get(tracks.get(j).trace.size()-1));
//System.out.println("Dist:"+dist);//Insert(0, pt2.x, pt2.y,dist);
}
if (tracks.get(j).track_id == 1) {
p1 = pt2;
double dist = euclideanDist(tracks.get(j).trace.get(tracks.get(j).trace.size() - 1), p1);
pointArray1.add(p1);
//Main.showOneArrayOutput(pointArray1, "1");
//Insert(1, pt2.x, pt2.y,dist);
//System.out.println(p1 + ":::::" + pointArray1);
}
if (tracks.get(j).track_id == 2) {
p2 = pt2;
double dist = euclideanDist(tracks.get(j).trace.get(tracks.get(j).trace.size() - 1), p2);
pointArray2.add(p2);
//Insert(2, pt2.x, pt2.y,dist);
}
if (tracks.get(j).track_id == 3) {
p3 = pt2;
double dist = euclideanDist(tracks.get(j).trace.get(tracks.get(j).trace.size() - 1), p3);
pointArray3.add(p3);
//Insert(3, pt2.x, pt2.y,dist);
}
if (tracks.get(j).track_id == 4) {
p4 = pt2;
double dist = euclideanDist(tracks.get(j).trace.get(tracks.get(j).trace.size() - 1), p4);
pointArray4.add(p4);
//Insert(4, pt2.x, pt2.y,dist);
}
if (tracks.get(j).track_id == 5) {
p5 = pt2;
double dist = euclideanDist(tracks.get(j).trace.get(tracks.get(j).trace.size() - 1), p5);
pointArray5.add(p5);
//Insert(5, pt2.x, pt2.y,dist);
}
if (tracks.get(j).track_id == 6) {
p6 = pt2;
double dist = euclideanDist(tracks.get(j).trace.get(tracks.get(j).trace.size() - 1), p6);
pointArray6.add(p6);
// Insert(6, pt2.x, pt2.y,dist);
}
if (tracks.get(j).track_id == 7) {
p7 = pt2;
double dist = euclideanDist(tracks.get(j).trace.get(tracks.get(j).trace.size() - 1), p7);
pointArray7.add(p7);
//Insert(7, pt2.x, pt2.y,dist);
}
if (tracks.get(j).track_id == 8) {
p8 = pt2;
double dist = euclideanDist(tracks.get(j).trace.get(tracks.get(j).trace.size() - 1), p8);
pointArray8.add(p8);
//Insert(8, pt2.x, pt2.y,dist);
}
if (tracks.get(j).track_id == 9) {
p9 = pt2;
double dist = euclideanDist(tracks.get(j).trace.get(tracks.get(j).trace.size() - 1), p9);
pointArray9.add(p9);
//Insert(9, pt2.x, pt2.y,dist);
}
if (tracks.get(j).track_id == 10) {
p10 = pt2;
double dist = euclideanDist(tracks.get(j).trace.get(tracks.get(j).trace.size() - 1), p10);
pointArray10.add(p10);
//Insert(10, pt2.x, pt2.y,dist);
}
if (tracks.get(j).track_id == 11) {
p11 = pt2;
double dist = euclideanDist(tracks.get(j).trace.get(tracks.get(j).trace.size() - 1), p11);
pointArray11.add(p11);
//Insert(11, pt2.x, pt2.y,dist);
}
if (tracks.get(j).track_id == 12) {
p12 = pt2;
double dist = euclideanDist(tracks.get(j).trace.get(tracks.get(j).trace.size() - 1), p12);
pointArray12.add(p12);
//Insert(12, pt2.x, pt2.y,dist);
}
if (tracks.get(j).track_id == 13) {
p13 = pt2;
double dist = euclideanDist(tracks.get(j).trace.get(tracks.get(j).trace.size() - 1), p13);
pointArray13.add(p13);
//Insert(13, pt2.x, pt2.y,dist);
}
if (tracks.get(j).track_id == 14) {
p14 = pt2;
double dist = euclideanDist(tracks.get(j).trace.get(tracks.get(j).trace.size() - 1), p14);
pointArray14.add(p14);
//Insert(14, pt2.x, pt2.y,dist);
}
if (tracks.get(j).track_id == 15) {
p15 = pt2;
double dist = euclideanDist(tracks.get(j).trace.get(tracks.get(j).trace.size() - 1), p15);
pointArray15.add(p15);
//Insert(15, pt2.x, pt2.y,dist);
}
if (tracks.get(j).track_id == 16) {
p16 = pt2;
double dist = euclideanDist(tracks.get(j).trace.get(tracks.get(j).trace.size() - 1), p16);
pointArray16.add(p16);
//Insert(16, pt2.x, pt2.y,dist);
}
if (tracks.get(j).track_id == 17) {
p17 = pt2;
double dist = euclideanDist(tracks.get(j).trace.get(tracks.get(j).trace.size() - 1), p17);
pointArray17.add(p17);
//Insert(17, pt2.x, pt2.y,dist);
}
if (tracks.get(j).track_id == 18) {
p18 = pt2;
double dist = euclideanDist(tracks.get(j).trace.get(tracks.get(j).trace.size() - 1), p18);
pointArray18.add(p18);
//Insert(18, pt2.x, pt2.y,dist);
}
if (tracks.get(j).track_id == 19) {
p19 = pt2;
double dist = euclideanDist(tracks.get(j).trace.get(tracks.get(j).trace.size() - 1), p19);
pointArray19.add(p19);
//Insert(19, pt2.x, pt2.y,dist);
}
if (tracks.get(j).track_id == 20) {
p20 = pt2;
double dist = euclideanDist(tracks.get(j).trace.get(tracks.get(j).trace.size() - 1), p20);
pointArray20.add(p20);
//Insert(20, pt2.x, pt2.y,dist);
}
if (tracks.get(j).track_id == 21) {
p21 = pt2;
double dist = euclideanDist(tracks.get(j).trace.get(tracks.get(j).trace.size() - 1), p21);
pointArray21.add(p21);
//Insert(21, pt2.x, pt2.y,dist);
}
if (tracks.get(j).track_id == 22) {
p22 = pt2;
double dist = euclideanDist(tracks.get(j).trace.get(tracks.get(j).trace.size() - 1), p22);
pointArray22.add(p22);
//Insert(22, pt2.x, pt2.y,dist);
}
if (tracks.get(j).track_id == 23) {
p23 = pt2;
double dist = euclideanDist(tracks.get(j).trace.get(tracks.get(j).trace.size() - 1), p23);
pointArray23.add(p23);
//Insert(23, pt2.x, pt2.y,dist);
}
//}
}
}
//System.out.println(p0 + "::" + p1 + "::" + p2 + "::" + p3 + "::" + p4);
//thread1.run();
//thread2.run();
//thread3.run();
//thread4.run();
}
public void updateKalman(Mat imag, Vector<Point> detections) {
// Update Kalman Filters state
if (detections.isEmpty()) {
for (int i = 0; i < assignment.size(); i++) {
assignment.set(i, -1);
}
}
for (int i = 0; i < assignment.size(); i++) {
// If track updated less than one time, than filter state is not correct.
tracks.get(i).prediction = tracks.get(i).KF.getPrediction();
if (assignment.get(i) != -1) // If we have assigned detect, then update using its coordinates,
{
tracks.get(i).skipped_frames = 0;
tracks.get(i).prediction = tracks.get(i).KF.update(detections.get(assignment.get(i)), true);
//tracks.get(i).KF.correction(detections.get(assignment.get(i)));
//System.out.println("Assign ID:"+i);
} else // if not continue using predictions
{
tracks.get(i).prediction = tracks.get(i).KF.update(new Point(0, 0), false);
}
if (tracks.get(i).trace.size() > max_trace_length) {
for (int j = 0; j < tracks.get(i).trace.size() - max_trace_length; j++) {
tracks.get(i).trace.remove(j);
}
}
//if(euclideanDist(tracks.get(i).prediction, tracks.get(i).trace.get(tracks.get(i).trace.size()-1))<=5){
tracks.get(i).trace.add(tracks.get(i).prediction);
tracks.get(i).KF.setLastResult(tracks.get(i).prediction);
//}
//Imgproc.putText(imag, "K",tracks.get(i).prediction,
//Core.FONT_HERSHEY_PLAIN, 2, new Scalar(255, 255, 255), 1);
}
}
I want to assign old trackId a long time but now I use this code. It will get a new trackId when it lost detection or move through another object.