test_track.cpp 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479
  1. /*************************************************************************
  2. * Copyright (C) [2019] by Cambricon, Inc. All rights reserved
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * The above copyright notice and this permission notice shall be included in
  11. * all copies or substantial portions of the Software.
  12. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  13. * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  14. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  15. * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  16. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  17. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  18. * THE SOFTWARE.
  19. *************************************************************************/
  20. #include <gtest/gtest.h>
  21. #include <memory>
  22. #include <string>
  23. #include <vector>
  24. #include "opencv2/highgui/highgui.hpp"
  25. #include "opencv2/imgproc/imgproc.hpp"
  26. #if (CV_MAJOR_VERSION >= 3)
  27. #include "opencv2/imgcodecs/imgcodecs.hpp"
  28. #endif
  29. #include "cnis/processor.h"
  30. #include "cnstream_frame_va.hpp"
  31. #include "cnstream_module.hpp"
  32. #include "device/mlu_context.h"
  33. #include "easyinfer/mlu_memory_op.h"
  34. #include "test_base.hpp"
  35. #include "track.hpp"
  36. namespace cnstream {
  37. static std::string GetDSModelPath() {
  38. if (infer_server::Predictor::Backend() == "magicmind") {
  39. return "../../data/models/feature_extract_nhwc.model";
  40. }
  41. edk::MluContext ctx;
  42. edk::CoreVersion core_ver = ctx.GetCoreVersion();
  43. std::string model_path = "";
  44. switch (core_ver) {
  45. case edk::CoreVersion::MLU220:
  46. model_path = "../../data/models/feature_extract_for_tracker_b4c4_argb_mlu220.cambricon";
  47. break;
  48. case edk::CoreVersion::MLU270:
  49. default:
  50. model_path = "../../data/models/feature_extract_for_tracker_b4c4_argb_mlu270.cambricon";
  51. break;
  52. }
  53. return model_path;
  54. }
  55. static constexpr const char* g_model_graph = "../../data/models/feature_extract_nhwc.graph";
  56. static constexpr const char* g_model_data = "../../data/models/feature_extract_nhwc.data";
  57. static constexpr const char *gname = "track";
  58. static constexpr const char *gfunc_name = "subnet0";
  59. static constexpr const char *ds_track = "FeatureMatch";
  60. static constexpr const char *img_path = "../../data/images/19.jpg";
  61. static constexpr int g_dev_id = 0;
  62. static constexpr int g_channel_id = 0;
  63. static constexpr float g_max_cosine_distance = 0.2f;
  64. TEST(Tracker, Construct) {
  65. std::shared_ptr<Module> track = std::make_shared<Tracker>(gname);
  66. EXPECT_STREQ(track->GetName().c_str(), gname);
  67. }
  68. TEST(Tracker, CheckParamSet) {
  69. std::shared_ptr<Module> track = std::make_shared<Tracker>(gname);
  70. ModuleParamSet param;
  71. EXPECT_TRUE(track->CheckParamSet(param));
  72. param["model_path"] = "fake_path";
  73. EXPECT_FALSE(track->CheckParamSet(param));
  74. param["device_id"] = "fake_id";
  75. EXPECT_FALSE(track->CheckParamSet(param));
  76. bool use_magicmind = infer_server::Predictor::Backend() == "magicmind";
  77. if (use_magicmind) {
  78. param["model_path"] = GetExePath() + GetDSModelPath();
  79. } else {
  80. param["model_path"] = GetExePath() + GetDSModelPath();
  81. param["func_name"] = gfunc_name;
  82. }
  83. param["device_id"] = std::to_string(g_dev_id);
  84. EXPECT_TRUE(track->CheckParamSet(param));
  85. param["max_cosine_distance"] = "fake_distance";
  86. EXPECT_FALSE(track->CheckParamSet(param));
  87. param["max_cosine_distance"] = std::to_string(g_max_cosine_distance);
  88. EXPECT_TRUE(track->CheckParamSet(param));
  89. }
  90. TEST(Tracker, OpenClose) {
  91. std::shared_ptr<Module> track = std::make_shared<Tracker>(gname);
  92. ModuleParamSet param;
  93. // Deep Sort On CPU
  94. param["track_name"] = ds_track;
  95. EXPECT_TRUE(track->Open(param));
  96. // Defaul param
  97. param.clear();
  98. EXPECT_TRUE(track->Open(param));
  99. // FeatureMatch On MLU
  100. param["track_name"] = ds_track;
  101. bool use_magicmind = infer_server::Predictor::Backend() == "magicmind";
  102. if (use_magicmind) {
  103. param["model_path"] = GetExePath() + GetDSModelPath();
  104. } else {
  105. param["model_path"] = GetExePath() + GetDSModelPath();
  106. param["func_name"] = gfunc_name;
  107. }
  108. EXPECT_TRUE(track->Open(param));
  109. track->Close();
  110. }
  111. std::shared_ptr<CNFrameInfo> GenTestData(int iter, int obj_num) {
  112. // prepare data
  113. int width = 1920;
  114. int height = 1080;
  115. cv::Mat img(height, width, CV_8UC3, cv::Scalar(0, 0, 0));
  116. auto data = cnstream::CNFrameInfo::Create(std::to_string(0));
  117. data->SetStreamIndex(g_channel_id);
  118. std::shared_ptr<CNDataFrame> frame(new (std::nothrow) CNDataFrame());
  119. frame->frame_id = 1;
  120. data->timestamp = 1000;
  121. frame->width = width;
  122. frame->height = height;
  123. void* ptr_cpu[1] = {img.data};
  124. frame->stride[0] = width;
  125. frame->ctx.dev_type = DevContext::DevType::CPU;
  126. frame->fmt = CNDataFormat::CN_PIXEL_FORMAT_BGR24;
  127. frame->dst_device_id = g_dev_id;
  128. frame->CopyToSyncMem(ptr_cpu, true);
  129. std::shared_ptr<CNInferObjs> objs_holder = std::make_shared<CNInferObjs>();
  130. for (int i = 0; i < obj_num; ++i) {
  131. auto obj = std::make_shared<CNInferObject>();
  132. obj->id = std::to_string(i);
  133. float val = i * 0.1 + 0.01;
  134. CNInferBoundingBox bbox = {val, val, val, val};
  135. obj->bbox = bbox;
  136. objs_holder->objs_.push_back(obj);
  137. }
  138. data->collection.Add(kCNDataFrameTag, frame);
  139. data->collection.Add(kCNInferObjsTag, objs_holder);
  140. return data;
  141. }
  142. std::shared_ptr<CNFrameInfo> GenTestYUVData(int iter, int obj_num) {
  143. // prepare data
  144. int width = 1920;
  145. int height = 1080;
  146. cv::Mat img(height + height / 2, width, CV_8UC1);
  147. auto data = cnstream::CNFrameInfo::Create(std::to_string(0));
  148. data->SetStreamIndex(g_channel_id);
  149. std::shared_ptr<CNDataFrame> frame(new (std::nothrow) CNDataFrame());
  150. frame->frame_id = 1;
  151. data->timestamp = 1000;
  152. frame->width = width;
  153. frame->height = height;
  154. void* ptr_cpu[2] = {img.data, img.data + height * width};
  155. frame->stride[0] = width;
  156. frame->stride[1] = width;
  157. frame->ctx.dev_type = DevContext::DevType::CPU;
  158. frame->fmt = CNDataFormat::CN_PIXEL_FORMAT_YUV420_NV21;
  159. frame->dst_device_id = g_dev_id;
  160. frame->CopyToSyncMem(ptr_cpu, true);
  161. std::shared_ptr<CNInferObjs> objs_holder = std::make_shared<CNInferObjs>();
  162. for (int i = 0; i < obj_num; ++i) {
  163. auto obj = std::make_shared<CNInferObject>();
  164. obj->id = std::to_string(i);
  165. float val = i * 0.1 + 0.01;
  166. CNInferBoundingBox bbox = {val, val, val, val};
  167. obj->bbox = bbox;
  168. objs_holder->objs_.push_back(obj);
  169. }
  170. data->collection.Add(kCNDataFrameTag, frame);
  171. data->collection.Add(kCNInferObjsTag, objs_holder);
  172. return data;
  173. }
  174. std::shared_ptr<CNFrameInfo> GenTestImageData() {
  175. // prepare data
  176. cv::Mat img;
  177. std::string image_path = GetExePath() + img_path;
  178. img = cv::imread(image_path, cv::IMREAD_COLOR);
  179. auto data = cnstream::CNFrameInfo::Create("1", false);
  180. data->SetStreamIndex(g_channel_id);
  181. std::shared_ptr<CNDataFrame> frame(new (std::nothrow) CNDataFrame());
  182. frame->frame_id = 1;
  183. data->timestamp = 1000;
  184. frame->width = img.cols;
  185. frame->height = img.rows;
  186. void* ptr_cpu[1] = {img.data};
  187. frame->stride[0] = img.cols;
  188. frame->ctx.dev_type = DevContext::DevType::CPU;
  189. frame->fmt = CNDataFormat::CN_PIXEL_FORMAT_BGR24;
  190. frame->dst_device_id = g_dev_id;
  191. frame->CopyToSyncMem(ptr_cpu, true);
  192. std::shared_ptr<CNInferObjs> objs_holder = std::make_shared<CNInferObjs>();
  193. auto obj = std::make_shared<CNInferObject>();
  194. obj->id = std::to_string(1);
  195. CNInferBoundingBox bbox = {0.2, 0.2, 0.6, 0.6};
  196. obj->bbox = bbox;
  197. objs_holder->objs_.push_back(obj);
  198. data->collection.Add(kCNDataFrameTag, frame);
  199. data->collection.Add(kCNInferObjsTag, objs_holder);
  200. return data;
  201. }
  202. TEST(Tracker, ProcessMluFeature) {
  203. // create track
  204. std::shared_ptr<Module> track = std::make_shared<Tracker>(gname);
  205. ModuleParamSet param;
  206. param["track_name"] = ds_track;
  207. bool use_magicmind = infer_server::Predictor::Backend() == "magicmind";
  208. if (use_magicmind) {
  209. param["model_path"] = GetExePath() + GetDSModelPath();
  210. } else {
  211. param["model_path"] = GetExePath() + GetDSModelPath();
  212. param["func_name"] = gfunc_name;
  213. }
  214. ASSERT_TRUE(track->Open(param));
  215. int obj_num = 4;
  216. int repeat_time = 10;
  217. for (int n = 0; n < repeat_time; ++n) {
  218. auto data = GenTestYUVData(n, obj_num);
  219. EXPECT_EQ(track->Process(data), 0);
  220. // send eos to ensure data process done
  221. auto eos = cnstream::CNFrameInfo::Create(std::to_string(0), true);
  222. eos->SetStreamIndex(g_channel_id);
  223. EXPECT_EQ(track->Process(eos), 0);
  224. CNInferObjsPtr objs_holder = data->collection.Get<CNInferObjsPtr>(kCNInferObjsTag);
  225. for (size_t idx = 0; idx < objs_holder->objs_.size(); ++idx) {
  226. auto& obj = objs_holder->objs_[idx];
  227. EXPECT_FALSE(obj->track_id.empty());
  228. }
  229. }
  230. }
  231. TEST(Tracker, ProcessCpuFeature) {
  232. // create track
  233. std::shared_ptr<Module> track = std::make_shared<Tracker>(gname);
  234. ModuleParamSet param;
  235. ASSERT_TRUE(track->Open(param));
  236. int repeat_time = 1;
  237. auto data = GenTestImageData();
  238. for (int n = 0; n < repeat_time; ++n) {
  239. EXPECT_EQ(track->Process(data), 0);
  240. CNInferObjsPtr objs_holder = data->collection.Get<CNInferObjsPtr>(kCNInferObjsTag);
  241. for (size_t idx = 0; idx < objs_holder->objs_.size(); ++idx) {
  242. auto& obj = objs_holder->objs_[idx];
  243. EXPECT_FALSE(obj->track_id.empty());
  244. }
  245. }
  246. }
  247. TEST(Tracker, ProcessFeatureMatchCPU0) {
  248. // create track
  249. std::shared_ptr<Module> track = std::make_shared<Tracker>(gname);
  250. ModuleParamSet param;
  251. param["track_name"] = "FeatureMatch";
  252. ASSERT_TRUE(track->Open(param));
  253. int iter = 0;
  254. int obj_num = 3;
  255. auto data = GenTestData(iter, obj_num);
  256. EXPECT_EQ(track->Process(data), 0);
  257. }
  258. TEST(Tracker, ProcessFeatureMatchCPU1) {
  259. // create track
  260. std::shared_ptr<Module> track = std::make_shared<Tracker>(gname);
  261. ModuleParamSet param;
  262. param["track_name"] = "FeatureMatch";
  263. ASSERT_TRUE(track->Open(param));
  264. int iter = 0;
  265. int obj_num = 3;
  266. auto data = GenTestData(iter, obj_num);
  267. EXPECT_EQ(track->Process(data), 0);
  268. // Illegal width and height
  269. CNDataFramePtr frame = data->collection.Get<CNDataFramePtr>(kCNDataFrameTag);
  270. frame->width = -1;
  271. EXPECT_EQ(track->Process(data), -1);
  272. frame->width = 1920;
  273. EXPECT_EQ(track->Process(data), 0);
  274. frame->height = -1;
  275. EXPECT_EQ(track->Process(data), -1);
  276. frame->height = 1080;
  277. EXPECT_EQ(track->Process(data), 0);
  278. frame->width = 1920;
  279. frame->height = 1080;
  280. EXPECT_EQ(track->Process(data), 0);
  281. }
  282. TEST(Tracker, ProcessFeatureMatchCPU2) {
  283. // create track
  284. std::shared_ptr<Module> track = std::make_shared<Tracker>(gname);
  285. ModuleParamSet param;
  286. param["track_name"] = "FeatureMatch";
  287. ASSERT_TRUE(track->Open(param));
  288. int iter = 0;
  289. int obj_num = 3;
  290. auto data = GenTestData(iter, obj_num);
  291. EXPECT_EQ(track->Process(data), 0);
  292. CNInferObjsPtr objs_holder = data->collection.Get<CNInferObjsPtr>(kCNInferObjsTag);
  293. auto obj = std::make_shared<CNInferObject>();
  294. obj->id = std::to_string(5);
  295. CNInferBoundingBox bbox = {0.6, 0.6, -0.1, -0.1};
  296. obj->bbox = bbox;
  297. objs_holder->objs_.push_back(obj);
  298. EXPECT_EQ(track->Process(data), 0);
  299. }
  300. TEST(Tracker, ProcessFeatureMatchCPU3) {
  301. // create track
  302. std::shared_ptr<Module> track = std::make_shared<Tracker>(gname);
  303. ModuleParamSet param;
  304. param["track_name"] = "FeatureMatch";
  305. ASSERT_TRUE(track->Open(param));
  306. int iter = 0;
  307. int obj_num = 3;
  308. auto data = GenTestData(iter, obj_num);
  309. EXPECT_EQ(track->Process(data), 0);
  310. CNInferObjsPtr objs_holder = data->collection.Get<CNInferObjsPtr>(kCNInferObjsTag);
  311. auto obj = std::make_shared<CNInferObject>();
  312. obj->id = std::to_string(6);
  313. CNInferBoundingBox bbox = {0.6, 0.6, 0.6, 0.6};
  314. obj->bbox = bbox;
  315. objs_holder->objs_.push_back(obj);
  316. EXPECT_EQ(track->Process(data), 0);
  317. }
  318. TEST(Tracker, ProcessFeatureMatchCPU4) {
  319. // create track
  320. std::shared_ptr<Module> track = std::make_shared<Tracker>(gname);
  321. ModuleParamSet param;
  322. param["track_name"] = "FeatureMatch";
  323. ASSERT_TRUE(track->Open(param));
  324. int obj_num = 4;
  325. int repeat_time = 10;
  326. for (int n = 0; n < repeat_time; ++n) {
  327. auto data = GenTestData(n, obj_num);
  328. EXPECT_EQ(track->Process(data), 0);
  329. CNInferObjsPtr objs_holder = data->collection.Get<CNInferObjsPtr>(kCNInferObjsTag);
  330. for (size_t idx = 0; idx < objs_holder->objs_.size(); ++idx) {
  331. auto& obj = objs_holder->objs_[idx];
  332. EXPECT_FALSE(obj->track_id.empty());
  333. }
  334. }
  335. }
  336. TEST(Tracker, ProcessFeatureMatchMLU1) {
  337. // create track
  338. std::shared_ptr<Module> track = std::make_shared<Tracker>(gname);
  339. ModuleParamSet param;
  340. param["track_name"] = "FeatureMatch";
  341. bool use_magicmind = infer_server::Predictor::Backend() == "magicmind";
  342. if (use_magicmind) {
  343. param["model_path"] = GetExePath() + GetDSModelPath();
  344. } else {
  345. param["model_path"] = GetExePath() + GetDSModelPath();
  346. param["func_name"] = gfunc_name;
  347. }
  348. ASSERT_TRUE(track->Open(param));
  349. int iter = 0;
  350. int obj_num = 3;
  351. auto data = GenTestYUVData(iter, obj_num);
  352. CNDataFramePtr frame = data->collection.Get<CNDataFramePtr>(kCNDataFrameTag);
  353. // invalid fmt
  354. frame->fmt = CNDataFormat::CN_PIXEL_FORMAT_RGB24;
  355. EXPECT_EQ(track->Process(data), -1);
  356. frame->fmt = CNDataFormat::CN_PIXEL_FORMAT_BGR24;
  357. EXPECT_EQ(track->Process(data), -1);
  358. frame->fmt = CNDataFormat::CN_PIXEL_FORMAT_YUV420_NV21;
  359. // invalid width and height
  360. frame->width = -1;
  361. EXPECT_EQ(track->Process(data), -1);
  362. frame->height = -1;
  363. EXPECT_EQ(track->Process(data), -1);
  364. }
  365. TEST(Tracker, ProcessFeatureMatchMLU2) {
  366. // create track
  367. std::shared_ptr<Module> track = std::make_shared<Tracker>(gname);
  368. ModuleParamSet param;
  369. param["track_name"] = "FeatureMatch";
  370. bool use_magicmind = infer_server::Predictor::Backend() == "magicmind";
  371. if (use_magicmind) {
  372. param["model_path"] = GetExePath() + GetDSModelPath();
  373. } else {
  374. param["model_path"] = GetExePath() + GetDSModelPath();
  375. param["func_name"] = gfunc_name;
  376. }
  377. ASSERT_TRUE(track->Open(param));
  378. int iter = 0;
  379. int obj_num = 0;
  380. auto data = GenTestYUVData(iter, obj_num);
  381. EXPECT_EQ(track->Process(data), 0);
  382. // send eos to ensure data process done
  383. auto eos = cnstream::CNFrameInfo::Create(std::to_string(0), true);
  384. eos->SetStreamIndex(g_channel_id);
  385. EXPECT_EQ(track->Process(eos), 0);
  386. size_t zero = 0;
  387. CNInferObjsPtr objs_holder = data->collection.Get<CNInferObjsPtr>(kCNInferObjsTag);
  388. EXPECT_EQ(objs_holder->objs_.size(), zero);
  389. }
  390. TEST(Tracker, ProcessFeatureMatchMLU3) {
  391. // create track
  392. std::shared_ptr<Module> track = std::make_shared<Tracker>(gname);
  393. ModuleParamSet param;
  394. param["track_name"] = "FeatureMatch";
  395. bool use_magicmind = infer_server::Predictor::Backend() == "magicmind";
  396. if (use_magicmind) {
  397. param["model_graph"] = GetExePath() + g_model_graph;
  398. param["model_data"] = GetExePath() + g_model_data;
  399. } else {
  400. param["model_path"] = GetExePath() + GetDSModelPath();
  401. param["func_name"] = gfunc_name;
  402. }
  403. ASSERT_TRUE(track->Open(param));
  404. int repeat_time = 10;
  405. int obj_num = 4;
  406. std::vector<CNFrameInfoPtr> datas(10);
  407. for (int n = 0; n < repeat_time; ++n) {
  408. datas[n] = GenTestYUVData(n, obj_num);
  409. EXPECT_EQ(track->Process(datas[n]), 0);
  410. }
  411. // send eos to ensure data process done
  412. auto eos = cnstream::CNFrameInfo::Create(std::to_string(0), true);
  413. eos->SetStreamIndex(g_channel_id);
  414. EXPECT_EQ(track->Process(eos), 0);
  415. for (int n = 0; n < repeat_time; ++n) {
  416. auto& data = datas[n];
  417. CNInferObjsPtr objs_holder = data->collection.Get<CNInferObjsPtr>(kCNInferObjsTag);
  418. for (size_t idx = 0; idx < objs_holder->objs_.size(); ++idx) {
  419. auto& obj = objs_holder->objs_[idx];
  420. EXPECT_FALSE(obj->track_id.empty());
  421. }
  422. }
  423. }
  424. } // namespace cnstream