Files
ANSCORE/modules/ANSMOT/ANSOCSortTrack.cpp

298 lines
12 KiB
C++
Raw Normal View History

2026-03-28 16:54:11 +11:00
#include "ANSOCSortTrack.h"
#include "OCSortObject.h"
#include "boost/property_tree/ptree.hpp"
#include "boost/property_tree/json_parser.hpp"
#include "boost/foreach.hpp"
#include "boost/optional.hpp"
#include <map>
namespace ANSCENTER {
Eigen::MatrixXf GetOCSortInputs(const char* jsonString) {
Eigen::MatrixXf ret(0, 9); // 0 row and 9 columns
try {
boost::property_tree::ptree pt;
std::stringstream ss;
ss << jsonString;
boost::property_tree::read_json(ss, pt);
boost::property_tree::ptree detections = pt.get_child("results");
if (detections.size() > 0) {
for (const auto& detection : detections) {
float xMin = detection.second.get<float>("x");
float yMin = detection.second.get<float>("y");
float width = detection.second.get<float>("width");
float height = detection.second.get<float>("height");
float conf = detection.second.get<float>("prob");
int classId = detection.second.get<int>("class_id");
std::string object_id = detection.second.get<std::string>("object_id");
std::stringstream ss(object_id);
std::vector<std::string> result;
int i = 0;
while (ss.good())
{
std::string substr;
getline(ss, substr, ';');
result.push_back(substr);
i++;
if (i > 5)break;
}
// We now need to parse object_id into DGId,CameraId,and ModelId
double xMax = xMin + width;
double yMax = yMin + height;
int DGId = 0;
int CameraId = 0;
int ModelId = 0;
if (result.size() >= 4) {
DGId = stoi(result[1]);
CameraId = stoi(result[2]);
ModelId = stoi(result[3]);
}
Eigen::MatrixXf newRow(1, ret.cols());
newRow << xMin, yMin, xMax, yMax, conf, classId, DGId, CameraId, ModelId;
ret.conservativeResize(ret.rows() + 1, Eigen::NoChange);
ret.row(ret.rows() - 1) = newRow;
}
}
return ret;
}
catch (const std::exception& e) {
return ret;
}
}
ANSOCSortTrack::ANSOCSortTrack()
{
_licenseValid = false;
CheckLicense();
float det_thresh = 0;
int max_age = 50;
int min_hits = 1;
float iou_threshold = 0.22136877277096445;
int delta_t = 1;
std::string asso_func = "iou";//giou//"iou"
float inertia = 0.3941737016672115;
bool use_byte = true;
tracker.update_parameters(det_thresh, max_age, min_hits, iou_threshold, delta_t, asso_func, inertia, use_byte);
}
ANSOCSortTrack::~ANSOCSortTrack() {
}
bool ANSOCSortTrack::Destroy() {
return true;
}
bool ANSOCSortTrack::UpdateParameters(const std::string& trackerParameters) {
//// Use JSON Boost to parse paramter from trackerParameters
try {
float det_thresh = 0;
int max_age = 50;
int min_hits = 1;
float iou_threshold = 0.22136877277096445;
int delta_t = 1;
int asso_func_in = 0;
std::string asso_func = "giou";
float inertia = 0.3941737016672115;
bool use_byte = true;
int use_byte_in = 0;
if (!trackerParameters.empty()) {
std::stringstream ss;
ss << trackerParameters;
boost::property_tree::ptree pt;
boost::property_tree::read_json(ss, pt);
auto rootNode = pt.get_child("parameters");
auto childNode = rootNode.get_child("det_thresh");
det_thresh = childNode.get_value<float>();
childNode = rootNode.get_child("max_age");
max_age = childNode.get_value<int>();
childNode = rootNode.get_child("min_hits");
min_hits = childNode.get_value<int>();
childNode = rootNode.get_child("iou_threshold");
iou_threshold = childNode.get_value<float>();
childNode = rootNode.get_child("delta_t");
delta_t = childNode.get_value<int>();
childNode = rootNode.get_child("asso_func");
asso_func_in = childNode.get_value<int>();
if (asso_func_in == 1)asso_func = "giou";
else asso_func = "iou";
childNode = rootNode.get_child("inertia");
inertia = childNode.get_value<float>();
childNode = rootNode.get_child("use_byte");
use_byte_in = childNode.get_value<int>();
if (use_byte_in == 1) use_byte = true;
else use_byte = false;
}
tracker.update_parameters(det_thresh, max_age, min_hits, iou_threshold, delta_t, asso_func, inertia, use_byte);
return true;
}
catch (const std::exception& e) {
this->_logger.LogFatal("ANSOCSortTrack::UpdateParameters", e.what(), __FILE__, __LINE__);
return false;
}
}
std::string ANSOCSortTrack::Update(int modelId, const std::string& detectionData) {
if (!_licenseValid) {
this->_logger.LogFatal("ANSOCSortTrack::Update", "Invalid license", __FILE__, __LINE__);
return "";
}
try {
boost::property_tree::ptree root;
boost::property_tree::ptree trackingObjects;
boost::property_tree::ptree pt;
std::vector<std::string> obj_ids;
Eigen::MatrixXf objects = GetOCSortInputs(detectionData.c_str());
//2. Do tracking
const auto outputs = tracker.update(objects);
if (outputs.size() > 0) {
for (int i = 0; i < outputs.size(); i++) {
double x_min = outputs[i][0];
double y_min = outputs[i][1];
double x_max = outputs[i][2];
double y_max = outputs[i][3];
int trackId = static_cast<int>(outputs[i][4]);
int classId = static_cast<int>(outputs[i][5]);
double prob = static_cast<double>(outputs[i][6]);
int DGId = static_cast<int>(outputs[i][7]);
int CameraId = static_cast<int>(outputs[i][8]);
int MId = static_cast<int>(outputs[i][9]);
std::string name = std::to_string(MId) + ":" + std::to_string(classId);
std::string object_id = name + ";" + std::to_string(DGId) + ";" + std::to_string(CameraId) + ";" + std::to_string(MId);
bool is_valid = true;
double width = x_max - x_min;
double heigh = y_max - y_min;
double left = x_min;
double top = y_min;
double right = x_max;
double bottom = y_max;
boost::property_tree::ptree trackingNode;
trackingNode.put("model_id", modelId);
trackingNode.put("track_id", trackId);
trackingNode.put("class_id", classId);
trackingNode.put("prob", prob);
trackingNode.put("x", x_min);
trackingNode.put("y", y_min);
trackingNode.put("width", width);
trackingNode.put("height", heigh);
trackingNode.put("left", left);
trackingNode.put("top", top);
trackingNode.put("right", right);
trackingNode.put("bottom", bottom);
trackingNode.put("valid", is_valid);
trackingNode.put("object_id", object_id);
trackingObjects.push_back(std::make_pair("", trackingNode));
}
}
//3. Convert result
root.add_child("results", trackingObjects);
std::ostringstream stream;
boost::property_tree::write_json(stream, root,false);
std::string st = stream.str();
return st;
}
catch (const std::exception& e) {
this->_logger.LogFatal("ANSOCSortTrack::Update", e.what(), __FILE__, __LINE__);
return "";
}
}
std::vector<TrackerObject> ANSOCSortTrack::UpdateTracker(int modelId, const std::vector<TrackerObject>& detectionObjects) {
if (!_licenseValid) {
this->_logger.LogFatal("ANSOCSortTrack::UpdateTracker", "Invalid license", __FILE__, __LINE__);
return std::vector<TrackerObject>();
}
try {
std::vector<TrackerObject> trackingResults;
Eigen::MatrixXf ret(0, 9); // 0 row and 9 columns
if (detectionObjects.size() > 0) {
for (const auto& detection : detectionObjects) {
float xMin = detection.x;
float yMin = detection.y;
float width = detection.width;
float height = detection.height;
float conf = detection.prob;
int classId = detection.class_id;
std::string object_id = detection.object_id;
// We now need to parse object_id into DGId,CameraId,and ModelId
double xMax = xMin + width;
double yMax = yMin + height;
int DGId = 0;
int CameraId = 0;
int ModelId = 0;
Eigen::MatrixXf newRow(1, ret.cols());
newRow << xMin, yMin, xMax, yMax, conf, classId, DGId, CameraId, ModelId;
ret.conservativeResize(ret.rows() + 1, Eigen::NoChange);
ret.row(ret.rows() - 1) = newRow;
}
}
//2. Do tracking
const auto outputs = tracker.update(ret);
if (outputs.size() > 0) {
for (int i = 0; i < outputs.size(); i++) {
TrackerObject trackObj;
double x_min = outputs[i][0];
double y_min = outputs[i][1];
double x_max = outputs[i][2];
double y_max = outputs[i][3];
int trackId = static_cast<int>(outputs[i][4]);
int classId = static_cast<int>(outputs[i][5]);
double prob = static_cast<double>(outputs[i][6]);
int DGId = static_cast<int>(outputs[i][7]);
int CameraId = static_cast<int>(outputs[i][8]);
int MId = static_cast<int>(outputs[i][9]);
std::string name = std::to_string(MId) + ":" + std::to_string(classId);
std::string object_id = name + ";" + std::to_string(DGId) + ";" + std::to_string(CameraId) + ";" + std::to_string(MId);
bool is_valid = true;
double width = x_max - x_min;
double heigh = y_max - y_min;
double left = x_min;
double top = y_min;
double right = x_max;
double bottom = y_max;
trackObj.track_id = trackId;
trackObj.class_id = classId;
trackObj.prob = prob;
trackObj.x = x_min;
trackObj.y = y_min;
trackObj.width = width;
trackObj.height = heigh;
trackObj.left = left;
trackObj.top = top;
trackObj.right = right;
trackObj.bottom = bottom;
trackObj.object_id = object_id;
trackingResults.push_back(trackObj);
}
}
return trackingResults;
}
catch (const std::exception& e) {
this->_logger.LogFatal("ANSOCSortTrack::UpdateTracker", e.what(), __FILE__, __LINE__);
return std::vector<TrackerObject>();
}
}
}