144 lines
6.2 KiB
C++
144 lines
6.2 KiB
C++
#include "EigenBoundingBoxTrackUtils.h"
|
|
namespace ByteTrackEigen {
|
|
/**
|
|
* @brief Joins two lists of KalmanBBoxTrack pointers, ensuring unique track IDs.
|
|
*
|
|
* This function combines track lists A and B. If a track ID is present in both lists,
|
|
* the track from list B is used in the final list. This ensures that each track ID is
|
|
* unique in the resulting list.
|
|
*
|
|
* @param track_list_a First list of shared pointers to KalmanBBoxTrack objects.
|
|
* @param track_list_b Second list of shared pointers to KalmanBBoxTrack objects.
|
|
* @return std::vector<std::shared_ptr<KalmanBBoxTrack>> A list with unique tracks based on track IDs.
|
|
*/
|
|
std::vector<std::shared_ptr<KalmanBBoxTrack>> join_tracks(
|
|
const std::vector<std::shared_ptr<KalmanBBoxTrack>> track_list_a,
|
|
const std::vector<std::shared_ptr<KalmanBBoxTrack>> track_list_b) {
|
|
|
|
std::map<int, std::shared_ptr<KalmanBBoxTrack>> unique_tracks;
|
|
|
|
// Populate the map with tracks from track_list_a
|
|
for (auto& track : track_list_a) {
|
|
unique_tracks[track->get_track_id()] = track;
|
|
}
|
|
|
|
// Insert or overwrite with tracks from track_list_b
|
|
for (auto& track : track_list_b) {
|
|
unique_tracks[track->get_track_id()] = track;
|
|
}
|
|
|
|
// Convert the unique tracks in the map to a vector
|
|
std::vector<std::shared_ptr<KalmanBBoxTrack>> result;
|
|
for (auto [key, value] : unique_tracks) {
|
|
result.push_back(value);
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* @brief Subtracts tracks in track_list_b from track_list_a based on track IDs.
|
|
*
|
|
* This function creates a new list of tracks from track_list_a excluding those
|
|
* tracks whose IDs are found in track_list_b, effectively performing a set subtraction.
|
|
*
|
|
* @param track_list_a First list of shared pointers to KalmanBBoxTrack objects.
|
|
* @param track_list_b Second list of shared pointers to KalmanBBoxTrack objects.
|
|
* @return std::vector<std::shared_ptr<KalmanBBoxTrack>> A list of tracks present in track_list_a but not in track_list_b.
|
|
*/
|
|
std::vector<std::shared_ptr<KalmanBBoxTrack>> sub_tracks(
|
|
const std::vector<std::shared_ptr<KalmanBBoxTrack>>& track_list_a,
|
|
const std::vector<std::shared_ptr<KalmanBBoxTrack>>& track_list_b) {
|
|
|
|
std::unordered_set<int> track_ids_b;
|
|
|
|
// Populate set with track IDs from track_list_b for quick lookup
|
|
for (const auto& track : track_list_b) {
|
|
track_ids_b.insert(track->get_track_id());
|
|
}
|
|
|
|
// Collect tracks from track_list_a not found in track_list_b
|
|
std::vector<std::shared_ptr<KalmanBBoxTrack>> result;
|
|
for (const auto& track : track_list_a) {
|
|
if (track_ids_b.find(track->get_track_id()) == track_ids_b.end()) {
|
|
result.push_back(track);
|
|
}
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* @brief Removes duplicate tracks from two lists based on IOU distance and track age.
|
|
*
|
|
* This function identifies and removes duplicate tracks between two lists based on the
|
|
* Intersection Over Union (IOU) distance. If two tracks have an IOU distance less than
|
|
* a threshold (0.15), the older track is retained.
|
|
*
|
|
* @param track_list_a First list of shared pointers to KalmanBBoxTrack objects.
|
|
* @param track_list_b Second list of shared pointers to KalmanBBoxTrack objects.
|
|
* @return Pair of vectors each containing unique tracks after removing duplicates.
|
|
*/
|
|
std::pair<std::vector<std::shared_ptr<KalmanBBoxTrack>>, std::vector<std::shared_ptr<KalmanBBoxTrack>>>
|
|
remove_duplicate_tracks(const std::vector<std::shared_ptr<KalmanBBoxTrack>> track_list_a,
|
|
const std::vector<std::shared_ptr<KalmanBBoxTrack>> track_list_b) {
|
|
|
|
// Creating instance vectors to store de-referenced shared pointers from the input lists.
|
|
// This is necessary for the IOU distance calculation.
|
|
std::vector<KalmanBBoxTrack> s_tracks_a_instances;
|
|
s_tracks_a_instances.reserve(track_list_a.size());
|
|
for (const auto& ptr : track_list_a) {
|
|
s_tracks_a_instances.push_back(*ptr);
|
|
}
|
|
|
|
std::vector<KalmanBBoxTrack> s_tracks_b_instances;
|
|
s_tracks_b_instances.reserve(track_list_b.size());
|
|
for (const auto& ptr : track_list_b) {
|
|
s_tracks_b_instances.push_back(*ptr);
|
|
}
|
|
|
|
// Calculating pairwise IOU distance between tracks in both lists.
|
|
Eigen::MatrixXd pairwise_distance = iou_distance(s_tracks_a_instances, s_tracks_b_instances);
|
|
|
|
// Sets to track indices of duplicates in both lists.
|
|
std::unordered_set<int> duplicates_a, duplicates_b;
|
|
|
|
// Loop through the matrix of pairwise distances to identify duplicates.
|
|
for (int i = 0; i < pairwise_distance.rows(); ++i) {
|
|
for (int j = 0; j < pairwise_distance.cols(); ++j) {
|
|
// If IOU distance is below the threshold, consider the tracks as duplicates.
|
|
if (pairwise_distance(i, j) < 0.15) {
|
|
// Calculate track age to determine which track to keep.
|
|
int time_a = track_list_a[i]->get_frame_id() - track_list_a[i]->get_start_frame();
|
|
int time_b = track_list_b[j]->get_frame_id() - track_list_b[j]->get_start_frame();
|
|
|
|
// Retain the older track and mark the newer one as a duplicate.
|
|
if (time_a > time_b) {
|
|
duplicates_b.insert(j);
|
|
}
|
|
else {
|
|
duplicates_a.insert(i);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Constructing the result lists, excluding the identified duplicates.
|
|
std::vector<std::shared_ptr<KalmanBBoxTrack>> result_a, result_b;
|
|
for (int i = 0; i < track_list_a.size(); ++i) {
|
|
if (duplicates_a.find(i) == duplicates_a.end()) {
|
|
result_a.push_back(track_list_a[i]);
|
|
}
|
|
}
|
|
for (int j = 0; j < track_list_b.size(); ++j) {
|
|
if (duplicates_b.find(j) == duplicates_b.end()) {
|
|
result_b.push_back(track_list_b[j]);
|
|
}
|
|
}
|
|
|
|
return { result_a, result_b };
|
|
}
|
|
|
|
|
|
}
|