#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 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("x"); float yMin = detection.second.get("y"); float width = detection.second.get("width"); float height = detection.second.get("height"); float conf = detection.second.get("prob"); int classId = detection.second.get("class_id"); std::string object_id = detection.second.get("object_id"); std::stringstream ss(object_id); std::vector 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(); childNode = rootNode.get_child("max_age"); max_age = childNode.get_value(); childNode = rootNode.get_child("min_hits"); min_hits = childNode.get_value(); childNode = rootNode.get_child("iou_threshold"); iou_threshold = childNode.get_value(); childNode = rootNode.get_child("delta_t"); delta_t = childNode.get_value(); childNode = rootNode.get_child("asso_func"); asso_func_in = childNode.get_value(); if (asso_func_in == 1)asso_func = "giou"; else asso_func = "iou"; childNode = rootNode.get_child("inertia"); inertia = childNode.get_value(); childNode = rootNode.get_child("use_byte"); use_byte_in = childNode.get_value(); 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 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(outputs[i][4]); int classId = static_cast(outputs[i][5]); double prob = static_cast(outputs[i][6]); int DGId = static_cast(outputs[i][7]); int CameraId = static_cast(outputs[i][8]); int MId = static_cast(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 ANSOCSortTrack::UpdateTracker(int modelId, const std::vector& detectionObjects) { if (!_licenseValid) { this->_logger.LogFatal("ANSOCSortTrack::UpdateTracker", "Invalid license", __FILE__, __LINE__); return std::vector(); } try { std::vector 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(outputs[i][4]); int classId = static_cast(outputs[i][5]); double prob = static_cast(outputs[i][6]); int DGId = static_cast(outputs[i][7]); int CameraId = static_cast(outputs[i][8]); int MId = static_cast(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(); } } }