OpenPoseEstimationComponent.cpp
Go to the documentation of this file.
1/*
2 * This file is part of ArmarX.
3 *
4 * ArmarX is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 *
8 * ArmarX is distributed in the hope that it will be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * @package VisionX::ArmarXObjects::OpenPoseEstimation
17 * @author Stefan Reither ( stef dot reither at web dot de )
18 * @date 2018
19 * @copyright http://www.gnu.org/licenses/gpl-2.0.txt
20 * GNU General Public License
21 */
22
24
25#include <SimoxUtility/algorithm/string.h>
26
28
30
32
33namespace armarx
34{
35 void
38 {
39 def->topic(listener2DPrx, "OpenPoseEstimation2D", "OpenPoseEstimation2DTopicName");
40
41 def->optional(
42 op_settings.net_resolution,
43 "OP_net_resolution",
44 "Multiples of 16. If it is increased, the accuracy potentially increases. If it is "
45 "decreased, the speed increases. For maximum speed-accuracy balance, it should keep "
46 "the "
47 "closest aspect ratio possible to the images or videos to be processed.\n Using `-1` "
48 "in "
49 "any of the dimensions, OP will choose the optimal aspect ratio depending on the "
50 "user's "
51 "input value.\n E.g. the default `-1x368` is equivalent to `656x368` in 16:9 "
52 "resolutions, "
53 "e.g. full HD (1980x1080) and HD (1280x720) resolutions.");
54 def->optional(op_settings.output_resolution,
55 "OP_output_resolution",
56 "The image resolution (display and output). Use \"-1x-1\" to force the "
57 "program to use the"
58 " input image resolution.");
59 def->optional(op_settings.scale_gap,
60 "OP_scale_gap",
61 "Scale gap between scales. No effect unless scale_number > 1. Initial scale "
62 "is always 1. "
63 "If you want to change the initial calib->get scale, you actually want to "
64 "multiply the "
65 "`net_resolution` by your desired initial scale.");
66 def->optional(op_settings.scale_number, "OP_scale_number", "Number of scales to average.");
67 def->optional(op_settings.model_pose,
68 "OP_model_pose",
69 "Model to be used. E.g. `BODY_25` (25 keypoints, best model), `COCO` (18 "
70 "keypoints), `MPI` (15 keypoints, ~10% faster), "
71 "MPI_4_layers` (15 keypoints, even faster but less accurate).");
72 def->optional(
73 op_settings.model_folder,
74 "OP_model_folder",
75 "Folder path (absolute or relative) where the models (pose, face, ...) are located.");
76 def->optional(op_settings.num_gpu_start, "OP_num_gpu_start", "GPU device start number.");
77 def->optional(op_settings.minimum_number_of_valid_keypoints_per_entitiy,
78 "MinimalAmountKeypoints",
79 "Minimal amount of keypoints per person. Detected persons with less valid "
80 "keypoints will be discarded.");
81
82 def->optional(op_render_threshold,
83 "OP_render_threshold",
84 "Only estimated keypoints whose score confidences are higher than this "
85 "threshold will be"
86 " rendered.\n Generally, a high threshold (> 0.5) will only render very "
87 "clear body parts;"
88 " while small thresholds (~0.1) will also output guessed and occluded "
89 "keypoints, but also"
90 " more false positives (i.e. wrong detections).");
91
92 def->optional(active_upon_startup,
93 "ActivateOnStartup",
94 "If true, poseEstimation-tasks are started after starting the component. If "
95 "false, the component idles.");
96 }
97
98 void
106
107 void
111
112 void
116
117 void
121
122 void
131
135
136 void
138 {
139 openposePtr->render2DResultImage(
141 }
142
143 void
145 {
146 ARMARX_DEBUG << deactivateSpam(0.5) << "Reporting 2Dkeypoints for " << openposeResult.size()
147 << " entities";
149 }
150
151 void
153 {
154 // nothing to visualize since no 3d info available
155 openposeResult.clear(); // last step in pipeline
156 }
157
158 void
160 {
161 // Check if openpose is setup
162 if (!openposePtr)
163 {
164 std::lock_guard l(openpose_initializing_mutex);
165 ARMARX_INFO << "Initialize OpenPose...";
167 }
168
169 while (running2D && openposeTask->isRunning())
170 {
171 if (!update_ready)
172 {
173 usleep(100);
174 continue;
175 }
176
177 update_ready = false;
178
179 // 0. An update is ready.
180 // The new input image is already stored in rgbImageBuffer
181 // We use this image to get the openpose data
182 // After that the openpose image is stored in openPoseResultImage and the
183 // OpenPose values are stored in openposeResult
184
185 // 1. create 2D-Keypoints from images
186 std::lock_guard rgbImage_lock(rgbImageBufferMutex);
187 auto op_array = openposePtr->getOpenposeKeypoints(rgbImageBuffer);
188 openposeResult = openposePtr->convert2DKeypointsToIce(op_array, rgbImageBuffer);
189
190 if (openposeResult.empty())
191 {
192 continue;
193 }
194
195 // 2. renderOutputImage
196 {
197 std::lock_guard output_lock(openposeResultImageMutex);
198 renderOutputImage(op_array);
199 }
200
201 // 3. send keypoints via topic
203
204 // 4. visualize
205 visualize();
206
207 result_image_ready = true;
208 }
209 }
210
211 void
213 {
214 if (running2D)
215 {
216 return;
217 }
218 else
219 {
220 ARMARX_INFO << "Starting OpenposeEstimation";
223 running2D = true;
224 openposeTask->start();
225 }
226 }
227
228 void
230 {
231 if (running2D)
232 {
233 ARMARX_INFO << "Stopping OpenposeEstimation";
234 running2D = false;
235 openposeTask->stop(true);
236 }
237
238 // free memory
239 openposePtr.reset();
240 }
241
242 void
244 {
245 ARMARX_WARNING << "Could not start 3D pose estimation in 2D component.";
246 }
247
248 void
252
253 void
255 const EnableHumanPoseEstimationInput& input,
256 const Ice::Current&)
257 {
258 if (input.enable2d)
259 {
260 start();
261 }
262 else
263 {
264 stop();
265 }
266 }
267} // namespace armarx
SpamFilterDataPtr deactivateSpam(float deactivationDurationSec=10.0f, const std::string &identifier="", bool deactivate=true) const
disables the logging for the current line for the given amount of seconds.
Definition Logging.cpp:99
void start3DPoseEstimation(const Ice::Current &=Ice::emptyCurrent) override
armarx::RunningTask< OpenPoseEstimationComponentPluginUser >::pointer_type openposeTask
void stop(const Ice::Current &=Ice::emptyCurrent) override
void start(const Ice::Current &=Ice::emptyCurrent) override
void stop3DPoseEstimation(const Ice::Current &=Ice::emptyCurrent) override
virtual void postCreatePropertyDefinitions(PropertyDefinitionsPtr &properties)
void enableHumanPoseEstimation(const EnableHumanPoseEstimationInput &input, const Ice::Current &=Ice::emptyCurrent) override
virtual void renderOutputImage(const op::Array< float > &)
#define ARMARX_INFO
The normal logging level.
Definition Logging.h:181
#define ARMARX_DEBUG
The logging level for output that is only interesting while debugging.
Definition Logging.h:184
#define ARMARX_WARNING
The logging level for unexpected behaviour, but not a serious problem.
Definition Logging.h:193
This file offers overloads of toIce() and fromIce() functions for STL container types.
std::shared_ptr< OpenPoseAdapter > MonocularOpenPoseEstimationPtr
IceUtil::Handle< class PropertyDefinitionContainer > PropertyDefinitionsPtr
PropertyDefinitions smart pointer type.