27 #include <RobotAPI/interface/visualization/DebugDrawerInterface.h>
31 #include <VirtualRobot/Robot.h>
33 #include <Calibration/Calibration.h>
34 #include <Calibration/StereoCalibration.h>
38 #include <VisionX/interface/components/OpenPoseEstimationInterface.h>
39 #include <VisionX/interface/components/PointCloudAndImageAndCalibrationProviderInterface.h>
40 #include <VisionX/components/image_processor/OpenPoseEstimation/Util.h>
41 #include <VisionX/components/image_processor/OpenPoseEstimation/KeypointManager.h>
42 #include <VisionX/components/image_processor/OpenPoseEstimation/ImageKeypointBuffer.h>
45 #include <openpose/core/headers.hpp>
46 #include <openpose/pose/headers.hpp>
47 #include <openpose/utilities/headers.hpp>
77 defineOptionalProperty<std::string>(
"OpenPoseEstimation2DTopicName",
"OpenPoseEstimation2D");
78 defineOptionalProperty<std::string>(
"OpenPoseEstimation3DTopicName",
"OpenPoseEstimation3D");
79 defineOptionalProperty<int>(
"DepthMedianRadius", 10,
"Radius of the circle around a target pixel in the depth image, which is used to calculate the median around that pixel.");
80 defineOptionalProperty<bool>(
"UseDistortionParameters",
false,
"Whether to use distortion parameters when transforming image coordinates into world coordinates");
82 defineRequiredProperty<std::string>(
"ImageProviderName",
"Name of the ImageProviderComponent");
83 defineOptionalProperty<std::string>(
"DebugDrawerTopicName",
"DebugDrawerUpdates",
"Name of the debug drawer topic that should be used");
85 defineOptionalProperty<OpenPoseEstimationMode>(
"Mode",
FromDepthImage,
"Sets the mode of this instance of OpenPoseEstiamtion. There are currently three support modes:"
86 "'FromDepthImage', which lets the image processor expect a rgb-image and a depth-image,"
87 "'FromStereoImage', which lets the image processor expect two images as a stereo input "
88 "which will be used for calculating the 3D-values and"
89 "'FromTopic', which lets the image processor listen on a topic which provides openpose-keypoints.")
90 .setMatchRegex(
"FromDepthImage|FromStereoImage|FromTopic")
95 defineOptionalProperty<std::string>(
"OP_net_resolution",
"-1x368",
"Multiples of 16. If it is increased, the accuracy potentially increases. If it is "
96 "decreased, the speed increases. For maximum speed-accuracy balance, it should keep the "
97 "closest aspect ratio possible to the images or videos to be processed.\n Using `-1` in "
98 "any of the dimensions, OP will choose the optimal aspect ratio depending on the user's "
99 "input value.\n E.g. the default `-1x368` is equivalent to `656x368` in 16:9 resolutions, "
100 "e.g. full HD (1980x1080) and HD (1280x720) resolutions.");
101 defineOptionalProperty<std::string>(
"OP_output_resolution",
"-1x-1",
"The image resolution (display and output). Use \"-1x-1\" to force the program to use the"
102 " input image resolution.");
103 defineOptionalProperty<double>(
"OP_scale_gap", 0.3,
"Scale gap between scales. No effect unless scale_number > 1. Initial scale is always 1. "
104 "If you want to change the initial calib->get scale, you actually want to multiply the "
105 "`net_resolution` by your desired initial scale.");
106 defineOptionalProperty<int>(
"OP_scale_number", 1,
"Number of scales to average.");
107 defineOptionalProperty<std::string>(
"OP_model_pose",
human::pose::model::openpose_body_25::ModelId,
"Model to be used. E.g. `BODY_25` (25 keypoints, best model), `COCO` (18 keypoints), `MPI` (15 keypoints, ~10% faster), "
108 "MPI_4_layers` (15 keypoints, even faster but less accurate).");
109 defineOptionalProperty<std::string>(
"OP_model_folder",
"models/",
"Folder path (absolute or relative) where the models (pose, face, ...) are located.");
110 defineOptionalProperty<int>(
"OP_num_gpu_start", 0,
"GPU device start number.");
111 defineOptionalProperty<float>(
"OP_render_threshold", 0.05f,
"Only estimated keypoints whose score confidences are higher than this threshold will be"
112 " rendered.\n Generally, a high threshold (> 0.5) will only render very clear body parts;"
113 " while small thresholds (~0.1) will also output guessed and occluded keypoints, but also"
114 " more false positives (i.e. wrong detections).");
115 defineOptionalProperty<int>(
"MaxDepth", 3000,
"Pixels with a distance higher than this value are masked out. Only for depth camera mode.",
PropertyDefinitionBase::eModifiable);
116 defineOptionalProperty<int>(
"MaxDepthDifference", 700,
"Allowed difference of depth value for one keypoint to median of all keypoints.",
PropertyDefinitionBase::eModifiable);
117 defineOptionalProperty<int>(
"MaskBrightnessIncrease", 100,
"All masked pixels will be increased by this brightness for visualization. If value is <0, the original mask is shown.",
PropertyDefinitionBase::eModifiable);
119 defineOptionalProperty<std::string>(
"RobotStateComponentName",
"RobotStateComponent");
120 defineOptionalProperty<std::string>(
"CameraNodeName",
"DepthCamera",
"Name of the robot node for the input camera");
121 defineOptionalProperty<bool>(
"FilterWithWorkspacePolygonActive",
true,
"Whether to use the WorkspacePolygon for filtering keypoints.");
122 defineOptionalProperty<std::string>(
"WorkspacePolygon",
"-5000,-5000;5000,-5000;5000,5000;-5000,5000;-5000,-5000",
123 "A string that describes a polygon which represents the workspace of the robot.\n"
124 "Every keypoint outside of this polygon will be masked out.\n"
125 "Every point is seperated by a ';' (semicolon) and every point is described as 'x-value, y-value' (comma-seperated).\n"
126 "The last point must be identical to the first point.");
127 defineOptionalProperty<int>(
"MinimalAmountKeypoints", 5,
"Minimal amount of keypoints per person. Detected persons with less valid keypoints will be discarded.");
128 defineOptionalProperty<bool>(
"ReportOnlyNearestPerson",
false,
"If true, only one person is reported in the 3DTopic. The reported person is the nearest person to the robot.");
129 defineOptionalProperty<bool>(
"ActivateOnStartup",
true,
"If true, poseEstimation-tasks are started after starting the component. If false, the component idles.");
131 defineOptionalProperty<std::string>(
"Topic_Dimensions",
"480x360",
"Only for: 'Mode'='FromTopic'!! The dimensions of the image whose keypoints are reported over the topic.");
149 public OpenPoseEstimationInterface,
160 return "OpenPoseEstimation";
163 void start(
const Ice::Current& = Ice::emptyCurrent)
override;
164 void stop(
const Ice::Current& = Ice::emptyCurrent)
override;
172 static void Render2DResultImage(
const CByteImage& inputImage,
const CByteImage& maskedInputImage,
KeypointManagerPtr keypointManager, CByteImage& resultImage, op::PoseModel poseModel,
float renderThreshold,
int brightnessIncrease = 100);
173 static void Render2DResultImage(
const CByteImage& inputImage,
const CByteImage& maskedInputImage,
PoseKeypoints& keypoints, CByteImage& resultImage, op::PoseModel poseModel,
float renderThreshold,
int brightnessIncrease = 100);
174 static void VisualizeTransparentImageMask(CByteImage& resultImage,
const CByteImage& maskedInputImage,
int brightnessIncrease,
const CByteImage& inputImage);
198 void onMessage(
const Texting::TextMessage& text,
const Ice::Current& = Ice::emptyCurrent)
override;
203 std::string providerName;
205 bool useDistortionParameters;
206 bool reportOnlyNearestPerson;
207 bool filterWithWorkspacePolygonActive;
208 std::string cameraNodeName;
210 int minimalValidKeypoints;
211 float renderThreshold;
219 std::mutex keypointManagerMutex;
222 CByteImage** imageBuffer;
223 CByteImage* rgbImageBuffer, *maskedrgbImageBuffer;
224 std::mutex rgbImageBufferMutex;
225 CByteImage* depthImageBuffer;
226 std::mutex depthImageBufferMutex;
227 CByteImage** openPoseResultImage;
228 std::mutex resultImageBufferMutex;
230 armarx::MetaInfoSizeBasePtr imageMetaInfo;
231 unsigned int numImages;
235 visionx::ImageDimension incomingKeypointDimensions;
238 const CCalibration* calibration =
nullptr;
239 CStereoCalibration* stereoCalibration =
nullptr;
243 std::string layerName;
244 int layerCounter = 0;
247 OpenPose2DListenerPrx listener2DPrx;
248 OpenPose3DListenerPrx listener3DPrx;
257 long timeProvidedImage;
260 std::shared_ptr<op::ScaleAndSizeExtractor> scaleAndSizeExtractor;
261 std::shared_ptr<op::CvMatToOpInput> cvMatToOpInput;
262 std::shared_ptr<op::CvMatToOpOutput> cvMatToOpOutput;
263 std::shared_ptr<op::PoseExtractorCaffe> poseExtractorCaffe;
264 std::shared_ptr<op::OpOutputToCvMat> opOutputToCvMat;
265 void setupOpenPoseEnvironment();
267 op::PoseModel poseModel;
270 std::uint64_t timeoutCounter2d{0};
271 std::uint64_t readErrorCounter2d{0};
272 std::uint64_t sucessCounter2d{0};