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 
33 namespace armarx
34 {
35  void
38  {
39  def->topic(listener2DPrx, "OpenPoseEstimation2D", "OpenPoseEstimation2DTopicName");
40 
41  def->optional(
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(
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.");
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
100  {
102  {
103  start();
104  }
105  }
106 
107  void
109  {
110  }
111 
112  void
114  {
115  }
116 
117  void
119  {
120  }
121 
122  void
124  {
125 
126  stop();
127  running2D = false;
128 
129  delete openposeResultImage;
130  }
131 
133  {
134  }
135 
136  void
137  OpenPoseEstimationComponentPluginUser::renderOutputImage(const op::Array<float>& op_keypoints)
138  {
139  openposePtr->render2DResultImage(
141  }
142 
143  void
145  {
146  ARMARX_DEBUG << deactivateSpam(0.5) << "Reporting 2Dkeypoints for " << openposeResult.size()
147  << " entities";
148  listener2DPrx->report2DKeypoints(openposeResult, timestamp_of_update);
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
202  reportEntities();
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
250  {
251  }
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
armarx::OpenPoseAdapter::OpenPoseSettings::model_pose
std::string model_pose
Definition: OpenPoseAdapter.h:72
RemoteRobot.h
armarx::OpenPoseEstimationComponentPluginUser::openpose_initializing_mutex
std::mutex openpose_initializing_mutex
Definition: OpenPoseEstimationComponent.h:123
armarx::OpenPoseEstimationComponentPluginUser::OpenPoseEstimationComponentPluginUser
OpenPoseEstimationComponentPluginUser()
Definition: OpenPoseEstimationComponent.cpp:132
armarx::OpenPoseEstimationComponentPluginUser::update_ready
std::atomic_bool update_ready
Definition: OpenPoseEstimationComponent.h:132
armarx::OpenPoseEstimationComponentPluginUser::rgbImageBuffer
CByteImage * rgbImageBuffer
Definition: OpenPoseEstimationComponent.h:99
armarx::OpenPoseEstimationComponentPluginUser::active_upon_startup
bool active_upon_startup
Definition: OpenPoseEstimationComponent.h:89
armarx::OpenPoseAdapter::OpenPoseSettings::scale_number
int scale_number
Definition: OpenPoseAdapter.h:75
armarx::OpenPoseEstimationComponentPluginUser::preOnDisconnectImageProcessor
virtual void preOnDisconnectImageProcessor()
Definition: OpenPoseEstimationComponent.cpp:123
armarx::OpenPoseAdapter::OpenPoseSettings::model_folder
std::string model_folder
Definition: OpenPoseAdapter.h:73
armarx::MonocularOpenPoseEstimationPtr
std::shared_ptr< OpenPoseAdapter > MonocularOpenPoseEstimationPtr
Definition: OpenPoseAdapter.h:62
armarx::OpenPoseEstimationComponentPluginUser::result_image_ready
std::atomic_bool result_image_ready
Definition: OpenPoseEstimationComponent.h:116
armarx::OpenPoseEstimationComponentPluginUser::listener2DPrx
OpenPose2DListenerPrx listener2DPrx
Definition: OpenPoseEstimationComponent.h:108
armarx::OpenPoseEstimationComponentPluginUser::op_render_threshold
float op_render_threshold
Definition: OpenPoseEstimationComponent.h:120
armarx::OpenPoseEstimationComponentPluginUser::preOnInitImageProcessor
virtual void preOnInitImageProcessor()
Definition: OpenPoseEstimationComponent.cpp:108
armarx::OpenPoseEstimationComponentPluginUser::openposeResultImage
CByteImage ** openposeResultImage
Definition: OpenPoseEstimationComponent.h:115
armarx::RunningTask
Definition: ArmarXMultipleObjectsScheduler.h:36
armarx::OpenPoseEstimationComponentPluginUser::start
void start(const Ice::Current &=Ice::emptyCurrent) override
Definition: OpenPoseEstimationComponent.cpp:212
armarx::OpenPoseEstimationComponentPluginUser::start3DPoseEstimation
void start3DPoseEstimation(const Ice::Current &=Ice::emptyCurrent) override
Definition: OpenPoseEstimationComponent.cpp:243
armarx::OpenPoseEstimationComponentPluginUser::loop
void loop()
Definition: OpenPoseEstimationComponent.cpp:159
ImageProcessor.h
armarx::OpenPoseEstimationComponentPluginUser::stop
void stop(const Ice::Current &=Ice::emptyCurrent) override
Definition: OpenPoseEstimationComponent.cpp:229
armarx::OpenPoseEstimationComponentPluginUser::timestamp_of_update
std::atomic_long timestamp_of_update
Definition: OpenPoseEstimationComponent.h:134
armarx::OpenPoseEstimationComponentPluginUser::openposeTask
armarx::RunningTask< OpenPoseEstimationComponentPluginUser >::pointer_type openposeTask
Definition: OpenPoseEstimationComponent.h:130
armarx::OpenPoseAdapter::OpenPoseSettings::scale_gap
double scale_gap
Definition: OpenPoseAdapter.h:74
ARMARX_DEBUG
#define ARMARX_DEBUG
Definition: Logging.h:184
armarx::aron::input
ReaderT::InputType & input
Definition: rw.h:12
armarx::OpenPoseEstimationComponentPluginUser::postOnConnectImageProcessor
virtual void postOnConnectImageProcessor()
Definition: OpenPoseEstimationComponent.cpp:99
armarx::OpenPoseAdapter
Definition: OpenPoseAdapter.h:65
armarx::OpenPoseEstimationComponentPluginUser::running2D
std::atomic_bool running2D
Definition: OpenPoseEstimationComponent.h:131
armarx::OpenPoseEstimationComponentPluginUser::openposeResultImageMutex
std::mutex openposeResultImageMutex
Definition: OpenPoseEstimationComponent.h:114
armarx::OpenPoseAdapter::OpenPoseSettings::output_resolution
std::string output_resolution
Definition: OpenPoseAdapter.h:71
armarx::OpenPoseEstimationComponentPluginUser::rgbImageBufferMutex
std::mutex rgbImageBufferMutex
Definition: OpenPoseEstimationComponent.h:100
armarx::OpenPoseAdapter::OpenPoseSettings::minimum_number_of_valid_keypoints_per_entitiy
unsigned int minimum_number_of_valid_keypoints_per_entitiy
Definition: OpenPoseAdapter.h:77
armarx::OpenPoseAdapter::OpenPoseSettings::net_resolution
std::string net_resolution
Definition: OpenPoseAdapter.h:70
armarx::OpenPoseEstimationComponentPluginUser::stop3DPoseEstimation
void stop3DPoseEstimation(const Ice::Current &=Ice::emptyCurrent) override
Definition: OpenPoseEstimationComponent.cpp:249
Component.h
armarx::OpenPoseEstimationComponentPluginUser::postOnDisconnectImageProcessor
virtual void postOnDisconnectImageProcessor()
Definition: OpenPoseEstimationComponent.cpp:118
armarx::OpenPoseEstimationComponentPluginUser::renderOutputImage
virtual void renderOutputImage(const op::Array< float > &)
Definition: OpenPoseEstimationComponent.cpp:137
armarx::OpenPoseEstimationComponentPluginUser::openposeResult
HumanPose2DMap openposeResult
Definition: OpenPoseEstimationComponent.h:111
armarx::OpenPoseEstimationComponentPluginUser::reportEntities
virtual void reportEntities()
Definition: OpenPoseEstimationComponent.cpp:144
armarx::OpenPoseEstimationComponentPluginUser::visualize
virtual void visualize()
Definition: OpenPoseEstimationComponent.cpp:152
armarx::OpenPoseAdapter::OpenPoseSettings::num_gpu_start
int num_gpu_start
Definition: OpenPoseAdapter.h:76
ARMARX_INFO
#define ARMARX_INFO
Definition: Logging.h:181
armarx::OpenPoseEstimationComponentPluginUser::preOnConnectImageProcessor
virtual void preOnConnectImageProcessor()
Definition: OpenPoseEstimationComponent.cpp:113
IceUtil::Handle< class PropertyDefinitionContainer >
armarx::Logging::deactivateSpam
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
armarx::OpenPoseEstimationComponentPluginUser::openposePtr
MonocularOpenPoseEstimationPtr openposePtr
Definition: OpenPoseEstimationComponent.h:124
armarx::OpenPoseEstimationComponentPluginUser::enableHumanPoseEstimation
void enableHumanPoseEstimation(const EnableHumanPoseEstimationInput &input, const Ice::Current &=Ice::emptyCurrent) override
Definition: OpenPoseEstimationComponent.cpp:254
armarx::OpenPoseEstimationComponentPluginUser::op_settings
OpenPoseAdapter::OpenPoseSettings op_settings
Definition: OpenPoseEstimationComponent.h:119
ARMARX_WARNING
#define ARMARX_WARNING
Definition: Logging.h:193
OpenPoseEstimationComponent.h
armarx
This file offers overloads of toIce() and fromIce() functions for STL container types.
Definition: ArmarXTimeserver.cpp:27
armarx::OpenPoseEstimationComponentPluginUser::postCreatePropertyDefinitions
virtual void postCreatePropertyDefinitions(PropertyDefinitionsPtr &properties)
Definition: OpenPoseEstimationComponent.cpp:36