Advertisement
ravijoshi53

7_synchronous_custom_input.cpp

Jan 19th, 2019
193
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 11.29 KB | None | 0 0
  1. // ------------------------- OpenPose C++ API Tutorial - Example 7 - XXXXXXXXXXXXX -------------------------
  2. // If the user wants to learn to use the OpenPose library, we highly recommend to start with the
  3. // examples in `examples/tutorial_api_cpp/`.
  4. // This example summarizes all the functionality of the OpenPose library:
  5.     // 1. Read folder of images / video / webcam  (`producer` module)
  6.     // 2. Extract and render body keypoint / heatmap / PAF of that image (`pose` module)
  7.     // 3. Extract and render face keypoint / heatmap / PAF of that image (`face` module)
  8.     // 4. Save the results on disk (`filestream` module)
  9.     // 5. Display the rendered pose (`gui` module)
  10.     // Everything in a multi-thread scenario (`thread` module)
  11.     // Points 2 to 5 are included in the `wrapper` module
  12. // In addition to the previous OpenPose modules, we also need to use:
  13.     // 1. `core` module:
  14.         // For the Array<float> class that the `pose` module needs
  15.         // For the Datum struct that the `thread` module sends between the queues
  16.     // 2. `utilities` module: for the error & logging functions, i.e., op::error & op::log respectively
  17. // This file should only be used for the user to take specific examples.
  18.  
  19. // Command-line user intraface
  20. #define OPENPOSE_FLAGS_DISABLE_PRODUCER
  21. #include <openpose/flags.hpp>
  22. // OpenPose dependencies
  23. #include <openpose/headers.hpp>
  24.  
  25. // Custom OpenPose flags
  26. // Producer
  27. DEFINE_string(image_dir, "examples/media/",
  28.     "Process a directory of images. Read all standard formats (jpg, png, bmp, etc.).");
  29.  
  30. // If the user needs his own variables, he can inherit the op::Datum struct and add them in there.
  31. // UserDatum can be directly used by the OpenPose wrapper because it inherits from op::Datum, just define
  32. // WrapperT<std::vector<UserDatum>> instead of Wrapper (or equivalently WrapperT<std::vector<UserDatum>>)
  33. struct UserDatum : public op::Datum
  34. {
  35.     bool boolThatUserNeedsForSomeReason;
  36.  
  37.     UserDatum(const bool boolThatUserNeedsForSomeReason_ = false) :
  38.         boolThatUserNeedsForSomeReason{boolThatUserNeedsForSomeReason_}
  39.     {}
  40. };
  41.  
  42. // The W-classes can be implemented either as a template or as simple classes given
  43. // that the user usually knows which kind of data he will move between the queues,
  44. // in this case we assume a std::shared_ptr of a std::vector of UserDatum
  45.  
  46. // This worker will just read and return all the jpg files in a directory
  47. class WUserInput : public op::WorkerProducer<std::shared_ptr<std::vector<UserDatum>>>
  48. {
  49. public:
  50.     WUserInput(const std::string& directoryPath) :
  51.         mImageFiles{op::getFilesOnDirectory(directoryPath, "jpg")},
  52.         // If we want "jpg" + "png" images
  53.         // mImageFiles{op::getFilesOnDirectory(directoryPath, std::vector<std::string>{"jpg", "png"})},
  54.         mCounter{0}
  55.     {
  56.         if (mImageFiles.empty())
  57.             op::error("No images found on: " + directoryPath, __LINE__, __FUNCTION__, __FILE__);
  58.     }
  59.  
  60.     void initializationOnThread() {}
  61.  
  62.     std::shared_ptr<std::vector<UserDatum>> workProducer()
  63.     {
  64.         try
  65.         {
  66.             // Close program when empty frame
  67.             if (mImageFiles.size() <= mCounter)
  68.             {
  69.                 op::log("Last frame read and added to queue. Closing program after it is processed.",
  70.                         op::Priority::High);
  71.                 // This funtion stops this worker, which will eventually stop the whole thread system once all the
  72.                 // frames have been processed
  73.                 this->stop();
  74.                 return nullptr;
  75.             }
  76.             else
  77.             {
  78.                 // Create new datum
  79.                 auto datumsPtr = std::make_shared<std::vector<UserDatum>>();
  80.                 datumsPtr->emplace_back();
  81.                 auto& datum = datumsPtr->at(0);
  82.  
  83.                 // Fill datum
  84.                 datum.cvInputData = cv::imread(mImageFiles.at(mCounter++));
  85.  
  86.                 // If empty frame -> return nullptr
  87.                 if (datum.cvInputData.empty())
  88.                 {
  89.                     op::log("Empty frame detected on path: " + mImageFiles.at(mCounter-1) + ". Closing program.",
  90.                         op::Priority::High);
  91.                     this->stop();
  92.                     datumsPtr = nullptr;
  93.                 }
  94.  
  95.                 return datumsPtr;
  96.             }
  97.         }
  98.         catch (const std::exception& e)
  99.         {
  100.             this->stop();
  101.             op::error(e.what(), __LINE__, __FUNCTION__, __FILE__);
  102.             return nullptr;
  103.         }
  104.     }
  105.  
  106. private:
  107.     const std::vector<std::string> mImageFiles;
  108.     unsigned long long mCounter;
  109. };
  110.  
  111. int main(int argc, char *argv[])
  112. {
  113.     // Parsing command line flags
  114.     gflags::ParseCommandLineFlags(&argc, &argv, true);
  115.  
  116.     try
  117.     {
  118.         op::log("Starting OpenPose demo...", op::Priority::High);
  119.         const auto timerBegin = std::chrono::high_resolution_clock::now();
  120.  
  121.         // logging_level
  122.         op::check(0 <= FLAGS_logging_level && FLAGS_logging_level <= 255, "Wrong logging_level value.",
  123.                   __LINE__, __FUNCTION__, __FILE__);
  124.         op::ConfigureLog::setPriorityThreshold((op::Priority)FLAGS_logging_level);
  125.         op::Profiler::setDefaultX(FLAGS_profile_speed);
  126.         // // For debugging
  127.         // // Print all logging messages
  128.         // op::ConfigureLog::setPriorityThreshold(op::Priority::None);
  129.         // // Print out speed values faster
  130.         // op::Profiler::setDefaultX(100);
  131.  
  132.         // Applying user defined configuration - GFlags to program variables
  133.         // outputSize
  134.         const auto outputSize = op::flagsToPoint(FLAGS_output_resolution, "-1x-1");
  135.         // netInputSize
  136.         const auto netInputSize = op::flagsToPoint(FLAGS_net_resolution, "-1x368");
  137.         // faceNetInputSize
  138.         const auto faceNetInputSize = op::flagsToPoint(FLAGS_face_net_resolution, "368x368 (multiples of 16)");
  139.         // handNetInputSize
  140.         const auto handNetInputSize = op::flagsToPoint(FLAGS_hand_net_resolution, "368x368 (multiples of 16)");
  141.         // poseModel
  142.         const auto poseModel = op::flagsToPoseModel(FLAGS_model_pose);
  143.         // JSON saving
  144.         if (!FLAGS_write_keypoint.empty())
  145.             op::log("Flag `write_keypoint` is deprecated and will eventually be removed."
  146.                     " Please, use `write_json` instead.", op::Priority::Max);
  147.         // keypointScale
  148.         const auto keypointScale = op::flagsToScaleMode(FLAGS_keypoint_scale);
  149.         // heatmaps to add
  150.         const auto heatMapTypes = op::flagsToHeatMaps(FLAGS_heatmaps_add_parts, FLAGS_heatmaps_add_bkg,
  151.                                                       FLAGS_heatmaps_add_PAFs);
  152.         const auto heatMapScale = op::flagsToHeatMapScaleMode(FLAGS_heatmaps_scale);
  153.         // >1 camera view?
  154.         // const auto multipleView = (FLAGS_3d || FLAGS_3d_views > 1 || FLAGS_flir_camera);
  155.         const auto multipleView = false;
  156.         // Enabling Google Logging
  157.         const bool enableGoogleLogging = true;
  158.  
  159.         // OpenPose wrapper
  160.         op::log("Configuring OpenPose...", op::Priority::High);
  161.         op::WrapperT<std::vector<UserDatum>> opWrapperT;
  162.  
  163.         // Initializing the user custom classes
  164.         // Frames producer (e.g., video, webcam, ...)
  165.         auto wUserInput = std::make_shared<WUserInput>(FLAGS_image_dir);
  166.         // Add custom processing
  167.         const auto workerInputOnNewThread = true;
  168.         opWrapperT.setWorker(op::WorkerType::Input, wUserInput, workerInputOnNewThread);
  169.  
  170.         // Pose configuration (use WrapperStructPose{} for default and recommended configuration)
  171.         const op::WrapperStructPose wrapperStructPose{
  172.             !FLAGS_body_disable, netInputSize, outputSize, keypointScale, FLAGS_num_gpu, FLAGS_num_gpu_start,
  173.             FLAGS_scale_number, (float)FLAGS_scale_gap, op::flagsToRenderMode(FLAGS_render_pose, multipleView),
  174.             poseModel, !FLAGS_disable_blending, (float)FLAGS_alpha_pose, (float)FLAGS_alpha_heatmap,
  175.             FLAGS_part_to_show, FLAGS_model_folder, heatMapTypes, heatMapScale, FLAGS_part_candidates,
  176.             (float)FLAGS_render_threshold, FLAGS_number_people_max, FLAGS_maximize_positives, FLAGS_fps_max,
  177.             enableGoogleLogging};
  178.         opWrapperT.configure(wrapperStructPose);
  179.         // Face configuration (use op::WrapperStructFace{} to disable it)
  180.         const op::WrapperStructFace wrapperStructFace{
  181.             FLAGS_face, faceNetInputSize, op::flagsToRenderMode(FLAGS_face_render, multipleView, FLAGS_render_pose),
  182.             (float)FLAGS_face_alpha_pose, (float)FLAGS_face_alpha_heatmap, (float)FLAGS_face_render_threshold};
  183.         opWrapperT.configure(wrapperStructFace);
  184.         // Hand configuration (use op::WrapperStructHand{} to disable it)
  185.         const op::WrapperStructHand wrapperStructHand{
  186.             FLAGS_hand, handNetInputSize, FLAGS_hand_scale_number, (float)FLAGS_hand_scale_range, FLAGS_hand_tracking,
  187.             op::flagsToRenderMode(FLAGS_hand_render, multipleView, FLAGS_render_pose), (float)FLAGS_hand_alpha_pose,
  188.             (float)FLAGS_hand_alpha_heatmap, (float)FLAGS_hand_render_threshold};
  189.         opWrapperT.configure(wrapperStructHand);
  190.         // Extra functionality configuration (use op::WrapperStructExtra{} to disable it)
  191.         const op::WrapperStructExtra wrapperStructExtra{
  192.             FLAGS_3d, FLAGS_3d_min_views, FLAGS_identification, FLAGS_tracking, FLAGS_ik_threads};
  193.         opWrapperT.configure(wrapperStructExtra);
  194.         // Output (comment or use default argument to disable any output)
  195.         const op::WrapperStructOutput wrapperStructOutput{
  196.             FLAGS_cli_verbose, FLAGS_write_keypoint, op::stringToDataFormat(FLAGS_write_keypoint_format),
  197.             FLAGS_write_json, FLAGS_write_coco_json, FLAGS_write_coco_foot_json, FLAGS_write_coco_json_variant,
  198.             FLAGS_write_images, FLAGS_write_images_format, FLAGS_write_video, FLAGS_write_video_fps,
  199.             FLAGS_write_heatmaps, FLAGS_write_heatmaps_format, FLAGS_write_video_3d, FLAGS_write_video_adam,
  200.             FLAGS_write_bvh, FLAGS_udp_host, FLAGS_udp_port};
  201.         opWrapperT.configure(wrapperStructOutput);
  202.         // GUI (comment or use default argument to disable any visual output)
  203.         const op::WrapperStructGui wrapperStructGui{
  204.             op::flagsToDisplayMode(FLAGS_display, FLAGS_3d), !FLAGS_no_gui_verbose, FLAGS_fullscreen};
  205.         opWrapperT.configure(wrapperStructGui);
  206.         // Set to single-thread (for sequential processing and/or debugging and/or reducing latency)
  207.         opWrapperT.disableMultiThreading();
  208.  
  209.         // Start, run, and stop processing - exec() blocks this thread until OpenPose wrapper has finished
  210.         op::log("Starting thread(s)...", op::Priority::High);
  211.         opWrapperT.exec();
  212.  
  213.         // Measuring total time
  214.         const auto now = std::chrono::high_resolution_clock::now();
  215.         const auto totalTimeSec = (double)std::chrono::duration_cast<std::chrono::nanoseconds>(now-timerBegin).count()
  216.                                 * 1e-9;
  217.         const auto message = "OpenPose demo successfully finished. Total time: "
  218.                            + std::to_string(totalTimeSec) + " seconds.";
  219.         op::log(message, op::Priority::High);
  220.  
  221.         // Return successful message
  222.         return 0;
  223.     }
  224.     catch (const std::exception& e)
  225.     {
  226.         return -1;
  227.     }
  228. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement