forked from CMU-Perceptual-Computing-Lab/openpose
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Added 3d asynchronous functionality and example
- Loading branch information
1 parent
36ddcdb
commit 66a2757
Showing
19 changed files
with
420 additions
and
31 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
240 changes: 240 additions & 0 deletions
240
examples/tutorial_api_cpp/11_asynchronous_custom_input_multi_camera.cpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,240 @@ | ||
// ------------------------- OpenPose C++ API Tutorial - Example 10 - Custom Input ------------------------- | ||
// Asynchronous mode: ideal for fast prototyping when performance is not an issue. | ||
// In this function, the user can implement its own way to create frames (e.g., reading his own folder of images) | ||
// and emplaces/pushes the frames to OpenPose. | ||
|
||
// Third-party dependencies | ||
#include <opencv2/opencv.hpp> | ||
// Command-line user interface | ||
#define OPENPOSE_FLAGS_DISABLE_PRODUCER | ||
#include <openpose/flags.hpp> | ||
// OpenPose dependencies | ||
#include <openpose/headers.hpp> | ||
|
||
// Custom OpenPose flags | ||
// Producer | ||
DEFINE_string(video, "3d_4camera_video.avi", | ||
"Use a video file instead of the camera. Use `examples/media/video.avi` for our default example video."); | ||
DEFINE_string(camera_parameter_path, "models/cameraParameters/flir/", | ||
"String with the folder where the camera parameters are located. If there is only 1 XML file (for single" | ||
" video, webcam, or images from the same camera), you must specify the whole XML file path (ending in .xml)."); | ||
|
||
// This worker will just read and return all the basic image file formats in a directory | ||
class UserInputClass | ||
{ | ||
public: | ||
UserInputClass(const std::string& videoPath, const std::string& cameraParameterPath) : | ||
mClosed{false}, | ||
mFrameCounter{0ull}, | ||
mVideoCapture{videoPath} | ||
{ | ||
if (!mVideoCapture.isOpened()) | ||
{ | ||
mClosed = true; | ||
op::error("No video " + videoPath + " opened.", __LINE__, __FUNCTION__, __FILE__); | ||
} | ||
|
||
// Create CameraParameterReader | ||
mCameraParameterReader.readParameters(cameraParameterPath); | ||
} | ||
|
||
std::shared_ptr<std::vector<std::shared_ptr<op::Datum>>> createDatum() | ||
{ | ||
if (mClosed) | ||
{ | ||
op::opLog("Video already closed, nullptr returned.", op::Priority::High); | ||
return nullptr; | ||
} | ||
|
||
// Read cv::Mat | ||
cv::Mat cvInputData; | ||
mVideoCapture >> cvInputData; | ||
// If empty frame -> return nullptr | ||
if (cvInputData.empty()) | ||
{ | ||
// Close program when empty frame | ||
op::opLog("Empty frame detected, closing program.", op::Priority::High); | ||
mClosed = true; | ||
return nullptr; | ||
} | ||
|
||
// Create new datum and add 3D information (cv::Mat splitted and camera parameters) | ||
auto datumsPtr = std::make_shared<std::vector<std::shared_ptr<op::Datum>>>(); | ||
op::createMultiviewTDatum<op::Datum>(datumsPtr, mFrameCounter, mCameraParameterReader, (void*)&cvInputData); | ||
|
||
return datumsPtr; | ||
} | ||
|
||
bool isFinished() const | ||
{ | ||
return mClosed; | ||
} | ||
|
||
private: | ||
bool mClosed; | ||
unsigned long long mFrameCounter; | ||
cv::VideoCapture mVideoCapture; | ||
op::CameraParameterReader mCameraParameterReader; | ||
}; | ||
|
||
void configureWrapper(op::Wrapper& opWrapper) | ||
{ | ||
try | ||
{ | ||
// Configuring OpenPose | ||
|
||
// logging_level | ||
op::checkBool( | ||
0 <= FLAGS_logging_level && FLAGS_logging_level <= 255, "Wrong logging_level value.", | ||
__LINE__, __FUNCTION__, __FILE__); | ||
op::ConfigureLog::setPriorityThreshold((op::Priority)FLAGS_logging_level); | ||
op::Profiler::setDefaultX(FLAGS_profile_speed); | ||
|
||
// Applying user defined configuration - GFlags to program variables | ||
// outputSize | ||
const auto outputSize = op::flagsToPoint(op::String(FLAGS_output_resolution), "-1x-1"); | ||
// netInputSize | ||
const auto netInputSize = op::flagsToPoint(op::String(FLAGS_net_resolution), "-1x368"); | ||
// faceNetInputSize | ||
const auto faceNetInputSize = op::flagsToPoint(op::String(FLAGS_face_net_resolution), "368x368 (multiples of 16)"); | ||
// handNetInputSize | ||
const auto handNetInputSize = op::flagsToPoint(op::String(FLAGS_hand_net_resolution), "368x368 (multiples of 16)"); | ||
// poseMode | ||
const auto poseMode = op::flagsToPoseMode(FLAGS_body); | ||
// poseModel | ||
const auto poseModel = op::flagsToPoseModel(op::String(FLAGS_model_pose)); | ||
// JSON saving | ||
if (!FLAGS_write_keypoint.empty()) | ||
op::opLog( | ||
"Flag `write_keypoint` is deprecated and will eventually be removed. Please, use `write_json`" | ||
" instead.", op::Priority::Max); | ||
// keypointScaleMode | ||
const auto keypointScaleMode = op::flagsToScaleMode(FLAGS_keypoint_scale); | ||
// heatmaps to add | ||
const auto heatMapTypes = op::flagsToHeatMaps(FLAGS_heatmaps_add_parts, FLAGS_heatmaps_add_bkg, | ||
FLAGS_heatmaps_add_PAFs); | ||
const auto heatMapScaleMode = op::flagsToHeatMapScaleMode(FLAGS_heatmaps_scale); | ||
// >1 camera view? | ||
const auto multipleView = (FLAGS_3d || FLAGS_3d_views > 1); | ||
// Face and hand detectors | ||
const auto faceDetector = op::flagsToDetector(FLAGS_face_detector); | ||
const auto handDetector = op::flagsToDetector(FLAGS_hand_detector); | ||
// Enabling Google Logging | ||
const bool enableGoogleLogging = true; | ||
|
||
// Pose configuration (use WrapperStructPose{} for default and recommended configuration) | ||
const op::WrapperStructPose wrapperStructPose{ | ||
poseMode, netInputSize, outputSize, keypointScaleMode, FLAGS_num_gpu, FLAGS_num_gpu_start, | ||
FLAGS_scale_number, (float)FLAGS_scale_gap, op::flagsToRenderMode(FLAGS_render_pose, multipleView), | ||
poseModel, !FLAGS_disable_blending, (float)FLAGS_alpha_pose, (float)FLAGS_alpha_heatmap, | ||
FLAGS_part_to_show, op::String(FLAGS_model_folder), heatMapTypes, heatMapScaleMode, FLAGS_part_candidates, | ||
(float)FLAGS_render_threshold, FLAGS_number_people_max, FLAGS_maximize_positives, FLAGS_fps_max, | ||
op::String(FLAGS_prototxt_path), op::String(FLAGS_caffemodel_path), | ||
(float)FLAGS_upsampling_ratio, enableGoogleLogging}; | ||
opWrapper.configure(wrapperStructPose); | ||
// Face configuration (use op::WrapperStructFace{} to disable it) | ||
const op::WrapperStructFace wrapperStructFace{ | ||
FLAGS_face, faceDetector, faceNetInputSize, | ||
op::flagsToRenderMode(FLAGS_face_render, multipleView, FLAGS_render_pose), | ||
(float)FLAGS_face_alpha_pose, (float)FLAGS_face_alpha_heatmap, (float)FLAGS_face_render_threshold}; | ||
opWrapper.configure(wrapperStructFace); | ||
// Hand configuration (use op::WrapperStructHand{} to disable it) | ||
const op::WrapperStructHand wrapperStructHand{ | ||
FLAGS_hand, handDetector, handNetInputSize, FLAGS_hand_scale_number, (float)FLAGS_hand_scale_range, | ||
op::flagsToRenderMode(FLAGS_hand_render, multipleView, FLAGS_render_pose), (float)FLAGS_hand_alpha_pose, | ||
(float)FLAGS_hand_alpha_heatmap, (float)FLAGS_hand_render_threshold}; | ||
opWrapper.configure(wrapperStructHand); | ||
// Extra functionality configuration (use op::WrapperStructExtra{} to disable it) | ||
const op::WrapperStructExtra wrapperStructExtra{ | ||
FLAGS_3d, FLAGS_3d_min_views, FLAGS_identification, FLAGS_tracking, FLAGS_ik_threads}; | ||
opWrapper.configure(wrapperStructExtra); | ||
// Output (comment or use default argument to disable any output) | ||
const op::WrapperStructOutput wrapperStructOutput{ | ||
FLAGS_cli_verbose, op::String(FLAGS_write_keypoint), op::stringToDataFormat(FLAGS_write_keypoint_format), | ||
op::String(FLAGS_write_json), op::String(FLAGS_write_coco_json), FLAGS_write_coco_json_variants, | ||
FLAGS_write_coco_json_variant, op::String(FLAGS_write_images), op::String(FLAGS_write_images_format), | ||
op::String(FLAGS_write_video), FLAGS_write_video_fps, FLAGS_write_video_with_audio, | ||
op::String(FLAGS_write_heatmaps), op::String(FLAGS_write_heatmaps_format), op::String(FLAGS_write_video_3d), | ||
op::String(FLAGS_write_video_adam), op::String(FLAGS_write_bvh), op::String(FLAGS_udp_host), | ||
op::String(FLAGS_udp_port)}; | ||
opWrapper.configure(wrapperStructOutput); | ||
// GUI (comment or use default argument to disable any visual output) | ||
const op::WrapperStructGui wrapperStructGui{ | ||
op::flagsToDisplayMode(FLAGS_display, FLAGS_3d), !FLAGS_no_gui_verbose, FLAGS_fullscreen}; | ||
opWrapper.configure(wrapperStructGui); | ||
// Set to single-thread (for sequential processing and/or debugging and/or reducing latency) | ||
if (FLAGS_disable_multi_thread) | ||
opWrapper.disableMultiThreading(); | ||
} | ||
catch (const std::exception& e) | ||
{ | ||
op::error(e.what(), __LINE__, __FUNCTION__, __FILE__); | ||
} | ||
} | ||
|
||
int tutorialApiCpp() | ||
{ | ||
try | ||
{ | ||
op::opLog("Starting OpenPose demo...", op::Priority::High); | ||
const auto opTimer = op::getTimerInit(); | ||
|
||
// Required flags to enable 3-D | ||
FLAGS_3d = true; | ||
FLAGS_number_people_max = 1; | ||
FLAGS_3d_min_views = 3; | ||
FLAGS_output_resolution = "320x256"; // Optional, but otherwise it gets too big to render in real time | ||
// FLAGS_3d_views = X; // Not required because it only affects OpenPose producers (rather than custom ones) | ||
|
||
// Configuring OpenPose | ||
op::opLog("Configuring OpenPose...", op::Priority::High); | ||
op::Wrapper opWrapper{op::ThreadManagerMode::AsynchronousIn}; | ||
configureWrapper(opWrapper); | ||
|
||
// Start, run, and stop processing - exec() blocks this thread until OpenPose wrapper has finished | ||
op::opLog("Starting thread(s)...", op::Priority::High); | ||
opWrapper.start(); | ||
|
||
// User processing | ||
UserInputClass userInputClass(FLAGS_video, FLAGS_camera_parameter_path); | ||
bool userWantsToExit = false; | ||
while (!userWantsToExit && !userInputClass.isFinished()) | ||
{ | ||
if (!opWrapper.isRunning()) | ||
{ | ||
op::opLog("OpenPose wrapper is no longer running, exiting video.", op::Priority::High); | ||
break; | ||
} | ||
// Push frame | ||
auto datumToProcess = userInputClass.createDatum(); | ||
if (datumToProcess != nullptr) | ||
{ | ||
auto successfullyEmplaced = opWrapper.waitAndEmplace(datumToProcess); | ||
if (!successfullyEmplaced) | ||
op::opLog("Processed datum could not be emplaced.", op::Priority::High); | ||
} | ||
} | ||
|
||
op::opLog("Stopping thread(s)", op::Priority::High); | ||
opWrapper.stop(); | ||
|
||
// Measuring total time | ||
op::printTime(opTimer, "OpenPose demo successfully finished. Total time: ", " seconds.", op::Priority::High); | ||
|
||
// Return | ||
return 0; | ||
} | ||
catch (const std::exception&) | ||
{ | ||
return -1; | ||
} | ||
} | ||
|
||
int main(int argc, char *argv[]) | ||
{ | ||
// Parsing command line flags | ||
gflags::ParseCommandLineFlags(&argc, &argv, true); | ||
|
||
// Running tutorialApiCpp | ||
return tutorialApiCpp(); | ||
} |
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.