gapi_ot_tests_cpu.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287
  1. // This file is part of OpenCV project.
  2. // It is subject to the license terms in the LICENSE file found in the top-level directory
  3. // of this distribution and at http://opencv.org/license.html.
  4. //
  5. // Copyright (C) 2023 Intel Corporation
  6. #include "../test_precomp.hpp"
  7. #include <opencv2/gapi/ot.hpp>
  8. #include <opencv2/gapi/cpu/ot.hpp>
  9. #include "opencv2/gapi/streaming/meta.hpp"
  10. #include "opencv2/gapi/streaming/cap.hpp"
  11. namespace {
  12. cv::gapi::ot::TrackingStatus from_string(const std::string& status) {
  13. if (status == "NEW") {
  14. return cv::gapi::ot::TrackingStatus::NEW;
  15. }
  16. else if (status == "TRACKED") {
  17. return cv::gapi::ot::TrackingStatus::TRACKED;
  18. }
  19. else if (status == "LOST") {
  20. return cv::gapi::ot::TrackingStatus::LOST;
  21. }
  22. throw std::runtime_error("String representation for cv::gapi::ot::TrackingStatus: \""
  23. + status + "\" contains incorrect value!");
  24. }
  25. } // anonymous namespace
  26. namespace opencv_test {
  27. struct FrameDetections {
  28. std::size_t frame_no{};
  29. std::vector<std::vector<cv::Rect>> boxes;
  30. std::vector<std::vector<int32_t>> box_ids;
  31. FrameDetections() {}
  32. FrameDetections(std::size_t in_frame_no, const std::vector<std::vector<cv::Rect>>& in_boxes,
  33. const std::vector<std::vector<int32_t>>& in_box_ids) :
  34. frame_no(in_frame_no),
  35. boxes(in_boxes),
  36. box_ids(in_box_ids) {}
  37. };
  38. struct TrackerReference {
  39. std::size_t frame_no{};
  40. std::vector<std::vector<cv::Rect>> tracked_boxes;
  41. std::vector<std::vector<int32_t>> tracked_box_ids;
  42. std::vector<std::vector<uint64_t>> tracking_ids;
  43. std::vector<std::vector<cv::gapi::ot::TrackingStatus>> tracking_statuses;
  44. TrackerReference() {}
  45. TrackerReference(std::size_t in_frame_no,
  46. const std::vector<std::vector<cv::Rect>>& in_tracked_boxes,
  47. const std::vector<std::vector<int32_t>>& in_tracked_box_ids,
  48. const std::vector<std::vector<uint64_t>>& in_tracking_ids,
  49. const std::vector<std::vector<cv::gapi::ot::TrackingStatus>>&
  50. in_tracking_statuses) :
  51. frame_no(in_frame_no),
  52. tracked_boxes(in_tracked_boxes),
  53. tracked_box_ids(in_tracked_box_ids),
  54. tracking_ids(in_tracking_ids),
  55. tracking_statuses(in_tracking_statuses) {}
  56. };
  57. struct FrameDetectionsParams {
  58. FrameDetections value;
  59. };
  60. struct TrackerReferenceParams {
  61. TrackerReference value;
  62. };
  63. } // namespace opencv_test
  64. namespace cv {
  65. namespace detail {
  66. template<> struct CompileArgTag<opencv_test::FrameDetectionsParams> {
  67. static const char* tag() {
  68. return "org.opencv.test.frame_detections_params";
  69. }
  70. };
  71. } // namespace detail
  72. namespace detail {
  73. template<> struct CompileArgTag<opencv_test::TrackerReferenceParams> {
  74. static const char* tag() {
  75. return "org.opencv.test.tracker_reference_params";
  76. }
  77. };
  78. } // namespace detail
  79. } // namespace cv
  80. namespace opencv_test {
  81. G_API_OP(CvVideo768x576_Detect, <std::tuple<cv::GArray<cv::Rect>, cv::GArray<int32_t>>(cv::GMat)>,
  82. "test.custom.cv_video_768x576_detect") {
  83. static std::tuple<cv::GArrayDesc, cv::GArrayDesc> outMeta(cv::GMatDesc) {
  84. return std::make_tuple(cv::empty_array_desc(), cv::empty_array_desc());
  85. }
  86. };
  87. GAPI_OCV_KERNEL_ST(OCV_CvVideo768x576_Detect, CvVideo768x576_Detect, FrameDetections) {
  88. static void setup(cv::GMatDesc,
  89. std::shared_ptr<FrameDetections> &state,
  90. const cv::GCompileArgs &compileArgs) {
  91. auto params = cv::gapi::getCompileArg<opencv_test::FrameDetectionsParams>(compileArgs)
  92. .value_or(opencv_test::FrameDetectionsParams{ });
  93. state = std::make_shared<FrameDetections>(params.value);
  94. }
  95. static void run(const cv::Mat&,
  96. std::vector<cv::Rect> &out_boxes,
  97. std::vector<int32_t> &out_box_ids,
  98. FrameDetections &state) {
  99. if (state.frame_no < state.boxes.size()) {
  100. out_boxes = state.boxes[state.frame_no];
  101. out_box_ids = state.box_ids[state.frame_no];
  102. ++state.frame_no;
  103. }
  104. }
  105. };
  106. G_API_OP(CheckTrackerResults, <cv::GOpaque<bool>(cv::GArray<cv::Rect>, cv::GArray<int32_t>,
  107. cv::GArray<uint64_t>, cv::GArray<int>)>,
  108. "test.custom.check_tracker_results") {
  109. static cv::GOpaqueDesc outMeta(cv::GArrayDesc, cv::GArrayDesc, cv::GArrayDesc, cv::GArrayDesc) {
  110. return cv::empty_gopaque_desc();
  111. }
  112. };
  113. GAPI_OCV_KERNEL_ST(OCVCheckTrackerResults, CheckTrackerResults, TrackerReference) {
  114. static void setup(cv::GArrayDesc, cv::GArrayDesc,
  115. cv::GArrayDesc, cv::GArrayDesc,
  116. std::shared_ptr<TrackerReference> &state,
  117. const cv::GCompileArgs &compileArgs) {
  118. auto params = cv::gapi::getCompileArg<opencv_test::TrackerReferenceParams>(compileArgs)
  119. .value_or(opencv_test::TrackerReferenceParams{ });
  120. state = std::make_shared<TrackerReference>(params.value);
  121. }
  122. static void run(const std::vector<cv::Rect> &in_tr_rcts,
  123. const std::vector<int32_t> &in_det_ids,
  124. const std::vector<uint64_t> &in_tr_ids,
  125. const std::vector<int> &in_tr_statuses,
  126. bool& success,
  127. TrackerReference& state) {
  128. if (state.frame_no < state.tracked_boxes.size()) {
  129. auto reference_boxes = state.tracked_boxes[state.frame_no];
  130. auto reference_box_ids = state.tracked_box_ids[state.frame_no];
  131. auto reference_tr_ids = state.tracking_ids[state.frame_no];
  132. auto reference_tr_statuses = state.tracking_statuses[state.frame_no];
  133. success = true;
  134. GAPI_Assert(in_tr_rcts.size() == reference_boxes.size());
  135. GAPI_Assert(in_det_ids.size() == reference_box_ids.size());
  136. GAPI_Assert(in_tr_ids.size() == reference_tr_ids.size());
  137. GAPI_Assert(in_tr_statuses.size() == reference_tr_statuses.size());
  138. for (uint32_t i = 0; (i < in_tr_rcts.size() && success); ++i) {
  139. const cv::Rect& reference_rc = reference_boxes[i];
  140. const cv::Rect& in_rc = in_tr_rcts[i];
  141. success &= (reference_rc == in_rc);
  142. success &= (reference_box_ids[i] == in_det_ids[i]);
  143. success &= (reference_tr_ids[i] == in_tr_ids[i]);
  144. success &= (reference_tr_statuses[i] == in_tr_statuses[i]);
  145. }
  146. ++state.frame_no;
  147. }
  148. else {
  149. success = true;
  150. }
  151. }
  152. };
  153. TEST(VASObjectTracker, PipelineTest)
  154. {
  155. constexpr int32_t frames_to_handle = 30;
  156. std::string pathToVideo = opencv_test::findDataFile("cv/video/768x576.avi");
  157. std::vector<std::vector<cv::Rect>> input_boxes(frames_to_handle);
  158. std::vector<std::vector<int32_t>> input_det_ids(frames_to_handle);
  159. std::string path_to_boxes = opencv_test::findDataFile("cv/video/vas_object_tracking/detections_30_frames.yml");
  160. cv::FileStorage fs_input_boxes(path_to_boxes, cv::FileStorage::READ);
  161. cv::FileNode fn_input_boxes = fs_input_boxes.root();
  162. for (auto it = fn_input_boxes.begin(); it != fn_input_boxes.end(); ++it) {
  163. cv::FileNode fn_frame = *it;
  164. std::string frame_name = fn_frame.name();
  165. int frame_no = std::stoi(frame_name.substr(frame_name.find("_") + 1));
  166. for (auto fit = fn_frame.begin(); fit != fn_frame.end(); ++fit) {
  167. cv::FileNode fn_box = *fit;
  168. cv::Rect box((int)fn_box["x"], (int)fn_box["y"],
  169. (int)fn_box["width"], (int)fn_box["height"]);
  170. input_boxes[frame_no].push_back(box);
  171. input_det_ids[frame_no].push_back(fn_box["id"]);
  172. }
  173. }
  174. std::vector<std::vector<cv::Rect>> reference_trackings(frames_to_handle);
  175. std::vector<std::vector<int32_t>> reference_trackings_det_ids(frames_to_handle);
  176. std::vector<std::vector<uint64_t>> reference_trackings_tr_ids(frames_to_handle);
  177. std::vector<std::vector<cv::gapi::ot::TrackingStatus>> reference_trackings_tr_statuses(frames_to_handle);
  178. std::string path_to_trackings = opencv_test::findDataFile("cv/video/vas_object_tracking/trackings_30_frames.yml");
  179. cv::FileStorage fs_reference_trackings(path_to_trackings, cv::FileStorage::READ);
  180. cv::FileNode fn_reference_trackings = fs_reference_trackings.root();
  181. for (auto it = fn_reference_trackings.begin(); it != fn_reference_trackings.end(); ++it) {
  182. cv::FileNode fn_frame = *it;
  183. std::string frame_name = fn_frame.name();
  184. int frame_no = std::stoi(frame_name.substr(frame_name.find("_") + 1));
  185. for (auto fit = fn_frame.begin(); fit != fn_frame.end(); ++fit) {
  186. cv::FileNode fn_tracked_box = *fit;
  187. cv::Rect tracked_box((int)fn_tracked_box["x"], (int)fn_tracked_box["y"],
  188. (int)fn_tracked_box["width"], (int)fn_tracked_box["height"]);
  189. reference_trackings[frame_no].push_back(tracked_box);
  190. reference_trackings_det_ids[frame_no].push_back(fn_tracked_box["id"]);
  191. reference_trackings_tr_ids[frame_no].push_back(int(fn_tracked_box["tracking_id"]));
  192. reference_trackings_tr_statuses[frame_no].push_back(
  193. from_string(fn_tracked_box["tracking_status"]));
  194. }
  195. }
  196. cv::GMat in;
  197. cv::GArray<cv::Rect> detections;
  198. cv::GArray<int> det_ids;
  199. std::tie(detections, det_ids) = CvVideo768x576_Detect::on(in);
  200. constexpr float delta_time = 0.055f;
  201. cv::GArray<cv::Rect> tracking_rects;
  202. cv::GArray<int32_t> tracking_det_ids;
  203. cv::GArray<uint64_t> tracking_ids;
  204. cv::GArray<int> tracking_statuses;
  205. std::tie(tracking_rects, tracking_det_ids, tracking_ids, tracking_statuses) =
  206. cv::gapi::ot::track(in, detections, det_ids, delta_time);
  207. cv::GOpaque<bool> check_result =
  208. CheckTrackerResults::on(tracking_rects, tracking_det_ids, tracking_ids, tracking_statuses);
  209. cv::GComputation ccomp(cv::GIn(in), cv::GOut(check_result));
  210. opencv_test::FrameDetections fds { 0, input_boxes, input_det_ids };
  211. opencv_test::TrackerReference tr { 0, reference_trackings,
  212. reference_trackings_det_ids,
  213. reference_trackings_tr_ids,
  214. reference_trackings_tr_statuses };
  215. // Graph compilation for streaming mode:
  216. auto compiled =
  217. ccomp.compileStreaming(cv::compile_args(
  218. cv::gapi::combine(cv::gapi::kernels<OCV_CvVideo768x576_Detect,
  219. OCVCheckTrackerResults>(),
  220. cv::gapi::ot::cpu::kernels()),
  221. opencv_test::FrameDetectionsParams{ fds },
  222. opencv_test::TrackerReferenceParams{ tr }));
  223. EXPECT_TRUE(compiled);
  224. EXPECT_FALSE(compiled.running());
  225. compiled.setSource<cv::gapi::wip::GCaptureSource>(pathToVideo);
  226. // Start of streaming:
  227. compiled.start();
  228. EXPECT_TRUE(compiled.running());
  229. // Streaming:
  230. bool success;
  231. std::size_t counter { }, limit { 30 };
  232. while(compiled.pull(cv::gout(success)) && (counter < limit)) {
  233. ++counter;
  234. }
  235. compiled.stop();
  236. EXPECT_TRUE(success);
  237. EXPECT_FALSE(compiled.running());
  238. }
  239. } // namespace opencv_test