demo.cpp 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. /*************************************************************************
  2. * Copyright (C) [2020] 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 <opencv2/opencv.hpp>
  21. #include <memory>
  22. #include <utility>
  23. #include <vector>
  24. #include "cnis/contrib/opencv_frame.h"
  25. #include "cnis/contrib/video_helper.h"
  26. #include "cnis/infer_server.h"
  27. #include "cnis/processor.h"
  28. #ifdef CNIS_USE_MAGICMIND
  29. constexpr const char* g_model_path =
  30. "http://video.cambricon.com/models/MLU370/yolov3_nhwc_tfu_0.5_int8_fp16.model";
  31. #else
  32. constexpr const char* g_model_path =
  33. "http://video.cambricon.com/models/MLU270/Primary_Detector/ssd/resnet34_ssd.cambricon";
  34. #endif
  35. struct DetectObject {
  36. int label;
  37. float score;
  38. infer_server::video::BoundingBox bbox;
  39. };
  40. struct PostprocSSD {
  41. float threshold;
  42. explicit PostprocSSD(float _threshold) : threshold(_threshold) {}
  43. inline float Clip(float x) { return x < 0 ? 0 : (x > 1 ? 1 : x); }
  44. bool operator()(infer_server::InferData* result, const infer_server::ModelIO& model_output,
  45. const infer_server::ModelInfo& model) {
  46. std::vector<DetectObject> objs;
  47. const float* data = reinterpret_cast<const float*>(model_output.buffers[0].Data());
  48. int box_num = data[0];
  49. data += 64;
  50. for (int bi = 0; bi < box_num; ++bi) {
  51. DetectObject obj;
  52. if (data[1] == 0) continue;
  53. obj.label = data[1] - 1;
  54. obj.score = data[2];
  55. if (threshold > 0 && obj.score < threshold) continue;
  56. obj.bbox.x = Clip(data[3]);
  57. obj.bbox.y = Clip(data[4]);
  58. obj.bbox.w = Clip(data[5]) - obj.bbox.x;
  59. obj.bbox.h = Clip(data[6]) - obj.bbox.y;
  60. objs.emplace_back(std::move(obj));
  61. data += 7;
  62. }
  63. result->Set(std::move(objs));
  64. return true;
  65. }
  66. };
  67. class PrintResult : public infer_server::Observer {
  68. void Response(infer_server::Status status, infer_server::PackagePtr out, infer_server::any user_data) noexcept {
  69. int frame_index = infer_server::any_cast<int>(user_data);
  70. if (status != infer_server::Status::SUCCESS) {
  71. std::cerr << "Infer failed for frame index " << frame_index << std::endl;
  72. return;
  73. }
  74. for (auto& it : out->data) {
  75. const std::vector<DetectObject>& objs = it->GetLref<std::vector<DetectObject>>();
  76. if (objs.empty()) {
  77. std::cout << "@@@@@@@@@@@ No objects detected in frame " << frame_index << std::endl;
  78. continue;
  79. }
  80. std::cout << "------------ Detected objects in frame " << frame_index << std::endl;
  81. for (auto& obj : objs) {
  82. std::cout << "label: " << obj.label
  83. << "\t score: " << obj.score
  84. << "\t bbox: " << obj.bbox.x << ", " << obj.bbox.y << ", " << obj.bbox.w << ", " << obj.bbox.h
  85. << std::endl;
  86. }
  87. std::cout << "------------ Detected objects end -----------" << std::endl;
  88. }
  89. }
  90. };
  91. int main(int argc, char** argv) {
  92. if (argc != 2) {
  93. std::cerr << "USAGE: " << argv[0] << " path-to-video-file" << std::endl;
  94. return 0;
  95. }
  96. cv::VideoCapture source(argv[1]);
  97. if (!source.isOpened()) {
  98. std::cerr << "!!!!!!!! cannot open video file: " << argv[1] << std::endl;
  99. return -1;
  100. }
  101. // server by device id
  102. infer_server::InferServer server(0);
  103. infer_server::SessionDesc desc;
  104. desc.batch_timeout = 200;
  105. desc.strategy = infer_server::BatchStrategy::DYNAMIC;
  106. desc.name = "infer server demo";
  107. desc.show_perf = true;
  108. desc.preproc = infer_server::PreprocessorHost::Create();
  109. desc.postproc = infer_server::Postprocessor::Create();
  110. // config process function
  111. #ifdef CNIS_USE_MAGICMIND
  112. // load model
  113. desc.model = infer_server::InferServer::LoadModel(g_model_path);
  114. desc.preproc->SetParams("process_function",
  115. infer_server::video::OpencvPreproc::GetFunction(infer_server::video::PixelFmt::RGB24,
  116. {}, {}, true, true));
  117. #else
  118. desc.model = infer_server::InferServer::LoadModel(g_model_path);
  119. desc.preproc->SetParams("process_function",
  120. infer_server::video::OpencvPreproc::GetFunction(infer_server::video::PixelFmt::RGBA));
  121. #endif
  122. desc.postproc->SetParams("process_function", infer_server::Postprocessor::ProcessFunction(PostprocSSD(0.5)));
  123. infer_server::Session_t session = server.CreateSession(desc, std::make_shared<PrintResult>());
  124. cv::Mat frame;
  125. constexpr const char* tag = "opencv_stream0";
  126. int frame_index = 0;
  127. // read frame to infer
  128. while (source.read(frame)) {
  129. infer_server::video::OpencvFrame cv_frame;
  130. cv_frame.img = std::move(frame);
  131. cv_frame.fmt = infer_server::video::PixelFmt::BGR24;
  132. infer_server::PackagePtr input = std::make_shared<infer_server::Package>();
  133. input->data.emplace_back(new infer_server::InferData);
  134. input->data[0]->Set(std::move(cv_frame));
  135. input->tag = tag;
  136. if (!server.Request(session, input, frame_index++)) {
  137. std::cerr << "request failed" << std::endl;
  138. server.DestroySession(session);
  139. return -2;
  140. }
  141. // since old is moved, we create a new mat
  142. frame = cv::Mat();
  143. }
  144. server.WaitTaskDone(session, tag);
  145. server.DestroySession(session);
  146. return 0;
  147. }