trajectory.cc 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529
  1. // Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved.
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. // The code is based on:
  15. // https://github.com/CnybTseng/JDE/blob/master/platforms/common/trajectory.cpp
  16. // The copyright of CnybTseng/JDE is as follows:
  17. // MIT License
  18. #include "ultra_infer/vision/tracking/pptracking/trajectory.h"
  19. #include <algorithm>
  20. namespace ultra_infer {
  21. namespace vision {
  22. namespace tracking {
  23. void TKalmanFilter::init(const cv::Mat &measurement) {
  24. measurement.copyTo(statePost(cv::Rect(0, 0, 1, 4)));
  25. statePost(cv::Rect(0, 4, 1, 4)).setTo(0);
  26. statePost.copyTo(statePre);
  27. float varpos = 2 * std_weight_position * (*measurement.ptr<float>(3));
  28. varpos *= varpos;
  29. float varvel = 10 * std_weight_velocity * (*measurement.ptr<float>(3));
  30. varvel *= varvel;
  31. errorCovPost.setTo(0);
  32. *errorCovPost.ptr<float>(0, 0) = varpos;
  33. *errorCovPost.ptr<float>(1, 1) = varpos;
  34. *errorCovPost.ptr<float>(2, 2) = 1e-4f;
  35. *errorCovPost.ptr<float>(3, 3) = varpos;
  36. *errorCovPost.ptr<float>(4, 4) = varvel;
  37. *errorCovPost.ptr<float>(5, 5) = varvel;
  38. *errorCovPost.ptr<float>(6, 6) = 1e-10f;
  39. *errorCovPost.ptr<float>(7, 7) = varvel;
  40. errorCovPost.copyTo(errorCovPre);
  41. }
  42. const cv::Mat &TKalmanFilter::predict() {
  43. float varpos = std_weight_position * (*statePre.ptr<float>(3));
  44. varpos *= varpos;
  45. float varvel = std_weight_velocity * (*statePre.ptr<float>(3));
  46. varvel *= varvel;
  47. processNoiseCov.setTo(0);
  48. *processNoiseCov.ptr<float>(0, 0) = varpos;
  49. *processNoiseCov.ptr<float>(1, 1) = varpos;
  50. *processNoiseCov.ptr<float>(2, 2) = 1e-4f;
  51. *processNoiseCov.ptr<float>(3, 3) = varpos;
  52. *processNoiseCov.ptr<float>(4, 4) = varvel;
  53. *processNoiseCov.ptr<float>(5, 5) = varvel;
  54. *processNoiseCov.ptr<float>(6, 6) = 1e-10f;
  55. *processNoiseCov.ptr<float>(7, 7) = varvel;
  56. return cv::KalmanFilter::predict();
  57. }
  58. const cv::Mat &TKalmanFilter::correct(const cv::Mat &measurement) {
  59. float varpos = std_weight_position * (*measurement.ptr<float>(3));
  60. varpos *= varpos;
  61. measurementNoiseCov.setTo(0);
  62. *measurementNoiseCov.ptr<float>(0, 0) = varpos;
  63. *measurementNoiseCov.ptr<float>(1, 1) = varpos;
  64. *measurementNoiseCov.ptr<float>(2, 2) = 1e-2f;
  65. *measurementNoiseCov.ptr<float>(3, 3) = varpos;
  66. return cv::KalmanFilter::correct(measurement);
  67. }
  68. void TKalmanFilter::project(cv::Mat *mean, cv::Mat *covariance) const {
  69. float varpos = std_weight_position * (*statePost.ptr<float>(3));
  70. varpos *= varpos;
  71. cv::Mat measurementNoiseCov_ = cv::Mat::eye(4, 4, CV_32F);
  72. *measurementNoiseCov_.ptr<float>(0, 0) = varpos;
  73. *measurementNoiseCov_.ptr<float>(1, 1) = varpos;
  74. *measurementNoiseCov_.ptr<float>(2, 2) = 1e-2f;
  75. *measurementNoiseCov_.ptr<float>(3, 3) = varpos;
  76. *mean = measurementMatrix * statePost;
  77. cv::Mat temp = measurementMatrix * errorCovPost;
  78. gemm(temp, measurementMatrix, 1, measurementNoiseCov_, 1, *covariance,
  79. cv::GEMM_2_T);
  80. }
  81. const cv::Mat &Trajectory::predict(void) {
  82. if (state != Tracked)
  83. *cv::KalmanFilter::statePost.ptr<float>(7) = 0;
  84. return TKalmanFilter::predict();
  85. }
  86. void Trajectory::update(Trajectory *traj, int timestamp_,
  87. bool update_embedding_) {
  88. timestamp = timestamp_;
  89. ++length;
  90. ltrb = traj->ltrb;
  91. xyah = traj->xyah;
  92. TKalmanFilter::correct(cv::Mat(traj->xyah));
  93. state = Tracked;
  94. is_activated = true;
  95. score = traj->score;
  96. if (update_embedding_)
  97. update_embedding(traj->current_embedding);
  98. }
  99. void Trajectory::activate(int &cnt, int timestamp_) {
  100. id = next_id(cnt);
  101. TKalmanFilter::init(cv::Mat(xyah));
  102. length = 0;
  103. state = Tracked;
  104. if (timestamp_ == 1) {
  105. is_activated = true;
  106. }
  107. timestamp = timestamp_;
  108. starttime = timestamp_;
  109. }
  110. void Trajectory::reactivate(Trajectory *traj, int &cnt, int timestamp_,
  111. bool newid) {
  112. TKalmanFilter::correct(cv::Mat(traj->xyah));
  113. update_embedding(traj->current_embedding);
  114. length = 0;
  115. state = Tracked;
  116. is_activated = true;
  117. timestamp = timestamp_;
  118. if (newid)
  119. id = next_id(cnt);
  120. }
  121. void Trajectory::update_embedding(const cv::Mat &embedding) {
  122. current_embedding = embedding / cv::norm(embedding);
  123. if (smooth_embedding.empty()) {
  124. smooth_embedding = current_embedding;
  125. } else {
  126. smooth_embedding = eta * smooth_embedding + (1 - eta) * current_embedding;
  127. }
  128. smooth_embedding = smooth_embedding / cv::norm(smooth_embedding);
  129. }
  130. TrajectoryPool operator+(const TrajectoryPool &a, const TrajectoryPool &b) {
  131. TrajectoryPool sum;
  132. sum.insert(sum.end(), a.begin(), a.end());
  133. std::vector<int> ids(a.size());
  134. for (size_t i = 0; i < a.size(); ++i)
  135. ids[i] = a[i].id;
  136. for (size_t i = 0; i < b.size(); ++i) {
  137. std::vector<int>::iterator iter = find(ids.begin(), ids.end(), b[i].id);
  138. if (iter == ids.end()) {
  139. sum.push_back(b[i]);
  140. ids.push_back(b[i].id);
  141. }
  142. }
  143. return sum;
  144. }
  145. TrajectoryPool operator+(const TrajectoryPool &a, const TrajectoryPtrPool &b) {
  146. TrajectoryPool sum;
  147. sum.insert(sum.end(), a.begin(), a.end());
  148. std::vector<int> ids(a.size());
  149. for (size_t i = 0; i < a.size(); ++i)
  150. ids[i] = a[i].id;
  151. for (size_t i = 0; i < b.size(); ++i) {
  152. std::vector<int>::iterator iter = find(ids.begin(), ids.end(), b[i]->id);
  153. if (iter == ids.end()) {
  154. sum.push_back(*b[i]);
  155. ids.push_back(b[i]->id);
  156. }
  157. }
  158. return sum;
  159. }
  160. TrajectoryPool &operator+=(TrajectoryPool &a, // NOLINT
  161. const TrajectoryPtrPool &b) {
  162. std::vector<int> ids(a.size());
  163. for (size_t i = 0; i < a.size(); ++i)
  164. ids[i] = a[i].id;
  165. for (size_t i = 0; i < b.size(); ++i) {
  166. if (b[i]->smooth_embedding.empty())
  167. continue;
  168. std::vector<int>::iterator iter = find(ids.begin(), ids.end(), b[i]->id);
  169. if (iter == ids.end()) {
  170. a.push_back(*b[i]);
  171. ids.push_back(b[i]->id);
  172. }
  173. }
  174. return a;
  175. }
  176. TrajectoryPool operator-(const TrajectoryPool &a, const TrajectoryPool &b) {
  177. TrajectoryPool dif;
  178. std::vector<int> ids(b.size());
  179. for (size_t i = 0; i < b.size(); ++i)
  180. ids[i] = b[i].id;
  181. for (size_t i = 0; i < a.size(); ++i) {
  182. std::vector<int>::iterator iter = find(ids.begin(), ids.end(), a[i].id);
  183. if (iter == ids.end())
  184. dif.push_back(a[i]);
  185. }
  186. return dif;
  187. }
  188. TrajectoryPool &operator-=(TrajectoryPool &a, // NOLINT
  189. const TrajectoryPool &b) {
  190. std::vector<int> ids(b.size());
  191. for (size_t i = 0; i < b.size(); ++i)
  192. ids[i] = b[i].id;
  193. TrajectoryPoolIterator piter;
  194. for (piter = a.begin(); piter != a.end();) {
  195. std::vector<int>::iterator iter = find(ids.begin(), ids.end(), piter->id);
  196. if (iter == ids.end())
  197. ++piter;
  198. else
  199. piter = a.erase(piter);
  200. }
  201. return a;
  202. }
  203. TrajectoryPtrPool operator+(const TrajectoryPtrPool &a,
  204. const TrajectoryPtrPool &b) {
  205. TrajectoryPtrPool sum;
  206. sum.insert(sum.end(), a.begin(), a.end());
  207. std::vector<int> ids(a.size());
  208. for (size_t i = 0; i < a.size(); ++i)
  209. ids[i] = a[i]->id;
  210. for (size_t i = 0; i < b.size(); ++i) {
  211. std::vector<int>::iterator iter = find(ids.begin(), ids.end(), b[i]->id);
  212. if (iter == ids.end()) {
  213. sum.push_back(b[i]);
  214. ids.push_back(b[i]->id);
  215. }
  216. }
  217. return sum;
  218. }
  219. TrajectoryPtrPool operator+(const TrajectoryPtrPool &a, TrajectoryPool *b) {
  220. TrajectoryPtrPool sum;
  221. sum.insert(sum.end(), a.begin(), a.end());
  222. std::vector<int> ids(a.size());
  223. for (size_t i = 0; i < a.size(); ++i)
  224. ids[i] = a[i]->id;
  225. for (size_t i = 0; i < b->size(); ++i) {
  226. std::vector<int>::iterator iter = find(ids.begin(), ids.end(), (*b)[i].id);
  227. if (iter == ids.end()) {
  228. sum.push_back(&(*b)[i]);
  229. ids.push_back((*b)[i].id);
  230. }
  231. }
  232. return sum;
  233. }
  234. TrajectoryPtrPool operator-(const TrajectoryPtrPool &a,
  235. const TrajectoryPtrPool &b) {
  236. TrajectoryPtrPool dif;
  237. std::vector<int> ids(b.size());
  238. for (size_t i = 0; i < b.size(); ++i)
  239. ids[i] = b[i]->id;
  240. for (size_t i = 0; i < a.size(); ++i) {
  241. std::vector<int>::iterator iter = find(ids.begin(), ids.end(), a[i]->id);
  242. if (iter == ids.end())
  243. dif.push_back(a[i]);
  244. }
  245. return dif;
  246. }
  247. cv::Mat embedding_distance(const TrajectoryPool &a, const TrajectoryPool &b) {
  248. cv::Mat dists(a.size(), b.size(), CV_32F);
  249. for (size_t i = 0; i < a.size(); ++i) {
  250. float *distsi = dists.ptr<float>(i);
  251. for (size_t j = 0; j < b.size(); ++j) {
  252. cv::Mat u = a[i].smooth_embedding;
  253. cv::Mat v = b[j].smooth_embedding;
  254. double uv = u.dot(v);
  255. double uu = u.dot(u);
  256. double vv = v.dot(v);
  257. double dist = std::abs(1. - uv / std::sqrt(uu * vv));
  258. // double dist = cv::norm(a[i].smooth_embedding, b[j].smooth_embedding,
  259. // cv::NORM_L2);
  260. distsi[j] = static_cast<float>(std::max(std::min(dist, 2.), 0.));
  261. }
  262. }
  263. return dists;
  264. }
  265. cv::Mat embedding_distance(const TrajectoryPtrPool &a,
  266. const TrajectoryPtrPool &b) {
  267. cv::Mat dists(a.size(), b.size(), CV_32F);
  268. for (size_t i = 0; i < a.size(); ++i) {
  269. float *distsi = dists.ptr<float>(i);
  270. for (size_t j = 0; j < b.size(); ++j) {
  271. // double dist = cv::norm(a[i]->smooth_embedding, b[j]->smooth_embedding,
  272. // cv::NORM_L2);
  273. // distsi[j] = static_cast<float>(dist);
  274. cv::Mat u = a[i]->smooth_embedding;
  275. cv::Mat v = b[j]->smooth_embedding;
  276. double uv = u.dot(v);
  277. double uu = u.dot(u);
  278. double vv = v.dot(v);
  279. double dist = std::abs(1. - uv / std::sqrt(uu * vv));
  280. distsi[j] = static_cast<float>(std::max(std::min(dist, 2.), 0.));
  281. }
  282. }
  283. return dists;
  284. }
  285. cv::Mat embedding_distance(const TrajectoryPtrPool &a,
  286. const TrajectoryPool &b) {
  287. cv::Mat dists(a.size(), b.size(), CV_32F);
  288. for (size_t i = 0; i < a.size(); ++i) {
  289. float *distsi = dists.ptr<float>(i);
  290. for (size_t j = 0; j < b.size(); ++j) {
  291. // double dist = cv::norm(a[i]->smooth_embedding, b[j].smooth_embedding,
  292. // cv::NORM_L2);
  293. // distsi[j] = static_cast<float>(dist);
  294. cv::Mat u = a[i]->smooth_embedding;
  295. cv::Mat v = b[j].smooth_embedding;
  296. double uv = u.dot(v);
  297. double uu = u.dot(u);
  298. double vv = v.dot(v);
  299. double dist = std::abs(1. - uv / std::sqrt(uu * vv));
  300. distsi[j] = static_cast<float>(std::max(std::min(dist, 2.), 0.));
  301. }
  302. }
  303. return dists;
  304. }
  305. cv::Mat mahalanobis_distance(const TrajectoryPool &a, const TrajectoryPool &b) {
  306. std::vector<cv::Mat> means(a.size());
  307. std::vector<cv::Mat> icovariances(a.size());
  308. for (size_t i = 0; i < a.size(); ++i) {
  309. cv::Mat covariance;
  310. a[i].project(&means[i], &covariance);
  311. cv::invert(covariance, icovariances[i]);
  312. }
  313. cv::Mat dists(a.size(), b.size(), CV_32F);
  314. for (size_t i = 0; i < a.size(); ++i) {
  315. float *distsi = dists.ptr<float>(i);
  316. for (size_t j = 0; j < b.size(); ++j) {
  317. const cv::Mat x(b[j].xyah);
  318. float dist =
  319. static_cast<float>(cv::Mahalanobis(x, means[i], icovariances[i]));
  320. distsi[j] = dist * dist;
  321. }
  322. }
  323. return dists;
  324. }
  325. cv::Mat mahalanobis_distance(const TrajectoryPtrPool &a,
  326. const TrajectoryPtrPool &b) {
  327. std::vector<cv::Mat> means(a.size());
  328. std::vector<cv::Mat> icovariances(a.size());
  329. for (size_t i = 0; i < a.size(); ++i) {
  330. cv::Mat covariance;
  331. a[i]->project(&means[i], &covariance);
  332. cv::invert(covariance, icovariances[i]);
  333. }
  334. cv::Mat dists(a.size(), b.size(), CV_32F);
  335. for (size_t i = 0; i < a.size(); ++i) {
  336. float *distsi = dists.ptr<float>(i);
  337. for (size_t j = 0; j < b.size(); ++j) {
  338. const cv::Mat x(b[j]->xyah);
  339. float dist =
  340. static_cast<float>(cv::Mahalanobis(x, means[i], icovariances[i]));
  341. distsi[j] = dist * dist;
  342. }
  343. }
  344. return dists;
  345. }
  346. cv::Mat mahalanobis_distance(const TrajectoryPtrPool &a,
  347. const TrajectoryPool &b) {
  348. std::vector<cv::Mat> means(a.size());
  349. std::vector<cv::Mat> icovariances(a.size());
  350. for (size_t i = 0; i < a.size(); ++i) {
  351. cv::Mat covariance;
  352. a[i]->project(&means[i], &covariance);
  353. cv::invert(covariance, icovariances[i]);
  354. }
  355. cv::Mat dists(a.size(), b.size(), CV_32F);
  356. for (size_t i = 0; i < a.size(); ++i) {
  357. float *distsi = dists.ptr<float>(i);
  358. for (size_t j = 0; j < b.size(); ++j) {
  359. const cv::Mat x(b[j].xyah);
  360. float dist =
  361. static_cast<float>(cv::Mahalanobis(x, means[i], icovariances[i]));
  362. distsi[j] = dist * dist;
  363. }
  364. }
  365. return dists;
  366. }
  367. static inline float calc_inter_area(const cv::Vec4f &a, const cv::Vec4f &b) {
  368. if (a[2] < b[0] || a[0] > b[2] || a[3] < b[1] || a[1] > b[3])
  369. return 0.f;
  370. float w = std::min(a[2], b[2]) - std::max(a[0], b[0]);
  371. float h = std::min(a[3], b[3]) - std::max(a[1], b[1]);
  372. return w * h;
  373. }
  374. cv::Mat iou_distance(const TrajectoryPool &a, const TrajectoryPool &b) {
  375. std::vector<float> areaa(a.size());
  376. for (size_t i = 0; i < a.size(); ++i) {
  377. float w = a[i].ltrb[2] - a[i].ltrb[0];
  378. float h = a[i].ltrb[3] - a[i].ltrb[1];
  379. areaa[i] = w * h;
  380. }
  381. std::vector<float> areab(b.size());
  382. for (size_t j = 0; j < b.size(); ++j) {
  383. float w = b[j].ltrb[2] - b[j].ltrb[0];
  384. float h = b[j].ltrb[3] - b[j].ltrb[1];
  385. areab[j] = w * h;
  386. }
  387. cv::Mat dists(a.size(), b.size(), CV_32F);
  388. for (size_t i = 0; i < a.size(); ++i) {
  389. const cv::Vec4f &boxa = a[i].ltrb;
  390. float *distsi = dists.ptr<float>(i);
  391. for (size_t j = 0; j < b.size(); ++j) {
  392. const cv::Vec4f &boxb = b[j].ltrb;
  393. float inters = calc_inter_area(boxa, boxb);
  394. distsi[j] = 1.f - inters / (areaa[i] + areab[j] - inters);
  395. }
  396. }
  397. return dists;
  398. }
  399. cv::Mat iou_distance(const TrajectoryPtrPool &a, const TrajectoryPtrPool &b) {
  400. std::vector<float> areaa(a.size());
  401. for (size_t i = 0; i < a.size(); ++i) {
  402. float w = a[i]->ltrb[2] - a[i]->ltrb[0];
  403. float h = a[i]->ltrb[3] - a[i]->ltrb[1];
  404. areaa[i] = w * h;
  405. }
  406. std::vector<float> areab(b.size());
  407. for (size_t j = 0; j < b.size(); ++j) {
  408. float w = b[j]->ltrb[2] - b[j]->ltrb[0];
  409. float h = b[j]->ltrb[3] - b[j]->ltrb[1];
  410. areab[j] = w * h;
  411. }
  412. cv::Mat dists(a.size(), b.size(), CV_32F);
  413. for (size_t i = 0; i < a.size(); ++i) {
  414. const cv::Vec4f &boxa = a[i]->ltrb;
  415. float *distsi = dists.ptr<float>(i);
  416. for (size_t j = 0; j < b.size(); ++j) {
  417. const cv::Vec4f &boxb = b[j]->ltrb;
  418. float inters = calc_inter_area(boxa, boxb);
  419. distsi[j] = 1.f - inters / (areaa[i] + areab[j] - inters);
  420. }
  421. }
  422. return dists;
  423. }
  424. cv::Mat iou_distance(const TrajectoryPtrPool &a, const TrajectoryPool &b) {
  425. std::vector<float> areaa(a.size());
  426. for (size_t i = 0; i < a.size(); ++i) {
  427. float w = a[i]->ltrb[2] - a[i]->ltrb[0];
  428. float h = a[i]->ltrb[3] - a[i]->ltrb[1];
  429. areaa[i] = w * h;
  430. }
  431. std::vector<float> areab(b.size());
  432. for (size_t j = 0; j < b.size(); ++j) {
  433. float w = b[j].ltrb[2] - b[j].ltrb[0];
  434. float h = b[j].ltrb[3] - b[j].ltrb[1];
  435. areab[j] = w * h;
  436. }
  437. cv::Mat dists(a.size(), b.size(), CV_32F);
  438. for (size_t i = 0; i < a.size(); ++i) {
  439. const cv::Vec4f &boxa = a[i]->ltrb;
  440. float *distsi = dists.ptr<float>(i);
  441. for (size_t j = 0; j < b.size(); ++j) {
  442. const cv::Vec4f &boxb = b[j].ltrb;
  443. float inters = calc_inter_area(boxa, boxb);
  444. distsi[j] = 1.f - inters / (areaa[i] + areab[j] - inters);
  445. }
  446. }
  447. return dists;
  448. }
  449. } // namespace tracking
  450. } // namespace vision
  451. } // namespace ultra_infer